Merge pull request #2264 from daquexian/issue_2240

search nicknames (issue 2240)
This commit is contained in:
Vincent Breitmoser 2017-03-27 07:32:57 +02:00 committed by GitHub
commit 437764ad5c

View file

@ -15,6 +15,7 @@ import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Email; import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Contacts.Data; import android.provider.ContactsContract.Contacts.Data;
import android.support.annotation.Nullable;
import com.fsck.k9.R; import com.fsck.k9.R;
import com.fsck.k9.mail.Address; import com.fsck.k9.mail.Address;
@ -44,6 +45,7 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> {
ContactsContract.CommonDataKinds.Email.CONTACT_ID, ContactsContract.CommonDataKinds.Email.CONTACT_ID,
ContactsContract.Contacts.PHOTO_THUMBNAIL_URI ContactsContract.Contacts.PHOTO_THUMBNAIL_URI
}; };
private static final String SORT_ORDER = "" + private static final String SORT_ORDER = "" +
ContactsContract.CommonDataKinds.Email.TIMES_CONTACTED + " DESC, " + ContactsContract.CommonDataKinds.Email.TIMES_CONTACTED + " DESC, " +
ContactsContract.Contacts.SORT_KEY_PRIMARY; ContactsContract.Contacts.SORT_KEY_PRIMARY;
@ -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_ADDRESS = 0;
private static final int INDEX_EMAIL_STATUS = 1; 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 = { private static final String[] PROJECTION_CRYPTO_STATUS = {
"email_address", "email_address",
"email_status" "email_status"
@ -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, private void fillContactDataFromQuery(String query, List<Recipient> recipients,
Map<String, Recipient> recipientMap) { 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 + "%"; query = "%" + query + "%";
Uri queryUri = ContactsContract.CommonDataKinds.Email.CONTENT_URI;
Uri queryUri = Email.CONTENT_URI;
String selection = Contacts.DISPLAY_NAME_PRIMARY + " LIKE ? " + String selection = Contacts.DISPLAY_NAME_PRIMARY + " LIKE ? " +
" OR (" + Email.ADDRESS + " LIKE ? AND " + Data.MIMETYPE + " = '" + Email.CONTENT_ITEM_TYPE + "')"; " OR (" + Email.ADDRESS + " LIKE ? AND " + Data.MIMETYPE + " = '" + Email.CONTENT_ITEM_TYPE + "')";
String[] selectionArgs = { query, query }; String[] selectionArgs = { query, query };
Cursor cursor = contentResolver.query(queryUri, PROJECTION, selection, selectionArgs, SORT_ORDER); Cursor cursor = contentResolver.query(queryUri, PROJECTION, selection, selectionArgs, SORT_ORDER);
if (cursor == null) { if (cursor == null) {
return; return false;
} }
fillContactDataFromCursor(cursor, recipients, recipientMap); fillContactDataFromCursor(cursor, recipients, recipientMap);
if (observerContact != null) { return true;
observerContact = new ForceLoadContentObserver();
contentResolver.registerContentObserver(queryUri, false, observerContact);
}
} }
private void fillContactDataFromCursor(Cursor cursor, List<Recipient> recipients, private void fillContactDataFromCursor(Cursor cursor, List<Recipient> recipients,
Map<String, Recipient> recipientMap) { 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()) { while (cursor.moveToNext()) {
String name = cursor.getString(INDEX_NAME); if (name == null) {
name = cursor.getString(INDEX_NAME);
}
String email = cursor.getString(INDEX_EMAIL); String email = cursor.getString(INDEX_EMAIL);
long contactId = cursor.getLong(INDEX_CONTACT_ID); long contactId = cursor.getLong(INDEX_CONTACT_ID);
String lookupKey = cursor.getString(INDEX_LOOKUP_KEY); String lookupKey = cursor.getString(INDEX_LOOKUP_KEY);