diff options
Diffstat (limited to 'chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java')
-rw-r--r-- | chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java | 159 |
1 files changed, 121 insertions, 38 deletions
diff --git a/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java b/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java index b54d83d..00f1ff4 100644 --- a/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java +++ b/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java @@ -16,9 +16,13 @@ package com.android.ex.chips; +import android.accounts.Account; +import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; import android.database.MatrixCursor; +import android.net.Uri; +import android.provider.ContactsContract; import android.text.util.Rfc822Token; import android.text.util.Rfc822Tokenizer; import android.util.Log; @@ -29,11 +33,14 @@ import android.widget.CursorAdapter; import android.widget.ImageView; import android.widget.TextView; +import com.android.ex.chips.BaseRecipientAdapter.DirectoryListQuery; +import com.android.ex.chips.BaseRecipientAdapter.DirectorySearchParams; import com.android.ex.chips.Queries.Query; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.List; /** * RecipientAlternatesAdapter backs the RecipientEditTextView for managing contacts @@ -55,9 +62,13 @@ public class RecipientAlternatesAdapter extends CursorAdapter { public static final int QUERY_TYPE_PHONE = 1; private Query mQuery; - public static HashMap<String, RecipientEntry> getMatchingRecipients(Context context, - ArrayList<String> inAddresses) { - return getMatchingRecipients(context, inAddresses, QUERY_TYPE_EMAIL); + public interface RecipientMatchCallback { + public void matchesFound(HashMap<String, RecipientEntry> results); + } + + public static void getMatchingRecipients(Context context, ArrayList<String> inAddresses, + Account account, RecipientMatchCallback callback) { + getMatchingRecipients(context, inAddresses, QUERY_TYPE_EMAIL, account, callback); } /** @@ -67,10 +78,11 @@ public class RecipientAlternatesAdapter extends CursorAdapter { * * @param context Context. * @param inAddresses Array of addresses on which to perform the lookup. + * @param callback RecipientMatchCallback called when a match or matches are found. * @return HashMap<String,RecipientEntry> */ - public static HashMap<String, RecipientEntry> getMatchingRecipients(Context context, - ArrayList<String> inAddresses, int addressType) { + public static void getMatchingRecipients(Context context, ArrayList<String> inAddresses, + int addressType, Account account, RecipientMatchCallback callback) { Queries.Query query; if (addressType == QUERY_TYPE_EMAIL) { query = Queries.EMAIL; @@ -78,12 +90,12 @@ public class RecipientAlternatesAdapter extends CursorAdapter { query = Queries.PHONE; } int addressesSize = Math.min(MAX_LOOKUPS, inAddresses.size()); - String[] addresses = new String[addressesSize]; + HashSet<String> addresses = new HashSet<String>(); StringBuilder bindString = new StringBuilder(); // Create the "?" string and set up arguments. for (int i = 0; i < addressesSize; i++) { Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(inAddresses.get(i).toLowerCase()); - addresses[i] = (tokens.length > 0 ? tokens[0].getAddress() : inAddresses.get(i)); + addresses.add(tokens.length > 0 ? tokens[0].getAddress() : inAddresses.get(i)); bindString.append("?"); if (i < addressesSize - 1) { bindString.append(","); @@ -94,44 +106,115 @@ public class RecipientAlternatesAdapter extends CursorAdapter { Log.d(TAG, "Doing reverse lookup for " + addresses.toString()); } - HashMap<String, RecipientEntry> recipientEntries = new HashMap<String, RecipientEntry>(); - Cursor c = context.getContentResolver().query( - query.getContentUri(), - query.getProjection(), - query.getProjection()[Queries.Query.DESTINATION] + " IN (" + bindString.toString() - + ")", addresses, null); - - if (c != null) { - try { - if (c.moveToFirst()) { - do { - String address = c.getString(Queries.Query.DESTINATION); - recipientEntries.put(address, RecipientEntry.constructTopLevelEntry( - c.getString(Queries.Query.NAME), - c.getInt(Queries.Query.DISPLAY_NAME_SOURCE), - c.getString(Queries.Query.DESTINATION), - c.getInt(Queries.Query.DESTINATION_TYPE), - c.getString(Queries.Query.DESTINATION_LABEL), - c.getLong(Queries.Query.CONTACT_ID), - c.getLong(Queries.Query.DATA_ID), - c.getString(Queries.Query.PHOTO_THUMBNAIL_URI), - true)); - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "Received reverse look up information for " + address - + " RESULTS: " - + " NAME : " + c.getString(Queries.Query.NAME) - + " CONTACT ID : " + c.getLong(Queries.Query.CONTACT_ID) - + " ADDRESS :" + c.getString(Queries.Query.DESTINATION)); + String[] addressArray = new String[addresses.size()]; + addresses.toArray(addressArray); + HashMap<String, RecipientEntry> recipientEntries = null; + Cursor c = null; + + try { + c = context.getContentResolver().query( + query.getContentUri(), + query.getProjection(), + query.getProjection()[Queries.Query.DESTINATION] + " IN (" + + bindString.toString() + ")", addressArray, null); + recipientEntries = processContactEntries(c); + callback.matchesFound(recipientEntries); + } finally { + if (c != null) { + c.close(); + } + } + // See if any entries did not resolve; if so, we need to check other + // directories + if (recipientEntries.size() < addresses.size()) { + final List<DirectorySearchParams> paramsList; + Cursor directoryCursor = context.getContentResolver().query(DirectoryListQuery.URI, + DirectoryListQuery.PROJECTION, null, null, null); + paramsList = BaseRecipientAdapter.setupOtherDirectories(context, directoryCursor, + account); + // Run a directory query for each unmatched recipient. + HashSet<String> unresolvedAddresses = new HashSet<String>(); + for (String address : addresses) { + if (!recipientEntries.containsKey(address)) { + unresolvedAddresses.add(address); + } + } + Cursor directoryContactsCursor = null; + for (String unresolvedAddress : unresolvedAddresses) { + for (int i = 0; i < paramsList.size(); i++) { + try { + directoryContactsCursor = doQuery(unresolvedAddress, 1, + paramsList.get(i).directoryId, account, + context.getContentResolver(), query); + } finally { + if (directoryContactsCursor != null + && directoryContactsCursor.getCount() == 0) { + directoryContactsCursor.close(); + directoryContactsCursor = null; + } else { + break; } - } while (c.moveToNext()); + } + } + if (directoryContactsCursor != null) { + try { + callback.matchesFound(processContactEntries(directoryContactsCursor)); + } finally { + directoryContactsCursor.close(); + } } - } finally { - c.close(); } } + } + + private static HashMap<String, RecipientEntry> processContactEntries(Cursor c) { + HashMap<String, RecipientEntry> recipientEntries = new HashMap<String, RecipientEntry>(); + if (c != null && c.moveToFirst()) { + do { + String address = c.getString(Queries.Query.DESTINATION); + recipientEntries.put(address, RecipientEntry.constructTopLevelEntry( + c.getString(Queries.Query.NAME), + c.getInt(Queries.Query.DISPLAY_NAME_SOURCE), + c.getString(Queries.Query.DESTINATION), + c.getInt(Queries.Query.DESTINATION_TYPE), + c.getString(Queries.Query.DESTINATION_LABEL), + c.getLong(Queries.Query.CONTACT_ID), + c.getLong(Queries.Query.DATA_ID), + c.getString(Queries.Query.PHOTO_THUMBNAIL_URI), + true)); + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "Received reverse look up information for " + address + + " RESULTS: " + + " NAME : " + c.getString(Queries.Query.NAME) + + " CONTACT ID : " + c.getLong(Queries.Query.CONTACT_ID) + + " ADDRESS :" + c.getString(Queries.Query.DESTINATION)); + } + } while (c.moveToNext()); + } return recipientEntries; } + private static Cursor doQuery(CharSequence constraint, int limit, Long directoryId, + Account account, ContentResolver resolver, Query query) { + final Uri.Builder builder = query + .getContentFilterUri() + .buildUpon() + .appendPath(constraint.toString()) + .appendQueryParameter(ContactsContract.LIMIT_PARAM_KEY, + String.valueOf(limit + BaseRecipientAdapter.ALLOWANCE_FOR_DUPLICATES)); + if (directoryId != null) { + builder.appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, + String.valueOf(directoryId)); + } + if (account != null) { + builder.appendQueryParameter(BaseRecipientAdapter.PRIMARY_ACCOUNT_NAME, account.name); + builder.appendQueryParameter(BaseRecipientAdapter.PRIMARY_ACCOUNT_TYPE, account.type); + } + final Cursor cursor = resolver.query(builder.build(), query.getProjection(), null, null, + null); + return cursor; + } + public RecipientAlternatesAdapter(Context context, long contactId, long currentId, int viewId, OnCheckedItemChangedListener listener) { this(context, contactId, currentId, viewId, QUERY_TYPE_EMAIL, listener); |