Loading k9mail/src/main/java/com/fsck/k9/activity/compose/RecipientLoader.java +93 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -44,6 +45,7 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> { 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; Loading @@ -51,6 +53,14 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> { 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" Loading Loading @@ -173,35 +183,110 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> { } 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<Recipient> recipients, Map<String, Recipient> 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<Recipient> recipients, Map<String, Recipient> 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<Recipient> recipients, Map<String, Recipient> 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<Recipient> recipients, Map<String, Recipient> recipientMap) { fillContactDataFromCursor(cursor, recipients, recipientMap, null); } private void fillContactDataFromCursor(Cursor cursor, List<Recipient> recipients, Map<String, Recipient> 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); Loading Loading
k9mail/src/main/java/com/fsck/k9/activity/compose/RecipientLoader.java +93 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -44,6 +45,7 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> { 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; Loading @@ -51,6 +53,14 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> { 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" Loading Loading @@ -173,35 +183,110 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> { } 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<Recipient> recipients, Map<String, Recipient> 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<Recipient> recipients, Map<String, Recipient> 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<Recipient> recipients, Map<String, Recipient> 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<Recipient> recipients, Map<String, Recipient> recipientMap) { fillContactDataFromCursor(cursor, recipients, recipientMap, null); } private void fillContactDataFromCursor(Cursor cursor, List<Recipient> recipients, Map<String, Recipient> 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); Loading