From e794af0bbf01015c14898aaba355195ad50a1577 Mon Sep 17 00:00:00 2001 From: Andrew Chen Date: Sun, 2 Jan 2011 09:01:23 +0000 Subject: [PATCH] Prevent new mail notifications if they're older than our most recent message. First attempt at fixing Issue 1276. Only works with services that use numeric message IDs, like IMAP. --- .../k9/controller/MessagingController.java | 46 +++++++++++++------ src/com/fsck/k9/mail/store/LocalStore.java | 46 ++++++++++++++++++- 2 files changed, 76 insertions(+), 16 deletions(-) diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java index 1ee8a5e03..7b35be8d1 100644 --- a/src/com/fsck/k9/controller/MessagingController.java +++ b/src/com/fsck/k9/controller/MessagingController.java @@ -431,7 +431,6 @@ public class MessagingController implements Runnable * TODO this needs to cache the remote folder list * * @param account - * @param includeRemote * @param listener * @throws MessagingException */ @@ -456,7 +455,6 @@ public class MessagingController implements Runnable * TODO this needs to cache the remote folder list * * @param account - * @param includeRemote * @param listener * @throws MessagingException */ @@ -733,12 +731,6 @@ public class MessagingController implements Runnable /** * Find all messages in any local account which match the query 'query' - * @param folderNames TODO - * @param query - * @param listener - * @param searchAccounts TODO - * @param account TODO - * @param account * @throws MessagingException */ public void searchLocalMessages(final String[] accountUuids, final String[] folderNames, final Message[] messages, final String query, final boolean integrate, @@ -1069,6 +1061,7 @@ public class MessagingController implements Runnable tLocalFolder = localStore.getFolder(folder); final LocalFolder localFolder = tLocalFolder; localFolder.open(OpenMode.READ_WRITE); + localFolder.updateLastUid(); Message[] localMessages = localFolder.getMessages(null); HashMap localUidMap = new HashMap(); for (Message message : localMessages) @@ -1878,7 +1871,7 @@ public class MessagingController implements Runnable } // Send a notification of this message - if (shouldNotifyForMessage(account, message)) + if (shouldNotifyForMessage(account, localFolder, message)) { newMessages.incrementAndGet(); notifyAccount(mApplication, account, message, unreadBeforeStart, newMessages); @@ -2023,7 +2016,7 @@ public class MessagingController implements Runnable } // Send a notification of this message - if (shouldNotifyForMessage(account, message)) + if (shouldNotifyForMessage(account, localFolder, message)) { newMessages.incrementAndGet(); notifyAccount(mApplication, account, message, unreadBeforeStart, newMessages); @@ -3574,7 +3567,6 @@ public class MessagingController implements Runnable /** * Attempt to send any messages that are sitting in the Outbox. * @param account - * @param listener */ public void sendPendingMessagesSynchronous(final Account account) { @@ -4652,7 +4644,7 @@ public class MessagingController implements Runnable } - private boolean shouldNotifyForMessage(Account account, Message message) + private boolean shouldNotifyForMessage(Account account, LocalFolder localFolder, Message message) { // Do not notify if the user does not have notifications // enabled or if the message has been read @@ -4661,7 +4653,6 @@ public class MessagingController implements Runnable return false; } - Folder folder = message.getFolder(); if (folder != null) { @@ -4677,6 +4668,24 @@ public class MessagingController implements Runnable } } + if (message.getUid() != null && localFolder.getLastUid() != null) + { + try + { + Integer messageUid = Integer.parseInt(message.getUid()); + if (messageUid <= localFolder.getLastUid()) + { + if(K9.DEBUG) + Log.d(K9.LOG_TAG, "Message uid is " + messageUid + ", max message uid is " + localFolder.getLastUid() + ". Skipping notification."); + return false; + } + } + catch (NumberFormatException e) + { + // Nothing to be done here. + } + } + return true; } @@ -4786,7 +4795,7 @@ public class MessagingController implements Runnable /** * @param notification * Object to configure. Never null. - * @param rintone + * @param ringtone * String name of ringtone. null if no ringtone should be played * @param vibrationPattern * long[] vibration pattern. null if no vibration should be played @@ -4852,7 +4861,12 @@ public class MessagingController implements Runnable notifMgr.cancel(-1000 - account.getAccountNumber()); } - + /** + * Save a draft message. + * @param account Account we are saving for. + * @param message Message to save. + * @return Message representing the entry in the local store. + */ public Message saveDraft(final Account account, final Message message) { Message localMessage = null; @@ -4861,10 +4875,12 @@ public class MessagingController implements Runnable LocalStore localStore = account.getLocalStore(); LocalFolder localFolder = localStore.getFolder(account.getDraftsFolderName()); localFolder.open(OpenMode.READ_WRITE); + // Save the message to the store. localFolder.appendMessages(new Message[] { message }); + // Fetch the message back from the store. This is the Message that's returned to the caller. localMessage = localFolder.getMessage(message.getUid()); localMessage.setFlag(Flag.X_DOWNLOADED_FULL, true); diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java index 9b21140c6..233e27c9c 100644 --- a/src/com/fsck/k9/mail/store/LocalStore.java +++ b/src/com/fsck/k9/mail/store/LocalStore.java @@ -1068,7 +1068,9 @@ public class LocalStore extends Store implements Serializable private String prefId = null; private String mPushState = null; private boolean mIntegrate = false; - + // mLastUid is used during syncs. It holds the highest UID within the local folder so we + // know whether or not an unread message added to the local folder is actually "new" or not. + private Integer mLastUid = null; public LocalFolder(String name) { @@ -5301,6 +5303,48 @@ public class LocalStore extends Store implements Serializable { this.inTopGroup = inTopGroup; } + + public Integer getLastUid() + { + return mLastUid; + } + + public void updateLastUid() throws MessagingException + { + Integer lastUid = database.execute(false, new DbCallback() + { + @Override + public Integer doDbWork(final SQLiteDatabase db) + { + Cursor cursor = null; + try + { + open(OpenMode.READ_ONLY); + cursor = db.rawQuery("SELECT MAX(uid) FROM messages WHERE folder_id=?", new String[] { Long.toString(mFolderId) }); + if (cursor.getCount() > 0) + { + cursor.moveToFirst(); + return cursor.getInt(0); + } + } + catch (Exception e) + { + Log.e(K9.LOG_TAG, "Unable to updateLastUid: ", e); + } + finally + { + if (cursor != null) + { + cursor.close(); + } + } + return null; + } + }); + if(K9.DEBUG) + Log.d(K9.LOG_TAG, "Updated last UID for folder " + mName + " to " + lastUid); + mLastUid = lastUid; + } } public static class LocalTextBody extends TextBody