diff options
author | Scott Kennedy <skennedy@google.com> | 2013-11-21 14:31:33 -0800 |
---|---|---|
committer | Scott Kennedy <skennedy@google.com> | 2014-02-05 21:33:37 -0800 |
commit | ae07c2be104a1f95426b697f3074bea72bc140e1 (patch) | |
tree | 0c86989672f1a2876f8a6a6ca41d6e0e179bb1b7 /chips/src/com/android/ex | |
parent | 95fedd51882128dea2152c3d1c7ff194f8e557bf (diff) | |
download | android_frameworks_ex-ae07c2be104a1f95426b697f3074bea72bc140e1.tar.gz android_frameworks_ex-ae07c2be104a1f95426b697f3074bea72bc140e1.tar.bz2 android_frameworks_ex-ae07c2be104a1f95426b697f3074bea72bc140e1.zip |
Fix directory lookups
The previous "fix" disabled the lookups.
Now we will do the lookups, with the proper lookup key and
directory id. We also do a much better job of showing directory
images.
Bug: 11693322
Bug: 12793279
Change-Id: I372711fd7b485f3183516fce2b11f9eff46a9b23
Diffstat (limited to 'chips/src/com/android/ex')
10 files changed, 303 insertions, 110 deletions
diff --git a/chips/src/com/android/ex/chips/BaseRecipientAdapter.java b/chips/src/com/android/ex/chips/BaseRecipientAdapter.java index 531fd37..8233081 100644 --- a/chips/src/com/android/ex/chips/BaseRecipientAdapter.java +++ b/chips/src/com/android/ex/chips/BaseRecipientAdapter.java @@ -23,6 +23,8 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.net.Uri; import android.os.AsyncTask; import android.os.Handler; @@ -45,6 +47,7 @@ import android.widget.Filterable; import com.android.ex.chips.DropdownChipLayouter.AdapterType; import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -147,10 +150,11 @@ public abstract class BaseRecipientAdapter extends BaseAdapter implements Filter public final int destinationType; public final String destinationLabel; public final long contactId; + public final Long directoryId; public final long dataId; public final String thumbnailUriString; public final int displayNameSource; - public final boolean isGalContact; + public final String lookupKey; public TemporaryEntry( String displayName, @@ -158,31 +162,34 @@ public abstract class BaseRecipientAdapter extends BaseAdapter implements Filter int destinationType, String destinationLabel, long contactId, + Long directoryId, long dataId, String thumbnailUriString, int displayNameSource, - boolean isGalContact) { + String lookupKey) { this.displayName = displayName; this.destination = destination; this.destinationType = destinationType; this.destinationLabel = destinationLabel; this.contactId = contactId; + this.directoryId = directoryId; this.dataId = dataId; this.thumbnailUriString = thumbnailUriString; this.displayNameSource = displayNameSource; - this.isGalContact = isGalContact; + this.lookupKey = lookupKey; } - public TemporaryEntry(Cursor cursor, boolean isGalContact) { + public TemporaryEntry(Cursor cursor, Long directoryId) { this.displayName = cursor.getString(Queries.Query.NAME); this.destination = cursor.getString(Queries.Query.DESTINATION); this.destinationType = cursor.getInt(Queries.Query.DESTINATION_TYPE); this.destinationLabel = cursor.getString(Queries.Query.DESTINATION_LABEL); this.contactId = cursor.getLong(Queries.Query.CONTACT_ID); + this.directoryId = directoryId; this.dataId = cursor.getLong(Queries.Query.DATA_ID); this.thumbnailUriString = cursor.getString(Queries.Query.PHOTO_THUMBNAIL_URI); this.displayNameSource = cursor.getInt(Queries.Query.DISPLAY_NAME_SOURCE); - this.isGalContact = isGalContact; + this.lookupKey = cursor.getString(Queries.Query.LOOKUP_KEY); } } @@ -234,7 +241,8 @@ public abstract class BaseRecipientAdapter extends BaseAdapter implements Filter } try { - defaultDirectoryCursor = doQuery(constraint, mPreferredMaxResultCount, null); + defaultDirectoryCursor = doQuery(constraint, mPreferredMaxResultCount, + null /* directoryId */); if (defaultDirectoryCursor == null) { if (DEBUG) { @@ -254,7 +262,7 @@ public abstract class BaseRecipientAdapter extends BaseAdapter implements Filter // Note: At this point each entry doesn't contain any photo // (thus getPhotoBytes() returns null). putOneEntry(new TemporaryEntry(defaultDirectoryCursor, - false /* isGalContact */), + null /* directoryId */), true, entryMap, nonAggregatedEntries, existingDestinations); } @@ -385,7 +393,7 @@ public abstract class BaseRecipientAdapter extends BaseAdapter implements Filter if (cursor != null) { while (cursor.moveToNext()) { - tempEntries.add(new TemporaryEntry(cursor, true /* isGalContact */)); + tempEntries.add(new TemporaryEntry(cursor, mParams.directoryId)); } } } finally { @@ -695,8 +703,8 @@ public abstract class BaseRecipientAdapter extends BaseAdapter implements Filter entry.displayName, entry.displayNameSource, entry.destination, entry.destinationType, entry.destinationLabel, - entry.contactId, entry.dataId, entry.thumbnailUriString, true, - entry.isGalContact)); + entry.contactId, entry.directoryId, entry.dataId, entry.thumbnailUriString, + true, entry.lookupKey)); } else if (entryMap.containsKey(entry.contactId)) { // We already have a section for the person. final List<RecipientEntry> entryList = entryMap.get(entry.contactId); @@ -704,16 +712,16 @@ public abstract class BaseRecipientAdapter extends BaseAdapter implements Filter entry.displayName, entry.displayNameSource, entry.destination, entry.destinationType, entry.destinationLabel, - entry.contactId, entry.dataId, entry.thumbnailUriString, true, - entry.isGalContact)); + entry.contactId, entry.directoryId, entry.dataId, entry.thumbnailUriString, + true, entry.lookupKey)); } else { final List<RecipientEntry> entryList = new ArrayList<RecipientEntry>(); entryList.add(RecipientEntry.constructTopLevelEntry( entry.displayName, entry.displayNameSource, entry.destination, entry.destinationType, entry.destinationLabel, - entry.contactId, entry.dataId, entry.thumbnailUriString, true, - entry.isGalContact)); + entry.contactId, entry.directoryId, entry.dataId, entry.thumbnailUriString, + true, entry.lookupKey)); entryMap.put(entry.contactId, entryList); } } @@ -879,6 +887,39 @@ public abstract class BaseRecipientAdapter extends BaseAdapter implements Filter } finally { photoCursor.close(); } + } else { + InputStream inputStream = null; + ByteArrayOutputStream outputStream = null; + try { + inputStream = mContentResolver.openInputStream(photoThumbnailUri); + final Bitmap bitmap = BitmapFactory.decodeStream(inputStream); + + if (bitmap != null) { + outputStream = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream); + photoBytes = outputStream.toByteArray(); + + entry.setPhotoBytes(photoBytes); + mPhotoCacheMap.put(photoThumbnailUri, photoBytes); + } + } catch (final FileNotFoundException e) { + Log.w(TAG, "Error opening InputStream for photo", e); + } finally { + try { + if (inputStream != null) { + inputStream.close(); + } + } catch (IOException e) { + Log.e(TAG, "Error closing photo input stream", e); + } + try { + if (outputStream != null) { + outputStream.close(); + } + } catch (IOException e) { + Log.e(TAG, "Error closing photo output stream", e); + } + } } } diff --git a/chips/src/com/android/ex/chips/DropdownChipLayouter.java b/chips/src/com/android/ex/chips/DropdownChipLayouter.java index aceefab..6b0e78e 100644 --- a/chips/src/com/android/ex/chips/DropdownChipLayouter.java +++ b/chips/src/com/android/ex/chips/DropdownChipLayouter.java @@ -171,7 +171,7 @@ public class DropdownChipLayouter { if (thumbnailUri != null) { // TODO: see if this needs to be done outside the main thread // as it may be too slow to get immediately. - view.setImageURI(entry.getPhotoThumbnailUri()); + view.setImageURI(thumbnailUri); } else { view.setImageResource(getDefaultPhotoResId()); } diff --git a/chips/src/com/android/ex/chips/Queries.java b/chips/src/com/android/ex/chips/Queries.java index 9d31aec..1e66b96 100644 --- a/chips/src/com/android/ex/chips/Queries.java +++ b/chips/src/com/android/ex/chips/Queries.java @@ -18,6 +18,7 @@ package com.android.ex.chips; import android.content.res.Resources; import android.net.Uri; +import android.provider.ContactsContract; import android.provider.ContactsContract.CommonDataKinds.Email; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.Contacts; @@ -28,14 +29,16 @@ import android.provider.ContactsContract.Contacts; /* package */ class Queries { public static final Query PHONE = new Query(new String[] { - Contacts.DISPLAY_NAME, // 0 - Phone.NUMBER, // 1 - Phone.TYPE, // 2 - Phone.LABEL, // 3 - Phone.CONTACT_ID, // 4 - Phone._ID, // 5 - Contacts.PHOTO_THUMBNAIL_URI,// 6 - Contacts.DISPLAY_NAME_SOURCE // 7 + Contacts.DISPLAY_NAME, // 0 + Phone.NUMBER, // 1 + Phone.TYPE, // 2 + Phone.LABEL, // 3 + Phone.CONTACT_ID, // 4 + Phone._ID, // 5 + Contacts.PHOTO_THUMBNAIL_URI, // 6 + Contacts.DISPLAY_NAME_SOURCE, // 7 + Contacts.LOOKUP_KEY, // 8 + ContactsContract.CommonDataKinds.Email.MIMETYPE // 9 }, Phone.CONTENT_FILTER_URI, Phone.CONTENT_URI) { @Override @@ -46,14 +49,16 @@ import android.provider.ContactsContract.Contacts; }; public static final Query EMAIL = new Query(new String[]{ - Contacts.DISPLAY_NAME, // 0 - Email.DATA, // 1 - Email.TYPE, // 2 - Email.LABEL, // 3 - Email.CONTACT_ID, // 4 - Email._ID, // 5 - Contacts.PHOTO_THUMBNAIL_URI,// 6 - Contacts.DISPLAY_NAME_SOURCE // 7 + Contacts.DISPLAY_NAME, // 0 + Email.DATA, // 1 + Email.TYPE, // 2 + Email.LABEL, // 3 + Email.CONTACT_ID, // 4 + Email._ID, // 5 + Contacts.PHOTO_THUMBNAIL_URI, // 6 + Contacts.DISPLAY_NAME_SOURCE, // 7 + Contacts.LOOKUP_KEY, // 8 + ContactsContract.CommonDataKinds.Email.MIMETYPE // 9 }, Email.CONTENT_FILTER_URI, Email.CONTENT_URI) { @Override @@ -76,8 +81,10 @@ import android.provider.ContactsContract.Contacts; public static final int DATA_ID = 5; // long public static final int PHOTO_THUMBNAIL_URI = 6; // String public static final int DISPLAY_NAME_SOURCE = 7; // int + public static final int LOOKUP_KEY = 8; // String + public static final int MIME_TYPE = 9; // String - public Query (String[] projection, Uri contentFilter, Uri content) { + public Query(String[] projection, Uri contentFilter, Uri content) { mProjection = projection; mContentFilterUri = contentFilter; mContentUri = content; diff --git a/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java b/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java index 547a76b..f6f662d 100644 --- a/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java +++ b/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java @@ -23,6 +23,7 @@ import android.database.Cursor; import android.database.MatrixCursor; import android.net.Uri; import android.provider.ContactsContract; +import android.provider.ContactsContract.Contacts; import android.text.TextUtils; import android.text.util.Rfc822Token; import android.text.util.Rfc822Tokenizer; @@ -60,9 +61,11 @@ public class RecipientAlternatesAdapter extends CursorAdapter { public static final int QUERY_TYPE_EMAIL = 0; public static final int QUERY_TYPE_PHONE = 1; - private Query mQuery; + private final Long mDirectoryId; private DropdownChipLayouter mDropdownChipLayouter; + private static final Map<String, String> sCorrectedPhotoUris = new HashMap<String, String>(); + public interface RecipientMatchCallback { public void matchesFound(Map<String, RecipientEntry> results); /** @@ -123,7 +126,7 @@ public class RecipientAlternatesAdapter extends CursorAdapter { query.getProjection(), query.getProjection()[Queries.Query.DESTINATION] + " IN (" + bindString.toString() + ")", addressArray, null); - recipientEntries = processContactEntries(c); + recipientEntries = processContactEntries(c, null /* directoryId */); callback.matchesFound(recipientEntries); } finally { if (c != null) { @@ -163,6 +166,7 @@ public class RecipientAlternatesAdapter extends CursorAdapter { if (paramsList != null) { Cursor directoryContactsCursor = null; for (String unresolvedAddress : unresolvedAddresses) { + Long directoryId = null; for (int i = 0; i < paramsList.size(); i++) { try { directoryContactsCursor = doQuery(unresolvedAddress, 1, @@ -174,6 +178,7 @@ public class RecipientAlternatesAdapter extends CursorAdapter { directoryContactsCursor.close(); directoryContactsCursor = null; } else { + directoryId = paramsList.get(i).directoryId; break; } } @@ -181,7 +186,7 @@ public class RecipientAlternatesAdapter extends CursorAdapter { if (directoryContactsCursor != null) { try { final Map<String, RecipientEntry> entries = - processContactEntries(directoryContactsCursor); + processContactEntries(directoryContactsCursor, directoryId); for (final String address : entries.keySet()) { matchesNotFound.remove(address); @@ -212,7 +217,8 @@ public class RecipientAlternatesAdapter extends CursorAdapter { callback.matchesNotFound(matchesNotFound); } - private static HashMap<String, RecipientEntry> processContactEntries(Cursor c) { + private static HashMap<String, RecipientEntry> processContactEntries(Cursor c, + Long directoryId) { HashMap<String, RecipientEntry> recipientEntries = new HashMap<String, RecipientEntry>(); if (c != null && c.moveToFirst()) { do { @@ -225,10 +231,11 @@ public class RecipientAlternatesAdapter extends CursorAdapter { c.getInt(Queries.Query.DESTINATION_TYPE), c.getString(Queries.Query.DESTINATION_LABEL), c.getLong(Queries.Query.CONTACT_ID), + directoryId, c.getLong(Queries.Query.DATA_ID), c.getString(Queries.Query.PHOTO_THUMBNAIL_URI), true, - false /* isGalContact TODO(skennedy) We should look these up eventually */); + c.getString(Queries.Query.LOOKUP_KEY)); /* * In certain situations, we may have two results for one address, where one of the @@ -325,43 +332,74 @@ public class RecipientAlternatesAdapter extends CursorAdapter { return cursor; } - public RecipientAlternatesAdapter(Context context, long contactId, long currentId, - int queryMode, OnCheckedItemChangedListener listener, - DropdownChipLayouter dropdownChipLayouter) { - super(context, getCursorForConstruction(context, contactId, queryMode), 0); + public RecipientAlternatesAdapter(Context context, long contactId, Long directoryId, + String lookupKey, long currentId, int queryMode, OnCheckedItemChangedListener listener, + DropdownChipLayouter dropdownChipLayouter) { + super(context, + getCursorForConstruction(context, contactId, directoryId, lookupKey, queryMode), 0); mCurrentId = currentId; + mDirectoryId = directoryId; mCheckedItemChangedListener = listener; - if (queryMode == QUERY_TYPE_EMAIL) { - mQuery = Queries.EMAIL; - } else if (queryMode == QUERY_TYPE_PHONE) { - mQuery = Queries.PHONE; - } else { - mQuery = Queries.EMAIL; - Log.e(TAG, "Unsupported query type: " + queryMode); - } - mDropdownChipLayouter = dropdownChipLayouter; } - private static Cursor getCursorForConstruction(Context context, long contactId, int queryType) { + private static Cursor getCursorForConstruction(Context context, long contactId, + Long directoryId, String lookupKey, int queryType) { final Cursor cursor; + final String desiredMimeType; if (queryType == QUERY_TYPE_EMAIL) { + final Uri uri; + final StringBuilder selection = new StringBuilder(); + selection.append(Queries.EMAIL.getProjection()[Queries.Query.CONTACT_ID]); + selection.append(" = ?"); + + if (directoryId == null || lookupKey == null) { + uri = Queries.EMAIL.getContentUri(); + desiredMimeType = null; + } else { + final Uri.Builder builder = Contacts.getLookupUri(contactId, lookupKey).buildUpon(); + builder.appendPath(Contacts.Entity.CONTENT_DIRECTORY) + .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, + String.valueOf(directoryId)); + uri = builder.build(); + desiredMimeType = ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE; + } cursor = context.getContentResolver().query( - Queries.EMAIL.getContentUri(), + uri, Queries.EMAIL.getProjection(), - Queries.EMAIL.getProjection()[Queries.Query.CONTACT_ID] + " =?", new String[] { + selection.toString(), new String[] { String.valueOf(contactId) }, null); } else { + final Uri uri; + final StringBuilder selection = new StringBuilder(); + selection.append(Queries.PHONE.getProjection()[Queries.Query.CONTACT_ID]); + selection.append(" = ?"); + + if (lookupKey == null) { + uri = Queries.PHONE.getContentUri(); + desiredMimeType = null; + } else { + final Uri.Builder builder = Contacts.getLookupUri(contactId, lookupKey).buildUpon(); + builder.appendPath(Contacts.Entity.CONTENT_DIRECTORY) + .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, + String.valueOf(directoryId)); + uri = builder.build(); + desiredMimeType = ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE; + } cursor = context.getContentResolver().query( - Queries.PHONE.getContentUri(), + uri, Queries.PHONE.getProjection(), - Queries.PHONE.getProjection()[Queries.Query.CONTACT_ID] + " =?", new String[] { + selection.toString(), new String[] { String.valueOf(contactId) }, null); } - return removeDuplicateDestinations(cursor); + + final Cursor resultCursor = removeUndesiredDestinations(cursor, desiredMimeType, lookupKey); + cursor.close(); + + return resultCursor; } /** @@ -374,22 +412,53 @@ public class RecipientAlternatesAdapter extends CursorAdapter { * - This method creates a MatrixCursor, so all data will be kept in memory. We wouldn't want * to do this if the original cursor is large, but it's okay here because the alternate list * won't be that big. + * + * @param desiredMimeType If this is non-<code>null</code>, only entries with this mime type + * will be added to the cursor + * @param lookupKey The lookup key used for this contact if there isn't one in the cursor. This + * should be the same one used in the query that returned the cursor */ // Visible for testing - /* package */ static Cursor removeDuplicateDestinations(Cursor original) { + static Cursor removeUndesiredDestinations(final Cursor original, final String desiredMimeType, + final String lookupKey) { final MatrixCursor result = new MatrixCursor( original.getColumnNames(), original.getCount()); final HashSet<String> destinationsSeen = new HashSet<String>(); + String defaultDisplayName = null; + String defaultPhotoThumbnailUri = null; + int defaultDisplayNameSource = 0; + + // Find some nice defaults in case we need them + original.moveToPosition(-1); + while (original.moveToNext()) { + final String mimeType = original.getString(Query.MIME_TYPE); + + if (ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE.equals( + mimeType)) { + // Store this data + defaultDisplayName = original.getString(Query.NAME); + defaultPhotoThumbnailUri = original.getString(Query.PHOTO_THUMBNAIL_URI); + defaultDisplayNameSource = original.getInt(Query.DISPLAY_NAME_SOURCE); + break; + } + } + original.moveToPosition(-1); while (original.moveToNext()) { + if (desiredMimeType != null) { + final String mimeType = original.getString(Query.MIME_TYPE); + if (!desiredMimeType.equals(mimeType)) { + continue; + } + } final String destination = original.getString(Query.DESTINATION); if (destinationsSeen.contains(destination)) { continue; } destinationsSeen.add(destination); - result.addRow(new Object[] { + final Object[] row = new Object[] { original.getString(Query.NAME), original.getString(Query.DESTINATION), original.getInt(Query.DESTINATION_TYPE), @@ -397,8 +466,48 @@ public class RecipientAlternatesAdapter extends CursorAdapter { original.getLong(Query.CONTACT_ID), original.getLong(Query.DATA_ID), original.getString(Query.PHOTO_THUMBNAIL_URI), - original.getInt(Query.DISPLAY_NAME_SOURCE) - }); + original.getInt(Query.DISPLAY_NAME_SOURCE), + original.getString(Query.LOOKUP_KEY), + original.getString(Query.MIME_TYPE) + }; + + if (row[Query.NAME] == null) { + row[Query.NAME] = defaultDisplayName; + } + if (row[Query.PHOTO_THUMBNAIL_URI] == null) { + row[Query.PHOTO_THUMBNAIL_URI] = defaultPhotoThumbnailUri; + } + if ((Integer) row[Query.DISPLAY_NAME_SOURCE] == 0) { + row[Query.DISPLAY_NAME_SOURCE] = defaultDisplayNameSource; + } + if (row[Query.LOOKUP_KEY] == null) { + row[Query.LOOKUP_KEY] = lookupKey; + } + + // Ensure we don't have two '?' like content://.../...?account_name=...?sz=... + final String photoThumbnailUri = (String) row[Query.PHOTO_THUMBNAIL_URI]; + if (photoThumbnailUri != null) { + if (sCorrectedPhotoUris.containsKey(photoThumbnailUri)) { + row[Query.PHOTO_THUMBNAIL_URI] = sCorrectedPhotoUris.get(photoThumbnailUri); + } else if (photoThumbnailUri.indexOf('?') != photoThumbnailUri.lastIndexOf('?')) { + final String[] parts = photoThumbnailUri.split("\\?"); + final StringBuilder correctedUriBuilder = new StringBuilder(); + for (int i = 0; i < parts.length; i++) { + if (i == 1) { + correctedUriBuilder.append("?"); // We only want one of these + } else if (i > 1) { + correctedUriBuilder.append("&"); // And we want these elsewhere + } + correctedUriBuilder.append(parts[i]); + } + + final String correctedUri = correctedUriBuilder.toString(); + sCorrectedPhotoUris.put(photoThumbnailUri, correctedUri); + row[Query.PHOTO_THUMBNAIL_URI] = correctedUri; + } + } + + result.addRow(row); } return result; @@ -423,10 +532,11 @@ public class RecipientAlternatesAdapter extends CursorAdapter { c.getInt(Queries.Query.DESTINATION_TYPE), c.getString(Queries.Query.DESTINATION_LABEL), c.getLong(Queries.Query.CONTACT_ID), + mDirectoryId, c.getLong(Queries.Query.DATA_ID), c.getString(Queries.Query.PHOTO_THUMBNAIL_URI), true, - false /* isGalContact TODO(skennedy) We should look these up eventually */); + c.getString(Queries.Query.LOOKUP_KEY)); } @Override diff --git a/chips/src/com/android/ex/chips/RecipientEditTextView.java b/chips/src/com/android/ex/chips/RecipientEditTextView.java index 9a4609d..eca0afb 100644 --- a/chips/src/com/android/ex/chips/RecipientEditTextView.java +++ b/chips/src/com/android/ex/chips/RecipientEditTextView.java @@ -483,7 +483,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements } protected ScrollView getScrollView() { - return mScrollView; + return mScrollView; } @Override @@ -1571,7 +1571,8 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements } private ListAdapter createAlternatesAdapter(DrawableRecipientChip chip) { - return new RecipientAlternatesAdapter(getContext(), chip.getContactId(), chip.getDataId(), + return new RecipientAlternatesAdapter(getContext(), chip.getContactId(), + chip.getDirectoryId(), chip.getLookupKey(), chip.getDataId(), getAdapter().getQueryType(), this, mDropdownChipLayouter); } @@ -2046,8 +2047,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements return constructChipSpan( RecipientEntry.constructFakeEntry((String) text, isValid(text.toString())), true, false); - } else if (currentChip.getContactId() == RecipientEntry.GENERATED_CONTACT - || currentChip.isGalContact()) { + } else if (currentChip.getContactId() == RecipientEntry.GENERATED_CONTACT) { int start = getChipStart(currentChip); int end = getChipEnd(currentChip); getSpannable().removeSpan(currentChip); @@ -2590,7 +2590,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements addresses.add(createAddressText(chip.getEntry())); } } - final BaseRecipientAdapter adapter = (BaseRecipientAdapter) getAdapter(); + final BaseRecipientAdapter adapter = getAdapter(); RecipientAlternatesAdapter.getMatchingRecipients(getContext(), adapter, addresses, adapter.getAccount(), new RecipientMatchCallback() { @Override @@ -2718,7 +2718,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements addresses.add(createAddressText(chip.getEntry())); } } - final BaseRecipientAdapter adapter = (BaseRecipientAdapter) getAdapter(); + final BaseRecipientAdapter adapter = getAdapter(); RecipientAlternatesAdapter.getMatchingRecipients(getContext(), adapter, addresses, adapter.getAccount(), new RecipientMatchCallback() { diff --git a/chips/src/com/android/ex/chips/RecipientEntry.java b/chips/src/com/android/ex/chips/RecipientEntry.java index 30fccae..7d9b87f 100644 --- a/chips/src/com/android/ex/chips/RecipientEntry.java +++ b/chips/src/com/android/ex/chips/RecipientEntry.java @@ -61,6 +61,8 @@ public class RecipientEntry { private final String mDestinationLabel; /** ID for the person */ private final long mContactId; + /** ID for the directory this contact came from, or <code>null</code> */ + private final Long mDirectoryId; /** ID for the destination */ private final long mDataId; private final boolean mIsDivider; @@ -74,11 +76,13 @@ public class RecipientEntry { */ private byte[] mPhotoBytes; - private final boolean mIsGalContact; + /** See {@link ContactsContract.Contacts#LOOKUP_KEY} */ + private final String mLookupKey; private RecipientEntry(int entryType, String displayName, String destination, - int destinationType, String destinationLabel, long contactId, long dataId, - Uri photoThumbnailUri, boolean isFirstLevel, boolean isValid, boolean isGalContact) { + int destinationType, String destinationLabel, long contactId, Long directoryId, + long dataId, Uri photoThumbnailUri, boolean isFirstLevel, boolean isValid, + String lookupKey) { mEntryType = entryType; mIsFirstLevel = isFirstLevel; mDisplayName = displayName; @@ -86,12 +90,13 @@ public class RecipientEntry { mDestinationType = destinationType; mDestinationLabel = destinationLabel; mContactId = contactId; + mDirectoryId = directoryId; mDataId = dataId; mPhotoThumbnailUri = photoThumbnailUri; mPhotoBytes = null; mIsDivider = false; mIsValid = isValid; - mIsGalContact = isGalContact; + mLookupKey = lookupKey; } public boolean isValid() { @@ -116,8 +121,8 @@ public class RecipientEntry { final String tokenizedAddress = tokens.length > 0 ? tokens[0].getAddress() : address; return new RecipientEntry(ENTRY_TYPE_PERSON, tokenizedAddress, tokenizedAddress, - INVALID_DESTINATION_TYPE, null, - INVALID_CONTACT, INVALID_CONTACT, null, true, isValid, false /* isGalContact */); + INVALID_DESTINATION_TYPE, null, INVALID_CONTACT, null /* directoryId */, + INVALID_CONTACT, null, true, isValid, null /* lookupKey */); } /** @@ -126,8 +131,8 @@ public class RecipientEntry { public static RecipientEntry constructFakePhoneEntry(final String phoneNumber, final boolean isValid) { return new RecipientEntry(ENTRY_TYPE_PERSON, phoneNumber, phoneNumber, - INVALID_DESTINATION_TYPE, null, - INVALID_CONTACT, INVALID_CONTACT, null, true, isValid, false /* isGalContact */); + INVALID_DESTINATION_TYPE, null, INVALID_CONTACT, null /* directoryId */, + INVALID_CONTACT, null, true, isValid, null /* lookupKey */); } /** @@ -149,35 +154,37 @@ public class RecipientEntry { public static RecipientEntry constructGeneratedEntry(String display, String address, boolean isValid) { return new RecipientEntry(ENTRY_TYPE_PERSON, display, address, INVALID_DESTINATION_TYPE, - null, GENERATED_CONTACT, GENERATED_CONTACT, null, true, isValid, - false /* isGalContact */); + null, GENERATED_CONTACT, null /* directoryId */, GENERATED_CONTACT, null, true, + isValid, null /* lookupKey */); } public static RecipientEntry constructTopLevelEntry(String displayName, int displayNameSource, String destination, int destinationType, String destinationLabel, long contactId, - long dataId, Uri photoThumbnailUri, boolean isValid, boolean isGalContact) { + Long directoryId, long dataId, Uri photoThumbnailUri, boolean isValid, + String lookupKey) { return new RecipientEntry(ENTRY_TYPE_PERSON, pickDisplayName(displayNameSource, displayName, destination), destination, destinationType, destinationLabel, - contactId, dataId, photoThumbnailUri, true, isValid, isGalContact); + contactId, directoryId, dataId, photoThumbnailUri, true, isValid, lookupKey); } public static RecipientEntry constructTopLevelEntry(String displayName, int displayNameSource, String destination, int destinationType, String destinationLabel, long contactId, - long dataId, String thumbnailUriAsString, boolean isValid, boolean isGalContact) { + Long directoryId, long dataId, String thumbnailUriAsString, boolean isValid, + String lookupKey) { return new RecipientEntry(ENTRY_TYPE_PERSON, pickDisplayName(displayNameSource, displayName, destination), destination, destinationType, destinationLabel, - contactId, dataId, (thumbnailUriAsString != null ? Uri.parse(thumbnailUriAsString) - : null), true, isValid, isGalContact); + contactId, directoryId, dataId, (thumbnailUriAsString != null + ? Uri.parse(thumbnailUriAsString) : null), true, isValid, lookupKey); } public static RecipientEntry constructSecondLevelEntry(String displayName, int displayNameSource, String destination, int destinationType, - String destinationLabel, long contactId, long dataId, String thumbnailUriAsString, - boolean isValid, boolean isGalContact) { + String destinationLabel, long contactId, Long directoryId, long dataId, + String thumbnailUriAsString, boolean isValid, String lookupKey) { return new RecipientEntry(ENTRY_TYPE_PERSON, pickDisplayName(displayNameSource, displayName, destination), destination, destinationType, destinationLabel, - contactId, dataId, (thumbnailUriAsString != null ? Uri.parse(thumbnailUriAsString) - : null), false, isValid, isGalContact); + contactId, directoryId, dataId, (thumbnailUriAsString != null + ? Uri.parse(thumbnailUriAsString) : null), false, isValid, lookupKey); } public int getEntryType() { @@ -204,6 +211,10 @@ public class RecipientEntry { return mContactId; } + public Long getDirectoryId() { + return mDirectoryId; + } + public long getDataId() { return mDataId; } @@ -234,8 +245,8 @@ public class RecipientEntry { return mEntryType == ENTRY_TYPE_PERSON; } - public boolean isGalContact() { - return mIsGalContact; + public String getLookupKey() { + return mLookupKey; } @Override diff --git a/chips/src/com/android/ex/chips/recipientchip/BaseRecipientChip.java b/chips/src/com/android/ex/chips/recipientchip/BaseRecipientChip.java index 032d3b2..8012b5c 100644 --- a/chips/src/com/android/ex/chips/recipientchip/BaseRecipientChip.java +++ b/chips/src/com/android/ex/chips/recipientchip/BaseRecipientChip.java @@ -50,6 +50,16 @@ interface BaseRecipientChip { long getContactId(); /** + * Get the directory id of the contact associated with this chip. + */ + Long getDirectoryId(); + + /** + * Get the directory lookup key associated with this chip, or <code>null</code>. + */ + String getLookupKey(); + + /** * Get the id of the data associated with this chip. */ long getDataId(); @@ -70,11 +80,4 @@ interface BaseRecipientChip { * before any reverse lookups. */ CharSequence getOriginalText(); - - /** - * Checks if this contact was retrieved from a GAL lookup. - * - * @return <code>true</code> if it came from GAL, <code>false</code> otherwise - */ - boolean isGalContact(); } diff --git a/chips/src/com/android/ex/chips/recipientchip/InvisibleRecipientChip.java b/chips/src/com/android/ex/chips/recipientchip/InvisibleRecipientChip.java index 11a66da..455f2cb 100644 --- a/chips/src/com/android/ex/chips/recipientchip/InvisibleRecipientChip.java +++ b/chips/src/com/android/ex/chips/recipientchip/InvisibleRecipientChip.java @@ -62,6 +62,16 @@ public class InvisibleRecipientChip extends ReplacementSpan implements DrawableR } @Override + public Long getDirectoryId() { + return mDelegate.getDirectoryId(); + } + + @Override + public String getLookupKey() { + return mDelegate.getLookupKey(); + } + + @Override public long getDataId() { return mDelegate.getDataId(); } @@ -82,11 +92,6 @@ public class InvisibleRecipientChip extends ReplacementSpan implements DrawableR } @Override - public boolean isGalContact() { - return mDelegate.isGalContact(); - } - - @Override public void draw(final Canvas canvas, final CharSequence text, final int start, final int end, final float x, final int top, final int y, final int bottom, final Paint paint) { // Do nothing. diff --git a/chips/src/com/android/ex/chips/recipientchip/SimpleRecipientChip.java b/chips/src/com/android/ex/chips/recipientchip/SimpleRecipientChip.java index ac8e897..533f53f 100644 --- a/chips/src/com/android/ex/chips/recipientchip/SimpleRecipientChip.java +++ b/chips/src/com/android/ex/chips/recipientchip/SimpleRecipientChip.java @@ -27,6 +27,10 @@ class SimpleRecipientChip implements BaseRecipientChip { private final long mContactId; + private final Long mDirectoryId; + + private final String mLookupKey; + private final long mDataId; private final RecipientEntry mEntry; @@ -39,6 +43,8 @@ class SimpleRecipientChip implements BaseRecipientChip { mDisplay = entry.getDisplayName(); mValue = entry.getDestination().trim(); mContactId = entry.getContactId(); + mDirectoryId = entry.getDirectoryId(); + mLookupKey = entry.getLookupKey(); mDataId = entry.getDataId(); mEntry = entry; } @@ -69,6 +75,16 @@ class SimpleRecipientChip implements BaseRecipientChip { } @Override + public Long getDirectoryId() { + return mDirectoryId; + } + + @Override + public String getLookupKey() { + return mLookupKey; + } + + @Override public long getDataId() { return mDataId; } @@ -93,11 +109,6 @@ class SimpleRecipientChip implements BaseRecipientChip { } @Override - public boolean isGalContact() { - return mEntry.isGalContact(); - } - - @Override public String toString() { return mDisplay + " <" + mValue + ">"; } diff --git a/chips/src/com/android/ex/chips/recipientchip/VisibleRecipientChip.java b/chips/src/com/android/ex/chips/recipientchip/VisibleRecipientChip.java index 4637f69..ce32e3d 100644 --- a/chips/src/com/android/ex/chips/recipientchip/VisibleRecipientChip.java +++ b/chips/src/com/android/ex/chips/recipientchip/VisibleRecipientChip.java @@ -63,6 +63,16 @@ public class VisibleRecipientChip extends ImageSpan implements DrawableRecipient } @Override + public Long getDirectoryId() { + return mDelegate.getDirectoryId(); + } + + @Override + public String getLookupKey() { + return mDelegate.getLookupKey(); + } + + @Override public long getDataId() { return mDelegate.getDataId(); } @@ -83,11 +93,6 @@ public class VisibleRecipientChip extends ImageSpan implements DrawableRecipient } @Override - public boolean isGalContact() { - return mDelegate.isGalContact(); - } - - @Override public Rect getBounds() { return getDrawable().getBounds(); } |