1 package com.android.ex.chips;
2
3 import android.net.Uri;
4 import android.provider.ContactsContract.CommonDataKinds.Email;
5 import android.provider.ContactsContract.DisplayNameSources;
6
7 /**
8 * Represents one entry inside recipient auto-complete list.
9 */
10 public class RecipientEntry {
11 /* package */ static final int INVALID_CONTACT = -1;
12 /**
13 * A GENERATED_CONTACT is one that was created based entirely on
14 * information passed in to the RecipientEntry from an external source
15 * that is not a real contact.
16 */
17 /* package */ static final int GENERATED_CONTACT = -2;
18
19 /** Used when {@link #mDestinationType} is invalid and thus shouldn't be used for display. */
20 /* package */ static final int INVALID_DESTINATION_TYPE = -1;
21
22 public static final int ENTRY_TYPE_PERSON = 0;
23
24 public static final int ENTRY_TYPE_SIZE = 1; // 这是什么类型?
25
26 private final int mEntryType; // 这是用来表征哪种分类方法的?
27
28 /**
29 * True when this entry is the first entry in a group, which should have a photo and display
30 * name, while the second or later entries won't.
31 */// 涉及到了 group 分组的概念,entry 是怎么分组的?为什么要分组?
32 private boolean mIsFirstLevel;
33 private final String mDisplayName;
34
35 /** Destination for this contact entry. Would be an email address or a phone number. */
36 private final String mDestination;
37 /** Type of the destination like {@link Email#TYPE_HOME} */
38 private final int mDestinationType;
39 /**
40 * Label of the destination which will be used when type was {@link Email#TYPE_CUSTOM}.
41 * Can be null when {@link #mDestinationType} is {@link #INVALID_DESTINATION_TYPE}.
42 */// 干嘛用的,应该不是用来显示的呀,显示不是已经有displayName了吗?
43 private final String mDestinationLabel;
44 /** ID for the person */
45 private final long mContactId;
46 /** ID for the destination */
47 private final long mDataId;
48 private final boolean mIsDivider;
49
50 private final Uri mPhotoThumbnailUri;
51
52 /**
53 * This can be updated after this object being constructed, when the photo is fetched
54 * from remote directories.
55 */
56 private byte[] mPhotoBytes;
57
58 private RecipientEntry(int entryType) {
59 mEntryType = entryType;
60 mDisplayName = null;
61 mDestination = null;
62 mDestinationType = INVALID_DESTINATION_TYPE;
63 mDestinationLabel = null;
64 mContactId = -1;
65 mDataId = -1;
66 mPhotoThumbnailUri = null;
67 mPhotoBytes = null;
68 mIsDivider = true;
69 }
70
71 private RecipientEntry(
72 int entryType, String displayName,
73 String destination, int destinationType, String destinationLabel,
74 long contactId, long dataId, Uri photoThumbnailUri, boolean isFirstLevel) {
75 mEntryType = entryType;
76 mIsFirstLevel = isFirstLevel;
77 mDisplayName = displayName;
78 mDestination = destination;
79 mDestinationType = destinationType;
80 mDestinationLabel = destinationLabel;
81 mContactId = contactId;
82 mDataId = dataId;
83 mPhotoThumbnailUri = photoThumbnailUri;
84 mPhotoBytes = null;
85 mIsDivider = false;
86 }
87
88 /**
89 * Determine if this was a RecipientEntry created from recipient info or
90 * an entry from contacts.
91 */
92 public static boolean isCreatedRecipient(long id) {
93 return id == RecipientEntry.INVALID_CONTACT || id == RecipientEntry.GENERATED_CONTACT;
94 }
95
96 /**
97 * Construct a RecipientEntry from just an address that has been entered.
98 * This address has not been resolved to a contact and therefore does not
99 * have a contact id or photo.
100 */
101 public static RecipientEntry constructFakeEntry(String address) {
102 return new RecipientEntry(ENTRY_TYPE_PERSON, address, address,
103 INVALID_DESTINATION_TYPE, null,
104 INVALID_CONTACT, INVALID_CONTACT, null, true);
105 }
106
107 /**
108 * @return the display name for the entry. If the display name source is larger than
109 * {@link DisplayNameSources#PHONE} we use the contact's display name, but if not,
110 * i.e. the display name came from an email address or a phone number, we don't use it
111 * to avoid confusion and just use the destination instead.
112 */
113 private static String pickDisplayName(int displayNameSource, String displayName,
114 String destination) {
115 return (displayNameSource > DisplayNameSources.PHONE) ? displayName : destination;
116 }
117
118 /**
119 * Construct a RecipientEntry from just an address that has been entered
120 * with both an associated display name. This address has not been resolved
121 * to a contact and therefore does not have a contact id or photo.
122 */
123 public static RecipientEntry constructGeneratedEntry(String display, String address) {
124 return new RecipientEntry(ENTRY_TYPE_PERSON, display,
125 address, INVALID_DESTINATION_TYPE, null,
126 GENERATED_CONTACT, GENERATED_CONTACT, null, true);
127 }
128
129 public static RecipientEntry constructTopLevelEntry(
130 String displayName, int displayNameSource, String destination, int destinationType,
131 String destinationLabel, long contactId, long dataId, Uri photoThumbnailUri) {
132 return new RecipientEntry(ENTRY_TYPE_PERSON, pickDisplayName(displayNameSource, displayName,
133 destination),
134 destination, destinationType, destinationLabel,
135 contactId, dataId,
136 photoThumbnailUri, true);
137 }
138
139 public static RecipientEntry constructTopLevelEntry(
140 String displayName, int displayNameSource, String destination, int destinationType,
141 String destinationLabel, long contactId, long dataId,
142 String thumbnailUriAsString) {
143 return new RecipientEntry(
144 ENTRY_TYPE_PERSON, pickDisplayName(displayNameSource, displayName, destination),
145 destination, destinationType, destinationLabel,
146 contactId, dataId,
147 (thumbnailUriAsString != null ? Uri.parse(thumbnailUriAsString) : null), true);
148 }
149
150 public static RecipientEntry constructSecondLevelEntry(
151 String displayName, int displayNameSource, String destination, int destinationType,
152 String destinationLabel, long contactId, long dataId, String thumbnailUriAsString) {
153 return new RecipientEntry(
154 ENTRY_TYPE_PERSON, pickDisplayName(displayNameSource, displayName, destination),
155 destination, destinationType, destinationLabel,
156 contactId, dataId,
157 (thumbnailUriAsString != null ? Uri.parse(thumbnailUriAsString) : null), false);
158 }
159
160 public int getEntryType() {
161 return mEntryType;
162 }
163
164 public String getDisplayName() {
165 return mDisplayName;
166 }
167
168 public String getDestination() {
169 return mDestination;
170 }
171
172 public int getDestinationType() {
173 return mDestinationType;
174 }
175
176 public String getDestinationLabel() {
177 return mDestinationLabel;
178 }
179
180 public long getContactId() {
181 return mContactId;
182 }
183
184 public long getDataId() {
185 return mDataId;
186 }
187
188 public boolean isFirstLevel() {
189 return mIsFirstLevel;
190 }
191
192 public Uri getPhotoThumbnailUri() {
193 return mPhotoThumbnailUri;
194 }
195
196 /** This can be called outside main Looper thread. */
197 public synchronized void setPhotoBytes(byte[] photoBytes) {
198 mPhotoBytes = photoBytes;
199 }
200
201 /** This can be called outside main Looper thread. */
202 public synchronized byte[] getPhotoBytes() {
203 return mPhotoBytes;
204 }
205
206 public boolean isSeparator() {
207 return mIsDivider;
208 }
209
210 public boolean isSelectable() {
211 return mEntryType == ENTRY_TYPE_PERSON;
212 }