diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 61a160aff..b61d17cab 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -17,7 +17,14 @@ + + + + + + + diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java index 711288efd..bd0394f95 100644 --- a/src/com/fsck/k9/activity/MessageCompose.java +++ b/src/com/fsck/k9/activity/MessageCompose.java @@ -57,6 +57,7 @@ import com.fsck.k9.controller.MessagingController; import com.fsck.k9.controller.MessagingListener; import com.fsck.k9.crypto.CryptoProvider; import com.fsck.k9.crypto.PgpData; +import com.fsck.k9.helper.Contacts; import com.fsck.k9.helper.Utility; import com.fsck.k9.mail.Address; import com.fsck.k9.mail.Body; @@ -2252,6 +2253,18 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc throw new RuntimeException("Failed to create a new message for send or save.", me); } + try + { + final Contacts contacts = Contacts.getInstance(MessageCompose.this); + contacts.markAsContacted(message.getRecipients(RecipientType.TO)); + contacts.markAsContacted(message.getRecipients(RecipientType.CC)); + contacts.markAsContacted(message.getRecipients(RecipientType.BCC)); + } + catch (Exception e) + { + Log.e(K9.LOG_TAG, "Failed to mark contact as contacted.", e); + } + MessagingController.getInstance(getApplication()).sendMessage(mAccount, message, null); if (mDraftUid != null) { diff --git a/src/com/fsck/k9/helper/Contacts.java b/src/com/fsck/k9/helper/Contacts.java index e95caf130..efacb02f8 100644 --- a/src/com/fsck/k9/helper/Contacts.java +++ b/src/com/fsck/k9/helper/Contacts.java @@ -174,4 +174,12 @@ public abstract class Contacts * row. */ public abstract String getEmail(Cursor cursor); + + /** + * Mark contacts with the provided email addresses as contacted. + * + * @param addresses Array of {@link Address} objects describing the + * contacts to be marked as contacted. + */ + public abstract void markAsContacted(final Address[] addresses); } diff --git a/src/com/fsck/k9/helper/ContactsSdk3_4.java b/src/com/fsck/k9/helper/ContactsSdk3_4.java index 0d15d8baa..d01f8e8b6 100644 --- a/src/com/fsck/k9/helper/ContactsSdk3_4.java +++ b/src/com/fsck/k9/helper/ContactsSdk3_4.java @@ -21,8 +21,9 @@ public class ContactsSdk3_4 extends com.fsck.k9.helper.Contacts * {@link #searchContacts(CharSequence)}. */ private static final String SORT_ORDER = - Contacts.People.TIMES_CONTACTED + " DESC, " + - Contacts.People.NAME; + Contacts.ContactMethods.TIMES_CONTACTED + " DESC, " + + Contacts.ContactMethods.DISPLAY_NAME + ", " + + Contacts.ContactMethods._ID; /** * Array of columns to load from the database. @@ -33,9 +34,10 @@ public class ContactsSdk3_4 extends com.fsck.k9.helper.Contacts */ private static final String PROJECTION[] = { - Contacts.People.ContactMethods._ID, - Contacts.People.ContactMethods.NAME, - Contacts.People.ContactMethods.DATA + Contacts.ContactMethods._ID, + Contacts.ContactMethods.DISPLAY_NAME, + Contacts.ContactMethods.DATA, + Contacts.ContactMethods.PERSON_ID }; /** @@ -50,6 +52,12 @@ public class ContactsSdk3_4 extends com.fsck.k9.helper.Contacts */ private static final int EMAIL_INDEX = 2; + /** + * Index of the contact id field in the projection. This must match the order in + * {@link #PROJECTION}. + */ + private static final int CONTACT_ID_INDEX = 3; + public ContactsSdk3_4(final Context context) { @@ -94,7 +102,7 @@ public class ContactsSdk3_4 extends com.fsck.k9.helper.Contacts if (c.getCount() > 0) { c.moveToFirst(); - name = c.getString(NAME_INDEX); + name = getName(c); } c.close(); } @@ -107,15 +115,7 @@ public class ContactsSdk3_4 extends com.fsck.k9.helper.Contacts { boolean result = false; - final String where = Contacts.ContactMethods.DATA + "=?"; - final String[] args = new String[] {emailAddress}; - - final Cursor c = mContentResolver.query( - Contacts.ContactMethods.CONTENT_EMAIL_URI, - PROJECTION, - where, - args, - null); + final Cursor c = getContactByAddress(emailAddress); if (c != null) { @@ -141,7 +141,8 @@ public class ContactsSdk3_4 extends com.fsck.k9.helper.Contacts } else { - where = "(" + + where = Contacts.ContactMethods.KIND + " = " + Contacts.KIND_EMAIL + + " AND" + "(" + Contacts.People.NAME + " LIKE ?" + ") OR (" + Contacts.ContactMethods.DATA + " LIKE ?" + @@ -151,7 +152,7 @@ public class ContactsSdk3_4 extends com.fsck.k9.helper.Contacts } final Cursor c = mContentResolver.query( - Contacts.ContactMethods.CONTENT_EMAIL_URI, + Contacts.ContactMethods.CONTENT_URI, PROJECTION, where, args, @@ -181,15 +182,7 @@ public class ContactsSdk3_4 extends com.fsck.k9.helper.Contacts return null; } - final String where = Contacts.ContactMethods.DATA + " = ?"; - final String[] args = new String[] {address}; - - final Cursor c = mContentResolver.query( - Contacts.ContactMethods.CONTENT_EMAIL_URI, - PROJECTION, - where, - args, - SORT_ORDER); + final Cursor c = getContactByAddress(address); String name = null; if (c != null) @@ -216,4 +209,49 @@ public class ContactsSdk3_4 extends com.fsck.k9.helper.Contacts { 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); + Contacts.People.markAsContacted(mContentResolver, personId); + } + c.close(); + } + } + } + + /** + * 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(String address) + { + final String where = Contacts.ContactMethods.KIND + " = " + Contacts.KIND_EMAIL + + " AND " + + Contacts.ContactMethods.DATA + " = ?"; + final String[] args = new String[] {address}; + + final Cursor c = mContentResolver.query( + Contacts.ContactMethods.CONTENT_URI, + PROJECTION, + where, + args, + SORT_ORDER); + return c; + } } diff --git a/src/com/fsck/k9/helper/ContactsSdk5.java b/src/com/fsck/k9/helper/ContactsSdk5.java index 1ebf26e11..57afb8d82 100644 --- a/src/com/fsck/k9/helper/ContactsSdk5.java +++ b/src/com/fsck/k9/helper/ContactsSdk5.java @@ -7,6 +7,7 @@ import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.net.Uri; +import android.provider.ContactsContract; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Intents; import android.provider.ContactsContract.CommonDataKinds.Email; @@ -24,8 +25,9 @@ public class ContactsSdk5 extends com.fsck.k9.helper.Contacts * {@link #searchContacts(CharSequence)}. */ private static final String SORT_ORDER = - Contacts.TIMES_CONTACTED + " DESC, " + - Contacts.DISPLAY_NAME; + Email.TIMES_CONTACTED + " DESC, " + + Contacts.DISPLAY_NAME + ", " + + Email._ID; /** * Array of columns to load from the database. @@ -36,9 +38,10 @@ public class ContactsSdk5 extends com.fsck.k9.helper.Contacts */ private static final String PROJECTION[] = { - Contacts._ID, + Email._ID, Contacts.DISPLAY_NAME, - Email.DATA + Email.DATA, + Email.CONTACT_ID }; /** @@ -53,6 +56,12 @@ public class ContactsSdk5 extends com.fsck.k9.helper.Contacts */ private static final int EMAIL_INDEX = 2; + /** + * Index of the contact id field in the projection. This must match the order in + * {@link #PROJECTION}. + */ + private static final int CONTACT_ID_INDEX = 3; + public ContactsSdk5(final Context context) { @@ -105,9 +114,7 @@ public class ContactsSdk5 extends com.fsck.k9.helper.Contacts { boolean result = false; - - final Uri uri = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(emailAddress)); - final Cursor c = mContentResolver.query(uri, PROJECTION, null, null, null); + final Cursor c = getContactByAddress(emailAddress); if (c != null) { @@ -157,13 +164,7 @@ public class ContactsSdk5 extends com.fsck.k9.helper.Contacts return null; } - final Uri uri = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(address)); - final Cursor c = mContentResolver.query( - uri, - PROJECTION, - null, - null, - SORT_ORDER); + final Cursor c = getContactByAddress(address); String name = null; if (c != null) @@ -190,4 +191,45 @@ public class ContactsSdk5 extends com.fsck.k9.helper.Contacts { 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(); + } + } + } + + /** + * 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; + } }