diff options
author | Dmitri Plotnikov <dplotnikov@google.com> | 2010-09-29 18:07:12 -0700 |
---|---|---|
committer | Dmitri Plotnikov <dplotnikov@google.com> | 2010-09-29 18:07:12 -0700 |
commit | 17d4817661d16464ffa0fd02cb6d1b362e96b8a1 (patch) | |
tree | d44454d2a4012703a3f28ca573c76f58d61844cc /common/java/com/android/common/contacts | |
parent | eb71cf6812bdb53bda75ac37a185f78f43ddfcef (diff) | |
download | android_frameworks_ex-17d4817661d16464ffa0fd02cb6d1b362e96b8a1.tar.gz android_frameworks_ex-17d4817661d16464ffa0fd02cb6d1b362e96b8a1.tar.bz2 android_frameworks_ex-17d4817661d16464ffa0fd02cb6d1b362e96b8a1.zip |
De-duping autocomplete email addresses
Change-Id: I5029a9fb49862d87a32dcf87772a4e746887d0fa
Diffstat (limited to 'common/java/com/android/common/contacts')
-rw-r--r-- | common/java/com/android/common/contacts/BaseEmailAddressAdapter.java | 88 |
1 files changed, 82 insertions, 6 deletions
diff --git a/common/java/com/android/common/contacts/BaseEmailAddressAdapter.java b/common/java/com/android/common/contacts/BaseEmailAddressAdapter.java index 8a9d3cf..6789a2c 100644 --- a/common/java/com/android/common/contacts/BaseEmailAddressAdapter.java +++ b/common/java/com/android/common/contacts/BaseEmailAddressAdapter.java @@ -65,13 +65,19 @@ public abstract class BaseEmailAddressAdapter extends CompositeCursorAdapter imp private static final String LIMIT_PARAM_KEY = "limit"; /** - * The preferred number of results to be retrieved. This number may be - * exceeded if there are several directories configured, because we will - * use the same limit for all directories. + * The preferred number of results to be retrieved. This number may be + * exceeded if there are several directories configured, because we will use + * the same limit for all directories. */ private static final int DEFAULT_PREFERRED_MAX_RESULT_COUNT = 10; /** + * The number of extra entries requested to allow for duplicates. Duplicates + * are removed from the overall result. + */ + private static final int ALLOWANCE_FOR_DUPLICATES = 5; + + /** * The "Searching..." message will be displayed if search is not complete * within this many milliseconds. */ @@ -217,7 +223,8 @@ public abstract class BaseEmailAddressAdapter extends CompositeCursorAdapter imp Uri uri = Email.CONTENT_FILTER_URI.buildUpon() .appendPath(constraint.toString()) .appendQueryParameter(DIRECTORY_PARAM_KEY, String.valueOf(mDirectoryId)) - .appendQueryParameter(LIMIT_PARAM_KEY, String.valueOf(getLimit())) + .appendQueryParameter(LIMIT_PARAM_KEY, + String.valueOf(getLimit() + ALLOWANCE_FOR_DUPLICATES)) .build(); Cursor cursor = mContentResolver.query( uri, EmailQuery.PROJECTION, null, null, null); @@ -331,7 +338,11 @@ public abstract class BaseEmailAddressAdapter extends CompositeCursorAdapter imp @Override protected boolean isEnabled(int partitionIndex, int position) { // The "Searching..." item should not be selectable - return !((DirectoryPartition)getPartition(partitionIndex)).loading; + return !isLoading(partitionIndex); + } + + private boolean isLoading(int partitionIndex) { + return ((DirectoryPartition)getPartition(partitionIndex)).loading; } @Override @@ -488,7 +499,7 @@ public abstract class BaseEmailAddressAdapter extends CompositeCursorAdapter imp if (partition.loading && TextUtils.equals(constraint, partition.constraint)) { partition.loading = false; mHandler.removeMessages(MESSAGE_SEARCH_PENDING, partition); - changeCursor(partitionIndex, cursor); + changeCursor(partitionIndex, removeDuplicatesAndTruncate(partitionIndex, cursor)); } else { // We got the result for an unexpected query (the user is still typing) // Just ignore this result @@ -501,6 +512,71 @@ public abstract class BaseEmailAddressAdapter extends CompositeCursorAdapter imp } } + /** + * Post-process the cursor to eliminate duplicates. Closes the original cursor + * and returns a new one. + */ + private Cursor removeDuplicatesAndTruncate(int partition, Cursor cursor) { + if (cursor == null) { + return null; + } + + if (cursor.getCount() <= DEFAULT_PREFERRED_MAX_RESULT_COUNT + && !hasDuplicates(cursor, partition)) { + return cursor; + } + + int count = 0; + MatrixCursor newCursor = new MatrixCursor(EmailQuery.PROJECTION); + cursor.moveToPosition(-1); + while (cursor.moveToNext() && count < DEFAULT_PREFERRED_MAX_RESULT_COUNT) { + String displayName = cursor.getString(EmailQuery.NAME); + String emailAddress = cursor.getString(EmailQuery.ADDRESS); + if (!isDuplicate(emailAddress, partition)) { + newCursor.addRow(new Object[]{displayName, emailAddress}); + count++; + } + } + cursor.close(); + + return newCursor; + } + + private boolean hasDuplicates(Cursor cursor, int partition) { + cursor.moveToPosition(-1); + while (cursor.moveToNext()) { + String emailAddress = cursor.getString(EmailQuery.ADDRESS); + if (isDuplicate(emailAddress, partition)) { + return true; + } + } + return false; + } + + /** + * Checks if the supplied email address is already present in partitions other + * than the supplied one. + */ + private boolean isDuplicate(String emailAddress, int excludePartition) { + int partitionCount = getPartitionCount(); + for (int partition = 0; partition < partitionCount; partition++) { + if (partition != excludePartition && !isLoading(partition)) { + Cursor cursor = getCursor(partition); + if (cursor != null) { + cursor.moveToPosition(-1); + while (cursor.moveToNext()) { + String address = cursor.getString(EmailQuery.ADDRESS); + if (TextUtils.equals(emailAddress, address)) { + return true; + } + } + } + } + } + + return false; + } + private final String makeDisplayString(Cursor cursor) { if (cursor.getColumnName(0).equals(SEARCHING_CURSOR_MARKER)) { return ""; |