diff --git a/k9mail/src/main/java/com/fsck/k9/activity/compose/RecipientLoader.java b/k9mail/src/main/java/com/fsck/k9/activity/compose/RecipientLoader.java index 03c60eecb..5c01427a7 100644 --- a/k9mail/src/main/java/com/fsck/k9/activity/compose/RecipientLoader.java +++ b/k9mail/src/main/java/com/fsck/k9/activity/compose/RecipientLoader.java @@ -15,6 +15,7 @@ import android.provider.ContactsContract; import android.provider.ContactsContract.CommonDataKinds.Email; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Contacts.Data; +import android.support.annotation.Nullable; import com.fsck.k9.R; import com.fsck.k9.mail.Address; @@ -44,6 +45,7 @@ public class RecipientLoader extends AsyncTaskLoader> { ContactsContract.CommonDataKinds.Email.CONTACT_ID, ContactsContract.Contacts.PHOTO_THUMBNAIL_URI }; + private static final String SORT_ORDER = "" + ContactsContract.CommonDataKinds.Email.TIMES_CONTACTED + " DESC, " + ContactsContract.Contacts.SORT_KEY_PRIMARY; @@ -51,6 +53,14 @@ public class RecipientLoader extends AsyncTaskLoader> { private static final int INDEX_EMAIL_ADDRESS = 0; private static final int INDEX_EMAIL_STATUS = 1; + private static final String[] PROJECTION_NICKNAME = { + ContactsContract.Data.CONTACT_ID, + ContactsContract.CommonDataKinds.Nickname.NAME + }; + + private static final int INDEX_CONTACT_ID_FOR_NICKNAME = 0; + private static final int INDEX_NICKNAME = 1; + private static final String[] PROJECTION_CRYPTO_STATUS = { "email_address", "email_status" @@ -173,35 +183,110 @@ public class RecipientLoader extends AsyncTaskLoader> { } + private Cursor getNicknameCursor(String nickname) { + nickname = "%" + nickname + "%"; + + Uri queryUriForNickname = ContactsContract.Data.CONTENT_URI; + + return getContext().getContentResolver().query(queryUriForNickname, + PROJECTION_NICKNAME, + ContactsContract.CommonDataKinds.Nickname.NAME + " LIKE ? AND " + + Data.MIMETYPE + " = ?", + new String[] { nickname, ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE }, + null); + } + + @SuppressWarnings("ConstantConditions") private void fillContactDataFromQuery(String query, List recipients, Map recipientMap) { - ContentResolver contentResolver = getContext().getContentResolver(); + boolean foundValidCursor = false; + foundValidCursor |= fillContactDataFromNickname(query, recipients, recipientMap); + foundValidCursor |= fillContactDataFromNameAndEmail(query, recipients, recipientMap); + if (foundValidCursor) { + registerContentObserver(); + } + + } + + private void registerContentObserver() { + if (observerContact != null) { + observerContact = new ForceLoadContentObserver(); + getContext().getContentResolver().registerContentObserver(Email.CONTENT_URI, false, observerContact); + } + } + + @SuppressWarnings("ConstantConditions") + private boolean fillContactDataFromNickname(String nickname, List recipients, + Map recipientMap) { + + boolean hasContact = false; + + final ContentResolver contentResolver = getContext().getContentResolver(); + + Uri queryUri = Email.CONTENT_URI; + + Cursor nicknameCursor = getNicknameCursor(nickname); + + if (nicknameCursor == null) { + return hasContact; + } + + try { + while (nicknameCursor.moveToNext()) { + String id = nicknameCursor.getString(INDEX_CONTACT_ID_FOR_NICKNAME); + String selection = ContactsContract.Data.CONTACT_ID + " = ?"; + Cursor cursor = contentResolver + .query(queryUri, PROJECTION, selection, new String[] { id }, SORT_ORDER); + + fillContactDataFromCursor(cursor, recipients, recipientMap, nicknameCursor.getString(INDEX_NICKNAME)); + + hasContact = true; + } + } finally { + nicknameCursor.close(); + } + + return hasContact; + } + + + private boolean fillContactDataFromNameAndEmail(String query, List recipients, + Map recipientMap) { + + ContentResolver contentResolver = getContext().getContentResolver(); query = "%" + query + "%"; - Uri queryUri = ContactsContract.CommonDataKinds.Email.CONTENT_URI; + + Uri queryUri = Email.CONTENT_URI; + String selection = Contacts.DISPLAY_NAME_PRIMARY + " LIKE ? " + " OR (" + Email.ADDRESS + " LIKE ? AND " + Data.MIMETYPE + " = '" + Email.CONTENT_ITEM_TYPE + "')"; String[] selectionArgs = { query, query }; Cursor cursor = contentResolver.query(queryUri, PROJECTION, selection, selectionArgs, SORT_ORDER); if (cursor == null) { - return; + return false; } fillContactDataFromCursor(cursor, recipients, recipientMap); - if (observerContact != null) { - observerContact = new ForceLoadContentObserver(); - contentResolver.registerContentObserver(queryUri, false, observerContact); - } + return true; + } private void fillContactDataFromCursor(Cursor cursor, List recipients, Map recipientMap) { + fillContactDataFromCursor(cursor, recipients, recipientMap, null); + } + + private void fillContactDataFromCursor(Cursor cursor, List recipients, + Map recipientMap, @Nullable String name) { while (cursor.moveToNext()) { - String name = cursor.getString(INDEX_NAME); + if (name == null) { + name = cursor.getString(INDEX_NAME); + } String email = cursor.getString(INDEX_EMAIL); long contactId = cursor.getLong(INDEX_CONTACT_ID); String lookupKey = cursor.getString(INDEX_LOOKUP_KEY);