diff --git a/src/com/fsck/k9/helper/Contacts.java b/src/com/fsck/k9/helper/Contacts.java
index 6e8f9fbb4..56866c21c 100644
--- a/src/com/fsck/k9/helper/Contacts.java
+++ b/src/com/fsck/k9/helper/Contacts.java
@@ -1,55 +1,76 @@
package com.fsck.k9.helper;
import android.content.ContentResolver;
+import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
-import android.os.Build;
import android.content.Intent;
+import android.provider.ContactsContract;
+import android.util.Log;
+
+import com.fsck.k9.K9;
import com.fsck.k9.mail.Address;
+import java.util.ArrayList;
+
/**
- * Helper class to access the contacts stored on the device. This is needed
- * because the original contacts API introduced with SDK 1 was deprecated with
- * SDK 5 and will eventually be removed in newer SDK versions.
- * A class that uses the latest contacts API available on the device will be
- * loaded at runtime.
- *
- * @see ContactsSdk5
- * @see ContactsSdk5p
+ * Helper class to access the contacts stored on the device.
*/
-public abstract class Contacts {
+public class Contacts {
/**
- * Instance of the SDK specific class that interfaces with the contacts
- * API.
+ * The order in which the search results are returned by
+ * {@link #searchContacts(CharSequence)}.
*/
- private static Contacts sInstance = null;
+ protected static final String SORT_ORDER =
+ ContactsContract.CommonDataKinds.Email.TIMES_CONTACTED + " DESC, " +
+ ContactsContract.Contacts.DISPLAY_NAME + ", " +
+ ContactsContract.CommonDataKinds.Email._ID;
/**
- * Get SDK specific instance of the Contacts class.
+ * Array of columns to load from the database.
+ *
+ * Important: The _ID field is needed by
+ * {@link com.fsck.k9.EmailAddressAdapter} or more specificly by
+ * {@link android.widget.ResourceCursorAdapter}.
+ */
+ protected static final String PROJECTION[] = {
+ ContactsContract.CommonDataKinds.Email._ID,
+ ContactsContract.Contacts.DISPLAY_NAME,
+ ContactsContract.CommonDataKinds.Email.DATA,
+ ContactsContract.CommonDataKinds.Email.CONTACT_ID
+ };
+
+ /**
+ * Index of the name field in the projection. This must match the order in
+ * {@link #PROJECTION}.
+ */
+ protected static final int NAME_INDEX = 1;
+
+ /**
+ * Index of the email address field in the projection. This must match the
+ * order in {@link #PROJECTION}.
+ */
+ protected static final int EMAIL_INDEX = 2;
+
+ /**
+ * Index of the contact id field in the projection. This must match the order in
+ * {@link #PROJECTION}.
+ */
+ protected static final int CONTACT_ID_INDEX = 3;
+
+
+ /**
+ * Get instance of the Contacts class.
+ *
+ *
Note: This is left over from the days when we needed to have SDK-specific code to access
+ * the contacts.
*
* @param context A {@link Context} instance.
* @return Appropriate {@link Contacts} instance for this device.
*/
public static Contacts getInstance(Context context) {
- Context appContext = context.getApplicationContext();
- if (sInstance == null) {
- /*
- * Check the version of the SDK we are running on. Choose an
- * implementation class designed for that version of the SDK.
- */
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ECLAIR_MR1) {
- /*
- * The new API was introduced with SDK 5. But Android versions < 2.2
- * need some additional code to be able to search for phonetic names.
- */
- sInstance = new ContactsSdk5p(appContext);
- } else {
- sInstance = new ContactsSdk5(appContext);
- }
- }
-
- return sInstance;
+ return new Contacts(context);
}
@@ -76,7 +97,25 @@ public abstract class Contacts {
* the instance also contains the (display) name of that
* entity.
*/
- public abstract void createContact(Address email);
+ public void createContact(final Address email) {
+ final Uri contactUri = Uri.fromParts("mailto", email.getAddress(), null);
+
+ final Intent contactIntent = new Intent(ContactsContract.Intents.SHOW_OR_CREATE_CONTACT);
+ contactIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ contactIntent.setData(contactUri);
+
+ // Pass along full E-mail string for possible create dialog
+ contactIntent.putExtra(ContactsContract.Intents.EXTRA_CREATE_DESCRIPTION,
+ email.toString());
+
+ // Only provide personal name hint if we have one
+ final String senderPersonal = email.getPersonal();
+ if (senderPersonal != null) {
+ contactIntent.putExtra(ContactsContract.Intents.Insert.NAME, senderPersonal);
+ }
+
+ mContext.startActivity(contactIntent);
+ }
/**
* Start the activity to add a phone number to an existing contact or add a new one.
@@ -84,7 +123,13 @@ public abstract class Contacts {
* @param phoneNumber
* The phone number to add to a contact, or to use when creating a new contact.
*/
- public abstract void addPhoneContact(String phoneNumber);
+ public void addPhoneContact(final String phoneNumber) {
+ Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
+ addIntent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
+ addIntent.putExtra(ContactsContract.Intents.Insert.PHONE, Uri.decode(phoneNumber));
+ addIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(addIntent);
+ }
/**
* Check whether the provided email address belongs to one of the contacts.
@@ -93,16 +138,52 @@ public abstract class Contacts {
* @return true, if the email address belongs to a contact.
* false, otherwise.
*/
- public abstract boolean isInContacts(String emailAddress);
+ public boolean isInContacts(final String emailAddress) {
+ boolean result = false;
+
+ final Cursor c = getContactByAddress(emailAddress);
+
+ if (c != null) {
+ if (c.getCount() > 0) {
+ result = true;
+ }
+ c.close();
+ }
+
+ return result;
+ }
/**
* Filter the contacts matching the given search term.
*
- * @param filter The search term to filter the contacts.
+ * @param constraint The search term to filter the contacts.
* @return A {@link Cursor} instance that can be used to get the
* matching contacts.
*/
- public abstract Cursor searchContacts(CharSequence filter);
+ public Cursor searchContacts(final CharSequence constraint) {
+ final String filter = (constraint == null) ? "" : constraint.toString();
+ final Uri uri = Uri.withAppendedPath(ContactsContract.CommonDataKinds.Email.CONTENT_FILTER_URI, Uri.encode(filter));
+ final Cursor c = mContentResolver.query(
+ uri,
+ PROJECTION,
+ null,
+ null,
+ SORT_ORDER);
+
+ if (c != null) {
+ /*
+ * To prevent expensive execution in the UI thread:
+ * Cursors get lazily executed, so if you don't call anything on
+ * the cursor before returning it from the background thread you'll
+ * have a complied program for the cursor, but it won't have been
+ * executed to generate the data yet. Often the execution is more
+ * expensive than the compilation...
+ */
+ c.getCount();
+ }
+
+ return c;
+ }
/**
* Get the name of the contact an email address belongs to.
@@ -111,7 +192,24 @@ public abstract class Contacts {
* @return The name of the contact the email address belongs to. Or
* null if there's no matching contact.
*/
- public abstract String getNameForAddress(String address);
+ public String getNameForAddress(String address) {
+ if (address == null) {
+ return null;
+ }
+
+ final Cursor c = getContactByAddress(address);
+
+ String name = null;
+ if (c != null) {
+ if (c.getCount() > 0) {
+ c.moveToFirst();
+ name = getName(c);
+ }
+ c.close();
+ }
+
+ return name;
+ }
/**
* Extract the name from a {@link Cursor} instance returned by
@@ -120,7 +218,9 @@ public abstract class Contacts {
* @param cursor The {@link Cursor} instance.
* @return The name of the contact in the {@link Cursor}'s current row.
*/
- public abstract String getName(Cursor cursor);
+ public String getName(Cursor cursor) {
+ return cursor.getString(NAME_INDEX);
+ }
/**
* Extract the email address from a {@link Cursor} instance returned by
@@ -130,7 +230,9 @@ public abstract class Contacts {
* @return The email address of the contact in the {@link Cursor}'s current
* row.
*/
- public abstract String getEmail(Cursor cursor);
+ public String getEmail(Cursor cursor) {
+ return cursor.getString(EMAIL_INDEX);
+ }
/**
* Mark contacts with the provided email addresses as contacted.
@@ -138,14 +240,30 @@ public abstract class Contacts {
* @param addresses Array of {@link Address} objects describing the
* contacts to be marked as contacted.
*/
- public abstract void markAsContacted(final Address[] addresses);
+ public void markAsContacted(final Address[] addresses) {
+ //TODO: Optimize! Potentially a lot of database queries
+ for (final Address address : addresses) {
+ final Cursor c = getContactByAddress(address.getAddress());
+
+ if (c != null) {
+ if (c.getCount() > 0) {
+ c.moveToFirst();
+ final long personId = c.getLong(CONTACT_ID_INDEX);
+ ContactsContract.Contacts.markAsContacted(mContentResolver, personId);
+ }
+ c.close();
+ }
+ }
+ }
/**
* Creates the intent necessary to open a contact picker.
*
* @return The intent necessary to open a contact picker.
*/
- public abstract Intent contactPickerIntent();
+ public Intent contactPickerIntent() {
+ return new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
+ }
/**
* Given a contact picker intent, returns a {@code ContactItem} instance for that contact.
@@ -156,7 +274,52 @@ public abstract class Contacts {
* @return A {@link ContactItem} instance describing the picked contact. Or {@code null} if the
* contact doesn't have any email addresses.
*/
- public abstract ContactItem extractInfoFromContactPickerIntent(final Intent intent);
+ public ContactItem extractInfoFromContactPickerIntent(final Intent intent) {
+ Cursor cursor = null;
+ ArrayList email = new ArrayList();
+
+ try {
+ Uri result = intent.getData();
+ String displayName = null;
+
+ // Get the contact id from the Uri
+ String id = result.getLastPathSegment();
+
+ cursor = mContentResolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, PROJECTION,
+ ContactsContract.CommonDataKinds.Email.CONTACT_ID + "=?", new String[] { id }, null);
+
+ if (cursor != null) {
+ while (cursor.moveToNext()) {
+ String address = cursor.getString(EMAIL_INDEX);
+ if (address != null) {
+ email.add(address);
+ }
+
+ if (displayName == null) {
+ displayName = cursor.getString(NAME_INDEX);
+ }
+ }
+
+ // Return 'null' if no email addresses have been found
+ if (email.size() == 0) {
+ return null;
+ }
+
+ // Use the first email address found as display name
+ if (displayName == null) {
+ displayName = email.get(0);
+ }
+
+ return new ContactItem(displayName, email);
+ }
+ } catch (Exception e) {
+ Log.e(K9.LOG_TAG, "Failed to get email data", e);
+ } finally {
+ Utility.closeQuietly(cursor);
+ }
+
+ return null;
+ }
/**
* Get URI to the picture of the contact with the supplied email address.
@@ -168,7 +331,47 @@ public abstract class Contacts {
* @return URI to the picture of the contact with the supplied email address. {@code null} if
* no such contact could be found or the contact doesn't have a picture.
*/
- public abstract Uri getPhotoUri(String address);
+ public Uri getPhotoUri(String address) {
+ Long contactId;
+ try {
+ final Cursor c = getContactByAddress(address);
+ if (c == null) {
+ return null;
+ }
+
+ try {
+ if (!c.moveToFirst()) {
+ return null;
+ }
+
+ contactId = c.getLong(CONTACT_ID_INDEX);
+ } finally {
+ c.close();
+ }
+
+ Cursor cur = mContentResolver.query(
+ ContactsContract.Data.CONTENT_URI,
+ null,
+ ContactsContract.Data.CONTACT_ID + "=" + contactId + " AND "
+ + ContactsContract.Data.MIMETYPE + "='"
+ + ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'", null,
+ null);
+ if (cur == null) {
+ return null;
+ }
+ if (!cur.moveToFirst()) {
+ cur.close();
+ return null; // no photo
+ }
+ // Ok, they have a photo
+ cur.close();
+ Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
+ return Uri.withAppendedPath(person, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
+ } catch (Exception e) {
+ Log.e(K9.LOG_TAG, "Couldn't fetch photo for contact with email " + address, e);
+ return null;
+ }
+ }
/**
* Does the device actually have a Contacts application suitable for
@@ -184,4 +387,24 @@ public abstract class Contacts {
}
return mHasContactPicker;
}
+
+ /**
+ * Return a {@link Cursor} instance that can be used to fetch information
+ * about the contact with the given email address.
+ *
+ * @param address The email address to search for.
+ * @return A {@link Cursor} instance that can be used to fetch information
+ * about the contact with the given email address
+ */
+ private Cursor getContactByAddress(final String address) {
+ final Uri uri = Uri.withAppendedPath(ContactsContract.CommonDataKinds.Email.CONTENT_LOOKUP_URI, Uri.encode(address));
+ final Cursor c = mContentResolver.query(
+ uri,
+ PROJECTION,
+ null,
+ null,
+ SORT_ORDER);
+ return c;
+ }
+
}
diff --git a/src/com/fsck/k9/helper/ContactsSdk5.java b/src/com/fsck/k9/helper/ContactsSdk5.java
deleted file mode 100644
index e9efef10e..000000000
--- a/src/com/fsck/k9/helper/ContactsSdk5.java
+++ /dev/null
@@ -1,305 +0,0 @@
-package com.fsck.k9.helper;
-
-import java.util.ArrayList;
-
-import android.content.ContentUris;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.util.Log;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Intents;
-import android.provider.ContactsContract.CommonDataKinds.Email;
-import android.provider.ContactsContract.Intents.Insert;
-
-import com.fsck.k9.mail.Address;
-import com.fsck.k9.K9;
-
-/**
- * Access the contacts on the device using the API introduced with SDK 5.
- *
- * @see android.provider.ContactsContract
- */
-public class ContactsSdk5 extends com.fsck.k9.helper.Contacts {
- /**
- * The order in which the search results are returned by
- * {@link #searchContacts(CharSequence)}.
- */
- protected static final String SORT_ORDER =
- Email.TIMES_CONTACTED + " DESC, " +
- Contacts.DISPLAY_NAME + ", " +
- Email._ID;
-
- /**
- * Array of columns to load from the database.
- *
- * Important: The _ID field is needed by
- * {@link com.fsck.k9.EmailAddressAdapter} or more specificly by
- * {@link android.widget.ResourceCursorAdapter}.
- */
- protected static final String PROJECTION[] = {
- Email._ID,
- Contacts.DISPLAY_NAME,
- Email.DATA,
- Email.CONTACT_ID
- };
-
- /**
- * Index of the name field in the projection. This must match the order in
- * {@link #PROJECTION}.
- */
- protected static final int NAME_INDEX = 1;
-
- /**
- * Index of the email address field in the projection. This must match the
- * order in {@link #PROJECTION}.
- */
- protected static final int EMAIL_INDEX = 2;
-
- /**
- * Index of the contact id field in the projection. This must match the order in
- * {@link #PROJECTION}.
- */
- protected static final int CONTACT_ID_INDEX = 3;
-
-
- public ContactsSdk5(final Context context) {
- super(context);
- }
-
- @Override
- public void createContact(final Address email) {
- final Uri contactUri = Uri.fromParts("mailto", email.getAddress(), null);
-
- final Intent contactIntent = new Intent(Intents.SHOW_OR_CREATE_CONTACT);
- contactIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- contactIntent.setData(contactUri);
-
- // Pass along full E-mail string for possible create dialog
- contactIntent.putExtra(Intents.EXTRA_CREATE_DESCRIPTION,
- email.toString());
-
- // Only provide personal name hint if we have one
- final String senderPersonal = email.getPersonal();
- if (senderPersonal != null) {
- contactIntent.putExtra(Intents.Insert.NAME, senderPersonal);
- }
-
- mContext.startActivity(contactIntent);
- }
-
- @Override
- public void addPhoneContact(final String phoneNumber) {
- Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
- addIntent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
- addIntent.putExtra(Insert.PHONE, Uri.decode(phoneNumber));
- addIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivity(addIntent);
- }
-
- @Override
- public boolean isInContacts(final String emailAddress) {
- boolean result = false;
-
- final Cursor c = getContactByAddress(emailAddress);
-
- if (c != null) {
- if (c.getCount() > 0) {
- result = true;
- }
- c.close();
- }
-
- return result;
- }
-
- @Override
- public Cursor searchContacts(final CharSequence constraint) {
- final String filter = (constraint == null) ? "" : constraint.toString();
- final Uri uri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, Uri.encode(filter));
- final Cursor c = mContentResolver.query(
- uri,
- PROJECTION,
- null,
- null,
- SORT_ORDER);
-
- if (c != null) {
- /*
- * To prevent expensive execution in the UI thread:
- * Cursors get lazily executed, so if you don't call anything on
- * the cursor before returning it from the background thread you'll
- * have a complied program for the cursor, but it won't have been
- * executed to generate the data yet. Often the execution is more
- * expensive than the compilation...
- */
- c.getCount();
- }
-
- return c;
- }
-
- @Override
- public String getNameForAddress(String address) {
- if (address == null) {
- return null;
- }
-
- final Cursor c = getContactByAddress(address);
-
- String name = null;
- if (c != null) {
- if (c.getCount() > 0) {
- c.moveToFirst();
- name = getName(c);
- }
- c.close();
- }
-
- return name;
- }
-
- @Override
- public String getName(Cursor c) {
- return c.getString(NAME_INDEX);
- }
-
- @Override
- public String getEmail(Cursor c) {
- return c.getString(EMAIL_INDEX);
- }
-
- @Override
- public void markAsContacted(final Address[] addresses) {
- //TODO: Optimize! Potentially a lot of database queries
- for (final Address address : addresses) {
- final Cursor c = getContactByAddress(address.getAddress());
-
- if (c != null) {
- if (c.getCount() > 0) {
- c.moveToFirst();
- final long personId = c.getLong(CONTACT_ID_INDEX);
- ContactsContract.Contacts.markAsContacted(mContentResolver, personId);
- }
- c.close();
- }
- }
- }
-
- @Override
- public Intent contactPickerIntent() {
- return new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
- }
-
- @Override
- public ContactItem extractInfoFromContactPickerIntent(final Intent data) {
- Cursor cursor = null;
- ArrayList email = new ArrayList();
-
- try {
- Uri result = data.getData();
- String displayName = null;
-
- // Get the contact id from the Uri
- String id = result.getLastPathSegment();
-
- cursor = mContentResolver.query(Email.CONTENT_URI, PROJECTION,
- Email.CONTACT_ID + "=?", new String[] { id }, null);
-
- if (cursor != null) {
- while (cursor.moveToNext()) {
- String address = cursor.getString(EMAIL_INDEX);
- if (address != null) {
- email.add(address);
- }
-
- if (displayName == null) {
- displayName = cursor.getString(NAME_INDEX);
- }
- }
-
- // Return 'null' if no email addresses have been found
- if (email.size() == 0) {
- return null;
- }
-
- // Use the first email address found as display name
- if (displayName == null) {
- displayName = email.get(0);
- }
-
- return new ContactItem(displayName, email);
- }
- } catch (Exception e) {
- Log.e(K9.LOG_TAG, "Failed to get email data", e);
- } finally {
- Utility.closeQuietly(cursor);
- }
-
- return null;
- }
-
- /**
- * Return a {@link Cursor} instance that can be used to fetch information
- * about the contact with the given email address.
- *
- * @param address The email address to search for.
- * @return A {@link Cursor} instance that can be used to fetch information
- * about the contact with the given email address
- */
- private Cursor getContactByAddress(final String address) {
- final Uri uri = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(address));
- final Cursor c = mContentResolver.query(
- uri,
- PROJECTION,
- null,
- null,
- SORT_ORDER);
- return c;
- }
-
- @Override
- public Uri getPhotoUri(String address) {
- Long contactId;
- try {
- final Cursor c = getContactByAddress(address);
- if (c == null) {
- return null;
- }
-
- try {
- if (!c.moveToFirst()) {
- return null;
- }
-
- contactId = c.getLong(CONTACT_ID_INDEX);
- } finally {
- c.close();
- }
-
- Cursor cur = mContentResolver.query(
- ContactsContract.Data.CONTENT_URI,
- null,
- ContactsContract.Data.CONTACT_ID + "=" + contactId + " AND "
- + ContactsContract.Data.MIMETYPE + "='"
- + ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'", null,
- null);
- if (cur == null) {
- return null;
- }
- if (!cur.moveToFirst()) {
- cur.close();
- return null; // no photo
- }
- // Ok, they have a photo
- cur.close();
- Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
- return Uri.withAppendedPath(person, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
- } catch (Exception e) {
- Log.e(K9.LOG_TAG, "Couldn't fetch photo for contact with email " + address, e);
- return null;
- }
- }
-}
diff --git a/src/com/fsck/k9/helper/ContactsSdk5p.java b/src/com/fsck/k9/helper/ContactsSdk5p.java
deleted file mode 100644
index bb5db650a..000000000
--- a/src/com/fsck/k9/helper/ContactsSdk5p.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package com.fsck.k9.helper;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.CommonDataKinds.Email;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-
-/**
- * Access the contacts on the device using the API introduced with SDK 5.
- * Use some additional code to make search work with phonetic names.
- *
- * Android versions >= 2.2 (Froyo) support searching for phonetic names
- * out of the box (see {@link ContactsSdk5}).
- *
- * @see android.provider.ContactsContract
- */
-public class ContactsSdk5p extends ContactsSdk5 {
- public ContactsSdk5p(final Context context) {
- super(context);
- }
-
- @Override
- public Cursor searchContacts(final CharSequence constraint) {
- if (constraint == null) {
- return null;
- }
-
- // Lookup using Email.CONTENT_FILTER_URI to get matching contact ids.
- // This does all sorts of magic we don't want to replicate.
- final String filter = constraint.toString();
- final Uri uri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, Uri.encode(filter));
- final Cursor cursor = mContentResolver.query(
- uri,
- new String[] {Email.CONTACT_ID},
- null,
- null,
- null);
-
- final StringBuilder matches = new StringBuilder();
- if ((cursor != null) && (cursor.getCount() > 0)) {
- boolean first = true;
- while (cursor.moveToNext()) {
- if (first) {
- first = false;
- } else {
- matches.append(",");
- }
- matches.append(cursor.getLong(0));
- }
- cursor.close();
- }
-
- // Find contacts with email addresses that have been found using
- // Email.CONTENT_FILTER_URI above or ones that have a matching phonetic name.
- final String where = Data.MIMETYPE + " = '" + Email.CONTENT_ITEM_TYPE + "'" +
- " AND " +
- "(" +
- // Match if found by Email.CONTENT_FILTER_URI
- Email.CONTACT_ID + " IN (" + matches.toString() + ")" +
- " OR " +
- // Match if phonetic given name starts with "constraint"
- StructuredName.PHONETIC_GIVEN_NAME + " LIKE ?" +
- " OR " +
- // Match if phonetic given name contains a word that starts with "constraint"
- StructuredName.PHONETIC_GIVEN_NAME + " LIKE ?" +
- " OR " +
- // Match if phonetic middle name starts with "constraint"
- StructuredName.PHONETIC_MIDDLE_NAME + " LIKE ?" +
- " OR " +
- // Match if phonetic middle name contains a word that starts with "constraint"
- StructuredName.PHONETIC_MIDDLE_NAME + " LIKE ?" +
- " OR " +
- // Match if phonetic family name starts with "constraint"
- StructuredName.PHONETIC_FAMILY_NAME + " LIKE ?" +
- " OR " +
- // Match if phonetic family name contains a word that starts with "constraint"
- StructuredName.PHONETIC_FAMILY_NAME + " LIKE ?" +
- ")";
- final String filter1 = constraint.toString() + "%";
- final String filter2 = "% " + filter1;
- final String[] args = new String[] {filter1, filter2, filter1, filter2, filter1, filter2};
- final Cursor c = mContentResolver.query(
- Email.CONTENT_URI,
- PROJECTION,
- where,
- args,
- SORT_ORDER);
-
- if (c != null) {
- /*
- * To prevent expensive execution in the UI thread:
- * Cursors get lazily executed, so if you don't call anything on
- * the cursor before returning it from the background thread you'll
- * have a complied program for the cursor, but it won't have been
- * executed to generate the data yet. Often the execution is more
- * expensive than the compilation...
- */
- c.getCount();
- }
-
- return c;
- }
-}