diff --git a/res/layout-land/message_view.xml b/res/layout-land/message_view.xml
index 45a9eda43..92541fc37 100644
--- a/res/layout-land/message_view.xml
+++ b/res/layout-land/message_view.xml
@@ -31,7 +31,19 @@
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1">
-
+
+
+
+
+
diff --git a/src/com/android/email/Utility.java b/src/com/android/email/Utility.java
index ede1a0651..13a7f9aa8 100644
--- a/src/com/android/email/Utility.java
+++ b/src/com/android/email/Utility.java
@@ -16,6 +16,15 @@
package com.android.email;
+import com.android.email.provider.EmailContent;
+import com.android.email.provider.EmailContent.Mailbox;
+import com.android.email.provider.EmailContent.MailboxColumns;
+import com.android.email.provider.EmailContent.Message;
+import com.android.email.provider.EmailContent.MessageColumns;
+
+import android.content.ContentResolver;
+import android.database.Cursor;
+
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -221,4 +230,47 @@ public class Utility {
// }
// }
}
+
+ // TODO: unit test this
+ public static String buildMailboxIdSelection(ContentResolver resolver, long mailboxId) {
+ // Setup default selection & args, then add to it as necessary
+ StringBuilder selection = new StringBuilder(
+ Message.FLAG_LOADED + "!=" + Message.NOT_LOADED + " AND ");
+ if (mailboxId == Mailbox.QUERY_ALL_INBOXES
+ || mailboxId == Mailbox.QUERY_ALL_DRAFTS
+ || mailboxId == Mailbox.QUERY_ALL_OUTBOX) {
+ // query for all mailboxes of type INBOX, DRAFTS, or OUTBOX
+ int type;
+ if (mailboxId == Mailbox.QUERY_ALL_INBOXES) {
+ type = Mailbox.TYPE_INBOX;
+ } else if (mailboxId == Mailbox.QUERY_ALL_DRAFTS) {
+ type = Mailbox.TYPE_DRAFTS;
+ } else {
+ type = Mailbox.TYPE_OUTBOX;
+ }
+ StringBuilder inboxes = new StringBuilder();
+ Cursor c = resolver.query(Mailbox.CONTENT_URI,
+ EmailContent.ID_PROJECTION,
+ MailboxColumns.TYPE + "=? AND " + MailboxColumns.FLAG_VISIBLE + "=1",
+ new String[] { Integer.toString(type) }, null);
+ // build an IN (mailboxId, ...) list
+ // TODO do this directly in the provider
+ while (c.moveToNext()) {
+ if (inboxes.length() != 0) {
+ inboxes.append(",");
+ }
+ inboxes.append(c.getLong(EmailContent.ID_PROJECTION_COLUMN));
+ }
+ c.close();
+ selection.append(MessageColumns.MAILBOX_KEY + " IN ");
+ selection.append("(").append(inboxes).append(")");
+ } else if (mailboxId == Mailbox.QUERY_ALL_UNREAD) {
+ selection.append(Message.FLAG_READ + "=0");
+ } else if (mailboxId == Mailbox.QUERY_ALL_FAVORITES) {
+ selection.append(Message.FLAG_FAVORITE + "=1");
+ } else {
+ selection.append(MessageColumns.MAILBOX_KEY + "=" + mailboxId);
+ }
+ return selection.toString();
+ }
}
diff --git a/src/com/android/email/activity/AccountFolderList.java b/src/com/android/email/activity/AccountFolderList.java
index b050a7cfe..25c459001 100644
--- a/src/com/android/email/activity/AccountFolderList.java
+++ b/src/com/android/email/activity/AccountFolderList.java
@@ -290,7 +290,7 @@ public class AccountFolderList extends ListActivity
count = getUnreadCountByMailboxType(this, Mailbox.TYPE_INBOX);
if (count > 0) {
row = childCursor.newRow();
- row.add(Long.valueOf(MessageList.QUERY_ALL_INBOXES)); // MAILBOX_COLUMN_ID = 0;
+ row.add(Long.valueOf(Mailbox.QUERY_ALL_INBOXES)); // MAILBOX_COLUMN_ID = 0;
row.add(getString(R.string.account_folder_list_summary_inbox)); // MAILBOX_DISPLAY_NAME
row.add(null); // MAILBOX_ACCOUNT_KEY = 2;
row.add(Integer.valueOf(Mailbox.TYPE_INBOX)); // MAILBOX_TYPE = 3;
@@ -301,7 +301,7 @@ public class AccountFolderList extends ListActivity
count = EmailContent.count(this, Message.CONTENT_URI, FAVORITE_COUNT_SELECTION, null);
if (count > 0) {
row = childCursor.newRow();
- row.add(Long.valueOf(MessageList.QUERY_ALL_FAVORITES)); // MAILBOX_COLUMN_ID = 0;
+ row.add(Long.valueOf(Mailbox.QUERY_ALL_FAVORITES)); // MAILBOX_COLUMN_ID = 0;
// MAILBOX_DISPLAY_NAME
row.add(getString(R.string.account_folder_list_summary_favorite));
row.add(null); // MAILBOX_ACCOUNT_KEY = 2;
@@ -312,7 +312,7 @@ public class AccountFolderList extends ListActivity
count = getUnreadCountByMailboxType(this, Mailbox.TYPE_DRAFTS);
if (count > 0) {
row = childCursor.newRow();
- row.add(Long.valueOf(MessageList.QUERY_ALL_DRAFTS)); // MAILBOX_COLUMN_ID = 0;
+ row.add(Long.valueOf(Mailbox.QUERY_ALL_DRAFTS)); // MAILBOX_COLUMN_ID = 0;
row.add(getString(R.string.account_folder_list_summary_drafts));// MAILBOX_DISPLAY_NAME
row.add(null); // MAILBOX_ACCOUNT_KEY = 2;
row.add(Integer.valueOf(Mailbox.TYPE_DRAFTS)); // MAILBOX_TYPE = 3;
@@ -322,7 +322,7 @@ public class AccountFolderList extends ListActivity
count = getUnreadCountByMailboxType(this, Mailbox.TYPE_OUTBOX);
if (count > 0) {
row = childCursor.newRow();
- row.add(Long.valueOf(MessageList.QUERY_ALL_OUTBOX)); // MAILBOX_COLUMN_ID = 0;
+ row.add(Long.valueOf(Mailbox.QUERY_ALL_OUTBOX)); // MAILBOX_COLUMN_ID = 0;
row.add(getString(R.string.account_folder_list_summary_outbox));// MAILBOX_DISPLAY_NAME
row.add(null); // MAILBOX_ACCOUNT_KEY = 2;
row.add(Integer.valueOf(Mailbox.TYPE_OUTBOX)); // MAILBOX_TYPE = 3;
diff --git a/src/com/android/email/activity/FolderMessageList.java b/src/com/android/email/activity/FolderMessageList.java
index 0419d81e2..baef57865 100644
--- a/src/com/android/email/activity/FolderMessageList.java
+++ b/src/com/android/email/activity/FolderMessageList.java
@@ -818,7 +818,8 @@ public class FolderMessageList extends ExpandableListActivity {
for (MessageInfoHolder holder : folder.messages) {
folderUids.add(holder.uid);
}
- MessageView.actionView(this, mAccountId, folder.name, message.uid, folderUids);
+ // deprecated
+ // MessageView.actionView(this, mAccountId, folder.name, message.uid, folderUids);
}
}
@@ -841,7 +842,7 @@ public class FolderMessageList extends ExpandableListActivity {
// TODO - save enough data to recreate the cursor, to enable prev/next in MessageView
int messageIdColumn = messageCursor.getColumnIndex(EmailContent.RECORD_ID);
long messageId = messageCursor.getLong(messageIdColumn);
- MessageView.actionView(this, messageId);
+ MessageView.actionView(this, messageId, -1);
}
}
diff --git a/src/com/android/email/activity/MessageList.java b/src/com/android/email/activity/MessageList.java
index 1d4fa1d3c..f35fb627e 100644
--- a/src/com/android/email/activity/MessageList.java
+++ b/src/com/android/email/activity/MessageList.java
@@ -68,16 +68,6 @@ import java.util.HashSet;
import java.util.Set;
public class MessageList extends ListActivity implements OnItemClickListener, OnClickListener {
-
- // Magic mailbox ID's
- // NOTE: This is a quick solution for merged mailboxes. I would rather implement this
- // with a more generic way of packaging and sharing queries between activities
- public static final long QUERY_ALL_INBOXES = -2;
- public static final long QUERY_ALL_UNREAD = -3;
- public static final long QUERY_ALL_FAVORITES = -4;
- public static final long QUERY_ALL_DRAFTS = -5;
- public static final long QUERY_ALL_OUTBOX = -6;
-
// Intent extras (internal to this activity)
private static final String EXTRA_ACCOUNT_ID = "com.android.email.activity._ACCOUNT_ID";
private static final String EXTRA_MAILBOX_TYPE = "com.android.email.activity.MAILBOX_TYPE";
@@ -139,12 +129,6 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
private SetTitleTask mSetTitleTask;
private SetFooterTask mSetFooterTask;
- /**
- * Reduced mailbox projection used to hunt for inboxes
- * TODO: remove this and implement a custom URI
- */
- public final static int MAILBOX_FIND_INBOX_COLUMN_ID = 0;
-
public final static String[] MAILBOX_FIND_INBOX_PROJECTION = new String[] {
EmailContent.RECORD_ID, MailboxColumns.TYPE, MailboxColumns.FLAG_VISIBLE
};
@@ -491,7 +475,7 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
if (mailbox.mType == EmailContent.Mailbox.TYPE_DRAFTS) {
MessageCompose.actionEditDraft(this, messageId);
} else {
- MessageView.actionView(this, messageId);
+ MessageView.actionView(this, messageId, mailboxId);
}
}
@@ -671,12 +655,14 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
*/
private void addFooterView(long mailboxId, long accountId, int mailboxType) {
// first, look for shortcuts that don't need us to spin up a DB access task
- if (mailboxId == QUERY_ALL_INBOXES || mailboxId == QUERY_ALL_UNREAD
- || mailboxId == QUERY_ALL_FAVORITES || mailboxId == QUERY_ALL_DRAFTS) {
+ if (mailboxId == Mailbox.QUERY_ALL_INBOXES
+ || mailboxId == Mailbox.QUERY_ALL_UNREAD
+ || mailboxId == Mailbox.QUERY_ALL_FAVORITES
+ || mailboxId == Mailbox.QUERY_ALL_DRAFTS) {
finishFooterView(LIST_FOOTER_MODE_REFRESH);
return;
}
- if (mailboxId == QUERY_ALL_OUTBOX || mailboxType == Mailbox.TYPE_OUTBOX) {
+ if (mailboxId == Mailbox.QUERY_ALL_OUTBOX || mailboxType == Mailbox.TYPE_OUTBOX) {
finishFooterView(LIST_FOOTER_MODE_SEND);
return;
}
@@ -879,60 +865,14 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
@Override
protected Cursor doInBackground(Void... params) {
- // Setup default selection & args, then add to it as necessary
- StringBuilder selection = new StringBuilder(
- Message.FLAG_LOADED + "!=" + Message.NOT_LOADED + " AND ");
- String[] selArgs = null;
-
- if (mMailboxKey == QUERY_ALL_INBOXES || mMailboxKey == QUERY_ALL_DRAFTS ||
- mMailboxKey == QUERY_ALL_OUTBOX) {
- // query for all mailboxes of type INBOX, DRAFTS, or OUTBOX
- int type;
- if (mMailboxKey == QUERY_ALL_INBOXES) {
- type = Mailbox.TYPE_INBOX;
- } else if (mMailboxKey == QUERY_ALL_DRAFTS) {
- type = Mailbox.TYPE_DRAFTS;
- } else {
- type = Mailbox.TYPE_OUTBOX;
- }
- StringBuilder inboxes = new StringBuilder();
- Cursor c = MessageList.this.mResolver.query(
- Mailbox.CONTENT_URI,
- MAILBOX_FIND_INBOX_PROJECTION,
- MailboxColumns.TYPE + "=? AND " + MailboxColumns.FLAG_VISIBLE + "=1",
- new String[] { Integer.toString(type) }, null);
- // build a long WHERE list
- // TODO do this directly in the provider
- while (c.moveToNext()) {
- if (inboxes.length() != 0) {
- inboxes.append(" OR ");
- }
- inboxes.append(MessageColumns.MAILBOX_KEY + "=");
- inboxes.append(c.getLong(MAILBOX_FIND_INBOX_COLUMN_ID));
- }
- c.close();
- // This is a hack - if there were no matching mailboxes, the empty selection string
- // would match *all* messages. Instead, force a "non-matching" selection, which
- // generates an empty Message cursor.
- // TODO: handle this properly when we move the compound lookup into the provider
- if (inboxes.length() == 0) {
- inboxes.append(Message.RECORD_ID + "=-1");
- }
- // make that the selection
- selection.append(inboxes);
- } else if (mMailboxKey == QUERY_ALL_UNREAD) {
- selection.append(Message.FLAG_READ + "=0");
- } else if (mMailboxKey == QUERY_ALL_FAVORITES) {
- selection.append(Message.FLAG_FAVORITE + "=1");
- } else {
- selection.append(MessageColumns.MAILBOX_KEY + "=?");
- selArgs = new String[] { String.valueOf(mMailboxKey) };
- }
- return MessageList.this.managedQuery(
+ String selection =
+ Utility.buildMailboxIdSelection(MessageList.this.mResolver, mMailboxKey);
+ Cursor c = MessageList.this.managedQuery(
EmailContent.Message.CONTENT_URI,
MessageList.this.mListAdapter.PROJECTION,
- selection.toString(), selArgs,
+ selection, null,
EmailContent.MessageColumns.TIMESTAMP + " DESC");
+ return c;
}
@Override
@@ -945,7 +885,7 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
}
// Reset the "new messages" count in the service, since we're seeing them now
- if (mMailboxKey == QUERY_ALL_INBOXES) {
+ if (mMailboxKey == Mailbox.QUERY_ALL_INBOXES) {
MailService.resetNewMessageCount(MessageList.this, -1);
} else if (mMailboxKey >= 0 && mAccountKey != -1) {
MailService.resetNewMessageCount(MessageList.this, mAccountKey);
@@ -964,16 +904,16 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
@Override
protected String[] doInBackground(Void... params) {
// Check special Mailboxes
- if (mMailboxKey == MessageList.QUERY_ALL_INBOXES) {
+ if (mMailboxKey == Mailbox.QUERY_ALL_INBOXES) {
return new String[] {null,
getString(R.string.account_folder_list_summary_inbox)};
- } else if (mMailboxKey == MessageList.QUERY_ALL_FAVORITES) {
+ } else if (mMailboxKey == Mailbox.QUERY_ALL_FAVORITES) {
return new String[] {null,
getString(R.string.account_folder_list_summary_favorite)};
- } else if (mMailboxKey == MessageList.QUERY_ALL_DRAFTS) {
+ } else if (mMailboxKey == Mailbox.QUERY_ALL_DRAFTS) {
return new String[] {null,
getString(R.string.account_folder_list_summary_drafts)};
- } else if (mMailboxKey == MessageList.QUERY_ALL_OUTBOX) {
+ } else if (mMailboxKey == Mailbox.QUERY_ALL_OUTBOX) {
return new String[] {null,
getString(R.string.account_folder_list_summary_outbox)};
}
diff --git a/src/com/android/email/activity/MessageView.java b/src/com/android/email/activity/MessageView.java
index b307e06b4..eafb181d1 100644
--- a/src/com/android/email/activity/MessageView.java
+++ b/src/com/android/email/activity/MessageView.java
@@ -27,6 +27,7 @@ import com.android.email.mail.MessagingException;
import com.android.email.mail.internet.EmailHtmlUtil;
import com.android.email.mail.internet.MimeUtility;
import com.android.email.provider.AttachmentProvider;
+import com.android.email.provider.EmailContent;
import com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.Attachment;
import com.android.email.provider.EmailContent.Body;
@@ -83,10 +84,7 @@ public class MessageView extends Activity
implements OnClickListener {
private static final String EXTRA_MESSAGE_ID = "com.android.email.MessageView_message_id";
private static final String EXTRA_ACCOUNT_ID = "com.android.email.MessageView_account_id";
- private static final String EXTRA_FOLDER = "com.android.email.MessageView_folder";
- private static final String EXTRA_MESSAGE = "com.android.email.MessageView_message";
- private static final String EXTRA_FOLDER_UIDS = "com.android.email.MessageView_folderUids";
- private static final String EXTRA_NEXT = "com.android.email.MessageView_next";
+ private static final String EXTRA_MAILBOX_ID = "com.android.email.MessageView_mailbox_id";
private static final String[] METHODS_WITH_PRESENCE_PROJECTION = new String[] {
People.ContactMethods._ID, // 0
@@ -127,6 +125,7 @@ public class MessageView extends Activity
private long mAccountId;
private Account mAccount;
private long mMessageId;
+ private long mMailboxId;
private Message mMessage;
private LoadMessageTask mLoadMessageTask;
@@ -139,7 +138,6 @@ public class MessageView extends Activity
private String mFolder;
private String mMessageUid;
- private Cursor mMessageListCursor;
private java.text.DateFormat mDateFormat;
private java.text.DateFormat mTimeFormat;
@@ -151,6 +149,11 @@ public class MessageView extends Activity
private MessageViewHandler mHandler = new MessageViewHandler();
private ControllerResults mControllerCallback = new ControllerResults();
+ private View mPrevious;
+ private View mNext;
+ private LoadPrevNextTask mLoadPrevNextTask;
+ private Cursor mPrevNextCursor;
+
class MessageViewHandler extends Handler {
private static final int MSG_ATTACHMENT_PROGRESS = 2;
private static final int MSG_SET_ATTACHMENTS_ENABLED = 4;
@@ -335,41 +338,60 @@ public class MessageView extends Activity
/**
* View a specific message found in the Email provider.
- *
- * TODO: Find a way to pass a cursor so we can iterator prev/next as well
+ * @param messageId the message to view.
+ * @param mailboxId identifies the sequence of messages used for prev/next navigation.
*/
- public static void actionView(Context context, long messageId) {
+ public static void actionView(Context context, long messageId, long mailboxId) {
Intent i = new Intent(context, MessageView.class);
i.putExtra(EXTRA_MESSAGE_ID, messageId);
+ i.putExtra(EXTRA_MAILBOX_ID, mailboxId);
context.startActivity(i);
}
- @Deprecated
- public static void actionView(Context context, long accountId,
- String folder, String messageUid, ArrayList folderUids) {
- actionView(context, accountId, folder, messageUid, folderUids, null);
+ /**
+ * Re-init everything needed for changing message.
+ */
+ private void messageChanged() {
+ cancelAllTasks();
+ setTitle("");
+ mAttachments.setVisibility(View.GONE);
+ mAttachmentIcon.setVisibility(View.GONE);
+
+ // are the text clear below needed?
+ // likely they only add flicker as the new message is displayed quickly
+// mSubjectView.setText(null);
+// mFromView.setText(null);
+// mTimeView.setText(null);
+// mDateView.setText(null);
+// mToView.setText(null);
+// mCcView.setText(null);
+
+ // Start an AsyncTask to make a new cursor and load the message
+ mLoadMessageTask = new LoadMessageTask(mMessageId);
+ mLoadMessageTask.execute();
+ updatePrevNextArrows(mPrevNextCursor);
}
- @Deprecated
- public static void actionView(Context context, long accountId,
- String folder, String messageUid, ArrayList folderUids, Bundle extras) {
- Intent i = new Intent(context, MessageView.class);
- i.putExtra(EXTRA_ACCOUNT_ID, accountId);
- i.putExtra(EXTRA_FOLDER, folder);
- i.putExtra(EXTRA_MESSAGE, messageUid);
- i.putExtra(EXTRA_FOLDER_UIDS, folderUids);
- if (extras != null) {
- i.putExtras(extras);
+ private void updatePrevNextArrows(Cursor cursor) {
+ if (cursor != null) {
+ boolean hasPrev, hasNext;
+ if (cursor.isAfterLast() || cursor.isBeforeFirst()) {
+ // The cursor not being on a message means that the current message was not found.
+ // While this should not happen, simply disable prev/next arrows in that case.
+ hasPrev = hasNext = false;
+ } else {
+ hasPrev = !cursor.isFirst();
+ hasNext = !cursor.isLast();
+ }
+ mPrevious.setVisibility(hasPrev ? View.VISIBLE : View.GONE);
+ mNext.setVisibility(hasNext ? View.VISIBLE : View.GONE);
}
- context.startActivity(i);
- }
+ }
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
-
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
-
setContentView(R.layout.message_view);
mSubjectView = (TextView) findViewById(R.id.subject);
@@ -385,14 +407,11 @@ public class MessageView extends Activity
mFavoriteIcon = (ImageView) findViewById(R.id.favorite);
mShowPicturesSection = findViewById(R.id.show_pictures_section);
mSenderPresenceView = (ImageView) findViewById(R.id.presence);
- mProgressDialog = new ProgressDialog(this);
- mProgressDialog.setIndeterminate(true);
- mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
-
- mMessageContentView.setVerticalScrollBarEnabled(false);
- mAttachments.setVisibility(View.GONE);
- mAttachmentIcon.setVisibility(View.GONE);
+ mNext = findViewById(R.id.next);
+ mPrevious = findViewById(R.id.previous);
+ mNext.setOnClickListener(this);
+ mPrevious.setOnClickListener(this);
mFromView.setOnClickListener(this);
mSenderPresenceView.setOnClickListener(this);
mFavoriteIcon.setOnClickListener(this);
@@ -401,10 +420,13 @@ public class MessageView extends Activity
findViewById(R.id.delete).setOnClickListener(this);
findViewById(R.id.show_pictures).setOnClickListener(this);
+ mMessageContentView.setVerticalScrollBarEnabled(false);
mMessageContentView.getSettings().setBlockNetworkImage(true);
mMessageContentView.getSettings().setSupportZoom(false);
- setTitle("");
+ mProgressDialog = new ProgressDialog(this);
+ mProgressDialog.setIndeterminate(true);
+ mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mDateFormat = android.text.format.DateFormat.getDateFormat(this); // short format
mTimeFormat = android.text.format.DateFormat.getTimeFormat(this); // 12/24 date format
@@ -414,37 +436,9 @@ public class MessageView extends Activity
Intent intent = getIntent();
mMessageId = intent.getLongExtra(EXTRA_MESSAGE_ID, -1);
-// mAccountId = intent.getLongExtra(EXTRA_ACCOUNT_ID, -1);
-// mAccount = EmailStore.Account.restoreAccountWithId(this, mAccountId);
-// mFolder = intent.getStringExtra(EXTRA_FOLDER);
-// mMessageUid = intent.getStringExtra(EXTRA_MESSAGE);
- mMessageListCursor = null; // TODO - pass message list cursor so we can prev/next
-
- View next = findViewById(R.id.next);
- View previous = findViewById(R.id.previous);
- /*
- * Next and Previous Message are not shown in landscape mode, so
- * we need to check before we use them.
- */
- if (next != null && previous != null && mMessageListCursor != null) {
- // TODO analyze based on cursor, not on a big nasty array
- next.setVisibility(View.GONE);
- previous.setVisibility(View.GONE);
-/*
- next.setOnClickListener(this);
- previous.setOnClickListener(this);
-
- findSurroundingMessagesUid();
-
- previous.setVisibility(mPreviousMessageUid != null ? View.VISIBLE : View.GONE);
- next.setVisibility(mNextMessageUid != null ? View.VISIBLE : View.GONE);
-
- boolean goNext = intent.getBooleanExtra(EXTRA_NEXT, false);
- if (goNext) {
- next.requestFocus();
- }
-*/
- }
+ mMailboxId = intent.getLongExtra(EXTRA_MAILBOX_ID, -1);
+ messageChanged();
+ }
/*
MessagingController.getInstance(getApplication()).addListener(mListener);
@@ -463,10 +457,6 @@ public class MessageView extends Activity
}
}.start();
*/
- // Start an AsyncTask to make a new cursor and load the message
- mLoadMessageTask = new LoadMessageTask(mMessageId);
- mLoadMessageTask.execute();
- }
@Override
public void onResume() {
@@ -485,6 +475,23 @@ public class MessageView extends Activity
Controller.getInstance(getApplication()).removeResultCallback(mControllerCallback);
}
+ private static void cancelTask(AsyncTask task) {
+ if (task != null && task.getStatus() != AsyncTask.Status.FINISHED) {
+ task.cancel(true);
+ }
+ }
+
+ private void cancelAllTasks() {
+ cancelTask(mLoadMessageTask);
+ mLoadMessageTask = null;
+ cancelTask(mLoadBodyTask);
+ mLoadBodyTask = null;
+ cancelTask(mLoadAttachmentsTask);
+ mLoadAttachmentsTask = null;
+ cancelTask(mLoadPrevNextTask);
+ mLoadPrevNextTask = null;
+ }
+
/**
* We override onDestroy to make sure that the WebView gets explicitly destroyed.
* Otherwise it can leak native references.
@@ -492,28 +499,16 @@ public class MessageView extends Activity
@Override
public void onDestroy() {
super.onDestroy();
-
- if (mLoadMessageTask != null
- && mLoadMessageTask.getStatus() != AsyncTask.Status.FINISHED) {
- mLoadMessageTask.cancel(true);
- mLoadMessageTask = null;
- }
- if (mLoadBodyTask != null
- && mLoadBodyTask.getStatus() != AsyncTask.Status.FINISHED) {
- mLoadBodyTask.cancel(true);
- mLoadBodyTask = null;
- }
- if (mLoadAttachmentsTask != null
- && mLoadAttachmentsTask.getStatus() != AsyncTask.Status.FINISHED) {
- mLoadAttachmentsTask.cancel(true);
- mLoadAttachmentsTask = null;
- }
-
+ cancelAllTasks();
// This is synchronized because the listener accesses mMessageContentView from its thread
synchronized (this) {
mMessageContentView.destroy();
mMessageContentView = null;
}
+ if (mPrevNextCursor != null) {
+ mPrevNextCursor.close();
+ mPrevNextCursor = null;
+ }
}
private void onDelete() {
@@ -593,23 +588,23 @@ public class MessageView extends Activity
}
private boolean onNext() {
- // TODO make this work using a cursor
- return false;
-/*
- Bundle extras = new Bundle(1);
- extras.putBoolean(EXTRA_NEXT, true);
- MessageView.actionView(this, mAccountId, mFolder, mNextMessageUid, mFolderUids, extras);
- finish();
-*/
+ if (mPrevNextCursor != null && mPrevNextCursor.moveToNext()) {
+ mMessageId = mPrevNextCursor.getLong(0);
+ messageChanged();
+ return true;
+ } else {
+ return false;
+ }
}
private boolean onPrevious() {
- // TODO make this work using a cursor
- return false;
-/*
- MessageView.actionView(this, mAccountId, mFolder, mPreviousMessageUid, mFolderUids);
- finish();
-*/
+ if (mPrevNextCursor != null && mPrevNextCursor.moveToPrevious()) {
+ mMessageId = mPrevNextCursor.getLong(0);
+ messageChanged();
+ return true;
+ } else {
+ return false;
+ }
}
private void onMarkAsRead(boolean isRead) {
@@ -956,6 +951,41 @@ public class MessageView extends Activity
mSenderPresenceView.setImageResource(presenceIconId);
}
+
+ /**
+ * This task finds out the messageId for the previous and next message
+ * in the order given by mailboxId as used in MessageList.
+ *
+ * It generates the same cursor as the one used in MessageList (but with an id-only projection),
+ * scans through it until finds the current messageId, and takes the previous and next ids.
+ */
+ private class LoadPrevNextTask extends AsyncTask {
+ private long mLocalMailboxId;
+
+ public LoadPrevNextTask(long mailboxId) {
+ mLocalMailboxId = mailboxId;
+ }
+
+ @Override
+ protected Cursor doInBackground(Void... params) {
+ String selection =
+ Utility.buildMailboxIdSelection(getContentResolver(), mLocalMailboxId);
+ Cursor c = MessageView.this.managedQuery(EmailContent.Message.CONTENT_URI,
+ EmailContent.ID_PROJECTION,
+ selection, null,
+ EmailContent.MessageColumns.TIMESTAMP + " DESC");
+ return c;
+ }
+
+ @Override
+ protected void onPostExecute(Cursor cursor) {
+ // position the cursor on the current message
+ while (cursor.moveToNext() && cursor.getLong(0) != mMessageId);
+ mPrevNextCursor = cursor;
+ updatePrevNextArrows(mPrevNextCursor);
+ }
+ }
+
/**
* Async task for loading a single message outside of the UI thread
*
@@ -1071,7 +1101,15 @@ public class MessageView extends Activity
Message message = new Message().restore(cursor);
mMessage = message;
mAccountId = message.mAccountKey;
-
+ if (mMailboxId == -1) {
+ mMailboxId = message.mMailboxKey;
+ }
+ // only start LoadPrevNextTask once
+ if (mPrevNextCursor == null) {
+ mLoadPrevNextTask = new LoadPrevNextTask(mMailboxId);
+ mLoadPrevNextTask.execute();
+ }
+
mSubjectView.setText(message.mSubject);
mFromView.setText(Address.toFriendly(Address.unpack(message.mFrom)));
Date date = new Date(message.mTimeStamp);
diff --git a/src/com/android/email/provider/EmailContent.java b/src/com/android/email/provider/EmailContent.java
index 14c2b434e..065923b45 100644
--- a/src/com/android/email/provider/EmailContent.java
+++ b/src/com/android/email/provider/EmailContent.java
@@ -1812,14 +1812,9 @@ public abstract class EmailContent {
// Push-Hold indicates an EAS push or ping Mailbox shouldn't sync just yet
public static final int CHECK_INTERVAL_PUSH_HOLD = -4;
-
private static final String WHERE_TYPE_AND_ACCOUNT_KEY =
MailboxColumns.TYPE + "=? and " + MailboxColumns.ACCOUNT_KEY + "=?";
- public Mailbox() {
- mBaseUri = CONTENT_URI;
- }
-
// Types of mailboxes. The list is ordered to match a typical UI presentation, e.g.
// placing the inbox at the top.
// The "main" mailbox for the account, almost always referred to as "Inbox"
@@ -1852,6 +1847,19 @@ public abstract class EmailContent {
public static final int FLAG_CHILDREN_VISIBLE = 1<<1;
public static final int FLAG_CANT_PUSH = 1<<2;
+ // Magic mailbox ID's
+ // NOTE: This is a quick solution for merged mailboxes. I would rather implement this
+ // with a more generic way of packaging and sharing queries between activities
+ public static final long QUERY_ALL_INBOXES = -2;
+ public static final long QUERY_ALL_UNREAD = -3;
+ public static final long QUERY_ALL_FAVORITES = -4;
+ public static final long QUERY_ALL_DRAFTS = -5;
+ public static final long QUERY_ALL_OUTBOX = -6;
+
+ public Mailbox() {
+ mBaseUri = CONTENT_URI;
+ }
+
/**
* Restore a Mailbox from the database, given its unique id
* @param context
diff --git a/src/com/android/email/service/MailService.java b/src/com/android/email/service/MailService.java
index 0e84c46f7..58d621d2f 100644
--- a/src/com/android/email/service/MailService.java
+++ b/src/com/android/email/service/MailService.java
@@ -553,7 +553,7 @@ public class MailService extends Service {
R.plurals.notification_new_multi_account_fmt, accountsWithNewMessages,
accountsWithNewMessages);
intent = MessageList.actionHandleAccountIntent(this,
- -1, MessageList.QUERY_ALL_INBOXES, -1);
+ -1, Mailbox.QUERY_ALL_INBOXES, -1);
}
// prepare appropriate pending intent, set up notification, and send