Add folders to AccountFolderList

* Scan folders and write into child cursors
* Clicking a folder takes you to MessageList
* Remove most links to FolderMessageList (nearly dead!)
* Repair 1-account startup behavior (takes you directly to inbox)
* Cleanup a few basic things like context menus & refresh

TODO: Magic mailbox section at the top
TODO: As always, better linkage to sync engine(s)
TODO: Menus, context menus, etc.
TODO: Proper handling of expandable list - accounts should stay open?
This commit is contained in:
Andrew Stadler 2009-07-10 16:46:51 -07:00
parent 72dce73390
commit ded3c915d8
10 changed files with 432 additions and 165 deletions

View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingLeft="36px"
android:paddingRight="4px" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_vertical">
<TextView
android:id="@+id/folder_name"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="?android:attr/textColorPrimary"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/folder_status"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorTertiary"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<View
android:layout_height="0dip"
android:layout_width="0dip"
android:layout_weight="1" />
<TextView
android:id="@+id/new_message_count"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="?android:attr/textColorPrimary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/text_box_light"
android:paddingLeft="10px"
android:paddingRight="10px"
android:minWidth="64px"
android:gravity="right" />
</LinearLayout>

View File

@ -15,10 +15,12 @@
--> -->
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/open"
android:title="@string/open_action" />
<item android:id="@+id/edit_account" <item android:id="@+id/edit_account"
android:title="@string/account_settings_action" /> android:title="@string/account_settings_action" />
<item android:id="@+id/delete_account" <item android:id="@+id/delete_account"
android:title="@string/remove_account_action" /> android:title="@string/remove_account_action" />
<!-- This is probably temporary -->
<item android:id="@+id/refresh_account"
android:title="@string/refresh_action" />
</menu> </menu>

View File

@ -15,27 +15,24 @@
--> -->
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item <item android:id="@+id/check_mail"
android:id="@+id/check_mail"
android:alphabeticShortcut="r" android:alphabeticShortcut="r"
android:title="@string/refresh_action" android:title="@string/refresh_action"
android:icon="@*android:drawable/ic_menu_refresh" android:icon="@*android:drawable/ic_menu_refresh"
/> />
<item <item android:id="@+id/add_new_account"
android:id="@+id/add_new_account" android:title="@string/add_account_action"
android:title="@string/add_account_action" android:icon="@android:drawable/ic_menu_add"
android:icon="@android:drawable/ic_menu_add" />
/> <item android:id="@+id/compose"
<item
android:id="@+id/compose"
android:alphabeticShortcut="c" android:alphabeticShortcut="c"
android:title="@string/compose_action" android:title="@string/compose_action"
android:icon="@*android:drawable/ic_menu_compose" android:icon="@*android:drawable/ic_menu_compose"
/> />
<!-- <!--
<item android:id="@+id/search" <item android:id="@+id/search"
android:title="@string/search_action" /> android:title="@string/search_action" />
<item android:id="@+id/preferences" <item android:id="@+id/preferences"
android:title="@string/preferences_action" /> android:title="@string/preferences_action" />
--> -->
</menu> </menu>

View File

@ -16,11 +16,12 @@
package com.android.email.activity; package com.android.email.activity;
import com.android.email.Controller;
import com.android.email.Email; import com.android.email.Email;
import com.android.email.MessagingController;
import com.android.email.R; import com.android.email.R;
import com.android.email.activity.setup.AccountSettings; import com.android.email.activity.setup.AccountSettings;
import com.android.email.activity.setup.AccountSetupBasics; import com.android.email.activity.setup.AccountSetupBasics;
import com.android.email.mail.MessagingException;
import com.android.email.mail.Store; import com.android.email.mail.Store;
import com.android.email.provider.EmailContent; import com.android.email.provider.EmailContent;
import com.android.email.provider.EmailContent.Account; import com.android.email.provider.EmailContent.Account;
@ -37,6 +38,7 @@ import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -48,14 +50,12 @@ import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.CursorTreeAdapter; import android.widget.CursorTreeAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView; import android.widget.ExpandableListView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener; import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
public class AccountFolderList extends ExpandableListActivity public class AccountFolderList extends ExpandableListActivity implements OnClickListener {
implements OnItemClickListener, OnClickListener {
private static final int DIALOG_REMOVE_ACCOUNT = 1; private static final int DIALOG_REMOVE_ACCOUNT = 1;
/** /**
* Key codes used to open a debug settings screen. * Key codes used to open a debug settings screen.
@ -66,26 +66,18 @@ public class AccountFolderList extends ExpandableListActivity
}; };
private int mSecretKeyCodeIndex = 0; private int mSecretKeyCodeIndex = 0;
private static final String ICICLE_SELECTED_ACCOUNT = "com.android.email.selectedAccount"; private static final String ICICLE_SELECTED_ACCOUNT = "com.android.email.selectedAccount";
private EmailContent.Account mSelectedContextAccount; private EmailContent.Account mSelectedContextAccount;
ExpandableListView mListView;
LoadAccountsTask mAsyncTask;
/** ExpandableListView mListView;
* Support for list adapter AccountsAdapter mListAdapter;
*/
private final static String[] sFromColumns = new String[] { LoadAccountsTask mLoadAccountsTask;
EmailContent.AccountColumns.DISPLAY_NAME, LoadMailboxesTask mLoadMailboxesTask;
EmailContent.AccountColumns.EMAIL_ADDRESS,
EmailContent.RECORD_ID private MessageListHandler mHandler = new MessageListHandler();
}; private ControllerResults mControllerCallback = new ControllerResults();
private final int[] sToIds = new int[] {
R.id.description,
R.id.email,
R.id.new_message_count
};
/** /**
* Start the Accounts list activity. Uses the CLEAR_TOP flag which means that other stacked * Start the Accounts list activity. Uses the CLEAR_TOP flag which means that other stacked
@ -102,7 +94,6 @@ public class AccountFolderList extends ExpandableListActivity
super.onCreate(icicle); super.onCreate(icicle);
setContentView(R.layout.account_folder_list); setContentView(R.layout.account_folder_list);
mListView = getExpandableListView(); mListView = getExpandableListView();
mListView.setOnItemClickListener(this);
mListView.setItemsCanFocus(false); mListView.setItemsCanFocus(false);
mListView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_INSET); mListView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_INSET);
mListView.setLongClickable(true); mListView.setLongClickable(true);
@ -114,7 +105,7 @@ public class AccountFolderList extends ExpandableListActivity
mSelectedContextAccount = (Account) icicle.getParcelable(ICICLE_SELECTED_ACCOUNT); mSelectedContextAccount = (Account) icicle.getParcelable(ICICLE_SELECTED_ACCOUNT);
} }
mAsyncTask = (LoadAccountsTask) new LoadAccountsTask().execute(); mLoadAccountsTask = (LoadAccountsTask) new LoadAccountsTask().execute();
} }
@Override @Override
@ -125,6 +116,12 @@ public class AccountFolderList extends ExpandableListActivity
} }
} }
@Override
public void onPause() {
super.onPause();
Controller.getInstance(getApplication()).removeResultCallback(mControllerCallback);
}
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
@ -132,15 +129,26 @@ public class AccountFolderList extends ExpandableListActivity
NotificationManager notifMgr = (NotificationManager) NotificationManager notifMgr = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE); getSystemService(Context.NOTIFICATION_SERVICE);
notifMgr.cancel(1); notifMgr.cancel(1);
Controller.getInstance(getApplication()).addResultCallback(mControllerCallback);
// TODO: What updates do we need to auto-trigger, now that we have mailboxes in view?
} }
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
if (mAsyncTask != null && mAsyncTask.getStatus() != LoadAccountsTask.Status.FINISHED) { if (mLoadMailboxesTask != null &&
mAsyncTask.cancel(true); mLoadMailboxesTask.getStatus() != LoadMailboxesTask.Status.FINISHED) {
mAsyncTask = null; mLoadMailboxesTask.cancel(true);
mLoadMailboxesTask = null;
}
if (mLoadAccountsTask != null &&
mLoadAccountsTask.getStatus() != LoadAccountsTask.Status.FINISHED) {
mLoadAccountsTask.cancel(true);
mLoadAccountsTask = null;
} }
} }
@ -148,17 +156,33 @@ public class AccountFolderList extends ExpandableListActivity
public void onGroupExpand(int groupPosition) { public void onGroupExpand(int groupPosition) {
super.onGroupExpand(groupPosition); super.onGroupExpand(groupPosition);
// This is a temporary hack, until I implement the child cursors // If we don't have a cursor yet, create one
AccountsAdapter adapter = (AccountsAdapter) mListView.getExpandableListAdapter(); Cursor childCursor = mListAdapter.getChild(groupPosition, 0);
if (adapter != null) { if (childCursor == null) {
Cursor groupCursor = adapter.getGroup(groupPosition); // Kill any previous unfinished task
long mailboxKey = groupCursor.getLong(EmailContent.Mailbox.CONTENT_ID_COLUMN); if (mLoadMailboxesTask != null &&
FolderMessageList.actionHandleAccount(this, mailboxKey); mLoadMailboxesTask.getStatus() != LoadMailboxesTask.Status.FINISHED) {
mLoadMailboxesTask.cancel(true);
mLoadMailboxesTask = null;
}
// Now start a new task to create a non-empty cursor
Cursor groupCursor = mListAdapter.getCursor();
long accountKey = groupCursor.getLong(EmailContent.Account.CONTENT_ID_COLUMN);
mLoadMailboxesTask = new LoadMailboxesTask(accountKey, groupPosition);
mLoadMailboxesTask.execute();
} }
} }
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
int childPosition, long id) {
onOpenFolder(groupPosition, childPosition);
return true; // "handled"
}
/** /**
* Async task to handle the cursor query out of the UI thread * Async task to handle the accounts query outside of the UI thread
*/ */
private class LoadAccountsTask extends AsyncTask<Void, Void, Cursor> { private class LoadAccountsTask extends AsyncTask<Void, Void, Cursor> {
@ -173,8 +197,8 @@ public class AccountFolderList extends ExpandableListActivity
@Override @Override
protected void onPostExecute(Cursor theCursor) { protected void onPostExecute(Cursor theCursor) {
AccountsAdapter adapter = new AccountsAdapter(theCursor, AccountFolderList.this); mListAdapter = new AccountsAdapter(theCursor, AccountFolderList.this);
mListView.setAdapter(adapter); mListView.setAdapter(mListAdapter);
// This is deferred until after the first fetch, so it won't flicker // This is deferred until after the first fetch, so it won't flicker
// while we're waiting to find out if we have any accounts // while we're waiting to find out if we have any accounts
@ -182,6 +206,45 @@ public class AccountFolderList extends ExpandableListActivity
} }
} }
/**
* Async task to handle the mailboxes query outside of the UI thread
*/
private class LoadMailboxesTask extends AsyncTask<Void, Void, Cursor> {
private long mAccountId;
private int mGroupNumber;
public LoadMailboxesTask(long accountId, int groupNumber) {
mAccountId = accountId;
mGroupNumber = groupNumber;
}
@Override
protected Cursor doInBackground(Void... params) {
// TODO use a custom projection and don't have to sample all of these columns
return AccountFolderList.this.managedQuery(
EmailContent.Mailbox.CONTENT_URI,
EmailContent.Mailbox.CONTENT_PROJECTION,
EmailContent.MailboxColumns.ACCOUNT_KEY + "=?",
new String[] { String.valueOf(mAccountId) },
EmailContent.MailboxColumns.TYPE);
}
@Override
protected void onPostExecute(Cursor theCursor) {
// TODO: There is a race condition here - what if the result came back after
// the positions shifted? We need to use something other than "groupNumber"
// to set the correct adapter & cursor.
AccountFolderList.this.mListAdapter.setChildrenCursor(mGroupNumber, theCursor);
// If there are zero folders, this is probably a brand-new account - schedule a
// top-level refresh
if (theCursor.getCount() == 0) {
onRefresh(mAccountId);
}
}
}
private void onAddNewAccount() { private void onAddNewAccount() {
AccountSetupBasics.actionNewAccount(this); AccountSetupBasics.actionNewAccount(this);
} }
@ -190,8 +253,22 @@ public class AccountFolderList extends ExpandableListActivity
AccountSettings.actionSettings(this, accountId); AccountSettings.actionSettings(this, accountId);
} }
private void onRefresh() { /**
MessagingController.getInstance(getApplication()).checkMail(this, null, null); * Refresh one or all accounts
* @param accountId A specific id to refresh folders only, or -1 to refresh everything
*/
private void onRefresh(long accountId) {
if (accountId == -1) {
// TODO implement a suitable "Refresh all accounts" / "check mail" comment in Controller
// TODO this is temp
Toast.makeText(this,
"Please longpress an account to refresh it", Toast.LENGTH_LONG).show();
} else {
EmailContent.Account account =
EmailContent.Account.restoreAccountWithId(this, accountId);
Controller.getInstance(getApplication()).updateMailboxList(
account, mControllerCallback);
}
} }
private void onCompose() { private void onCompose() {
@ -203,10 +280,6 @@ public class AccountFolderList extends ExpandableListActivity
} }
} }
private void onOpenAccount(long accountId) {
FolderMessageList.actionHandleAccount(this, accountId);
}
public void onClick(View view) { public void onClick(View view) {
if (view.getId() == R.id.add_new_account) { if (view.getId() == R.id.add_new_account) {
onAddNewAccount(); onAddNewAccount();
@ -227,6 +300,17 @@ public class AccountFolderList extends ExpandableListActivity
return super.onCreateDialog(id); return super.onCreateDialog(id);
} }
/**
* Open a folder. This may be a "real" folder or composite, depending on which group.
* @param groupPosition The group # (account)
* @param childPosition The child # (folder)
*/
private void onOpenFolder(int groupPosition, int childPosition) {
Cursor childCursor = mListAdapter.getChild(groupPosition, childPosition);
long mailboxKey = childCursor.getLong(EmailContent.Mailbox.CONTENT_ID_COLUMN);
MessageList.actionHandleAccount(this, mailboxKey, null, null);
}
private Dialog createRemoveAccountDialog() { private Dialog createRemoveAccountDialog() {
return new AlertDialog.Builder(this) return new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert) .setIcon(android.R.drawable.ic_dialog_alert)
@ -263,27 +347,29 @@ public class AccountFolderList extends ExpandableListActivity
@Override @Override
public boolean onContextItemSelected(MenuItem item) { public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo)item.getMenuInfo(); ExpandableListContextMenuInfo menuInfo = (ExpandableListContextMenuInfo)item.getMenuInfo();
Cursor c = (Cursor) mListView.getItemAtPosition(menuInfo.position); int type = ExpandableListView.getPackedPositionType(menuInfo.packedPosition);
long accountId = c.getLong(Account.CONTENT_ID_COLUMN);
switch (item.getItemId()) {
case R.id.delete_account:
onDeleteAccount(accountId);
break;
case R.id.edit_account:
onEditAccount(accountId);
break;
case R.id.open:
onOpenAccount(accountId);
break;
}
return true;
}
public void onItemClick(AdapterView parent, View view, int position, long id) { if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {
Cursor c = (Cursor) mListView.getItemAtPosition(position); int group = ExpandableListView.getPackedPositionGroup(menuInfo.packedPosition);
long accountId = c.getLong(Account.CONTENT_ID_COLUMN); Cursor c = (Cursor) mListView.getItemAtPosition(group);
onOpenAccount(accountId); long accountId = c.getLong(Account.CONTENT_ID_COLUMN);
switch (item.getItemId()) {
case R.id.delete_account:
onDeleteAccount(accountId);
break;
case R.id.edit_account:
onEditAccount(accountId);
break;
case R.id.refresh_account:
onRefresh(accountId);
break;
}
return true;
} else {
// TODO child context menus (per mailbox)
return false;
}
} }
@Override @Override
@ -293,7 +379,7 @@ public class AccountFolderList extends ExpandableListActivity
onAddNewAccount(); onAddNewAccount();
break; break;
case R.id.check_mail: case R.id.check_mail:
onRefresh(); onRefresh(-1);
break; break;
case R.id.compose: case R.id.compose:
onCompose(); onCompose();
@ -311,15 +397,21 @@ public class AccountFolderList extends ExpandableListActivity
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu); super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.accounts_option, menu); getMenuInflater().inflate(R.menu.account_folder_list_option, menu);
return true; return true;
} }
@Override @Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo info) {
super.onCreateContextMenu(menu, v, menuInfo); super.onCreateContextMenu(menu, v, info);
menu.setHeaderTitle(R.string.accounts_context_menu_title); ExpandableListContextMenuInfo menuInfo = (ExpandableListContextMenuInfo) info;
getMenuInflater().inflate(R.menu.accounts_context, menu); int type = ExpandableListView.getPackedPositionType(menuInfo.packedPosition);
if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {
menu.setHeaderTitle(R.string.accounts_context_menu_title);
getMenuInflater().inflate(R.menu.account_folder_list_context, menu);
} else {
// TODO child context menus (per mailbox)
}
} }
@Override @Override
@ -336,6 +428,50 @@ public class AccountFolderList extends ExpandableListActivity
return super.onKeyDown(keyCode, event); return super.onKeyDown(keyCode, event);
} }
/**
* Handler for UI-thread operations (when called from callbacks or any other threads)
*/
class MessageListHandler extends Handler {
private static final int MSG_PROGRESS = 1;
@Override
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case MSG_PROGRESS:
setProgressBarIndeterminateVisibility(msg.arg1 != 0);
break;
default:
super.handleMessage(msg);
}
}
/**
* Call from any thread to start/stop progress indicator(s)
* @param progress true to start, false to stop
*/
public void progress(boolean progress) {
android.os.Message msg = android.os.Message.obtain();
msg.what = MSG_PROGRESS;
msg.arg1 = progress ? 1 : 0;
sendMessage(msg);
}
}
/**
* Callback for async Controller results. This is all a placeholder until we figure out the
* final way to do this.
*/
private class ControllerResults implements Controller.Result {
public void updateMailboxListCallback(MessagingException result, long accountKey) {
mHandler.progress(false);
}
public void updateMailboxCallback(MessagingException result, long accountKey,
long mailboxKey, int totalMessagesInMailbox, int numNewMessages) {
mHandler.progress(false);
}
}
private static class AccountsAdapter extends CursorTreeAdapter { private static class AccountsAdapter extends CursorTreeAdapter {
Context mContext; Context mContext;
@ -350,8 +486,27 @@ public class AccountFolderList extends ExpandableListActivity
@Override @Override
protected void bindChildView(View view, Context context, Cursor cursor, boolean isLastChild) protected void bindChildView(View view, Context context, Cursor cursor, boolean isLastChild)
{ {
// TODO Auto-generated method stub String text = cursor.getString(EmailContent.Mailbox.CONTENT_DISPLAY_NAME_COLUMN);
if (text != null) {
TextView nameView = (TextView) view.findViewById(R.id.folder_name);
nameView.setText(text);
}
// TODO get/trach live folder status
text = null;
TextView statusView = (TextView) view.findViewById(R.id.folder_status);
if (text != null) {
statusView.setText(text);
statusView.setVisibility(View.VISIBLE);
} else {
statusView.setVisibility(View.GONE);
}
text = cursor.getString(EmailContent.Mailbox.CONTENT_UNREAD_COUNT_COLUMN);
if (text != null) {
TextView countView = (TextView) view.findViewById(R.id.new_message_count);
countView.setText(text);
}
} }
@Override @Override
@ -369,12 +524,14 @@ public class AccountFolderList extends ExpandableListActivity
emailView.setText(text); emailView.setText(text);
} }
// TODO get unread count from Account
int unreadMessageCount = 0;
TextView countView = (TextView) view.findViewById(R.id.new_message_count); TextView countView = (TextView) view.findViewById(R.id.new_message_count);
int unreadMessageCount = 0; // TODO get unread count from Account if (unreadMessageCount > 0) {
if (unreadMessageCount <= 0) {
countView.setVisibility(View.GONE);
} else {
countView.setText(String.valueOf(unreadMessageCount)); countView.setText(String.valueOf(unreadMessageCount));
countView.setVisibility(View.VISIBLE);
} else {
countView.setVisibility(View.GONE);
} }
} }
@ -398,8 +555,7 @@ public class AccountFolderList extends ExpandableListActivity
@Override @Override
protected View newChildView(Context context, Cursor cursor, boolean isLastChild, protected View newChildView(Context context, Cursor cursor, boolean isLastChild,
ViewGroup parent) { ViewGroup parent) {
// TODO Auto-generated method stub return mInflater.inflate(R.layout.account_folder_list_child, parent, false);
return null;
} }
@Override @Override

View File

@ -418,6 +418,7 @@ public class FolderMessageList extends ExpandableListActivity {
* @param context * @param context
* @param id * @param id
*/ */
@Deprecated
public static void actionHandleAccount(Context context, long id) { public static void actionHandleAccount(Context context, long id) {
actionHandleAccount(context, id, null); actionHandleAccount(context, id, null);
} }
@ -428,6 +429,7 @@ public class FolderMessageList extends ExpandableListActivity {
* @param id * @param id
* @param initialFolder The folder to open, or null for none * @param initialFolder The folder to open, or null for none
*/ */
@Deprecated
public static void actionHandleAccount(Context context, long id, String initialFolder) { public static void actionHandleAccount(Context context, long id, String initialFolder) {
Intent intent = new Intent(context, FolderMessageList.class); Intent intent = new Intent(context, FolderMessageList.class);
intent.putExtra(EXTRA_ACCOUNT_ID, id); intent.putExtra(EXTRA_ACCOUNT_ID, id);
@ -437,6 +439,7 @@ public class FolderMessageList extends ExpandableListActivity {
context.startActivity(intent); context.startActivity(intent);
} }
@Deprecated
public static Intent actionHandleAccountIntent(Context context, long id, String initialFolder) { public static Intent actionHandleAccountIntent(Context context, long id, String initialFolder) {
Intent intent = new Intent(context, FolderMessageList.class); Intent intent = new Intent(context, FolderMessageList.class);
intent.putExtra(EXTRA_ACCOUNT_ID, id); intent.putExtra(EXTRA_ACCOUNT_ID, id);
@ -456,6 +459,7 @@ public class FolderMessageList extends ExpandableListActivity {
* @param initialFolder If non-null, can set the folder name to open (typically Email.INBOX) * @param initialFolder If non-null, can set the folder name to open (typically Email.INBOX)
* @return an Intent which can be used to view that account * @return an Intent which can be used to view that account
*/ */
@Deprecated
public static Intent actionHandleAccountUriIntent(Context context, long id, public static Intent actionHandleAccountUriIntent(Context context, long id,
String initialFolder) { String initialFolder) {
Intent i = actionHandleAccountIntent(context, id, initialFolder); Intent i = actionHandleAccountIntent(context, id, initialFolder);

View File

@ -61,6 +61,8 @@ import java.util.Set;
public class MessageList extends ListActivity implements OnItemClickListener, OnClickListener { public class MessageList extends ListActivity implements OnItemClickListener, OnClickListener {
// Intent extras (internal to this activity) // 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";
private static final String EXTRA_MAILBOX_ID = "com.android.email.activity.MAILBOX_ID"; private static final String EXTRA_MAILBOX_ID = "com.android.email.activity.MAILBOX_ID";
private static final String EXTRA_ACCOUNT_NAME = "com.android.email.activity.ACCOUNT_NAME"; private static final String EXTRA_ACCOUNT_NAME = "com.android.email.activity.ACCOUNT_NAME";
private static final String EXTRA_MAILBOX_NAME = "com.android.email.activity.MAILBOX_NAME"; private static final String EXTRA_MAILBOX_NAME = "com.android.email.activity.MAILBOX_NAME";
@ -99,6 +101,36 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
context.startActivity(intent); context.startActivity(intent);
} }
/**
* Open a specific mailbox by account & type
*
* @param context The caller's context (for generating an intent)
* @param accountId The account to open
* @param mailboxType the type of mailbox to open (e.g. @see EmailContent.Mailbox.TYPE_INBOX)
*/
public static void actionHandleAccount(Context context, long accountId, int mailboxType) {
Intent intent = new Intent(context, MessageList.class);
intent.putExtra(EXTRA_ACCOUNT_ID, accountId);
intent.putExtra(EXTRA_MAILBOX_TYPE, mailboxType);
context.startActivity(intent);
}
/**
* Return an intent to open a specific mailbox by account & type. It will also clear
* notifications.
*
* @param context The caller's context (for generating an intent)
* @param accountId The account to open
* @param mailboxType the type of mailbox to open (e.g. @see EmailContent.Mailbox.TYPE_INBOX)
*/
public static Intent actionHandleAccountIntent(Context context, long accountId,
int mailboxType) {
Intent intent = new Intent(context, MessageList.class);
intent.putExtra(EXTRA_ACCOUNT_ID, accountId);
intent.putExtra(EXTRA_MAILBOX_TYPE, mailboxType);
return intent;
}
@Override @Override
public void onCreate(Bundle icicle) { public void onCreate(Bundle icicle) {
super.onCreate(icicle); super.onCreate(icicle);
@ -123,10 +155,30 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
mListAdapter = new MessageListAdapter(this); mListAdapter = new MessageListAdapter(this);
setListAdapter(mListAdapter); setListAdapter(mListAdapter);
// TODO set title to "account > mailbox (#unread)"
// TODO extend this to properly deal with multiple mailboxes, cursor, etc. // TODO extend this to properly deal with multiple mailboxes, cursor, etc.
mMailboxId = getIntent().getLongExtra(EXTRA_MAILBOX_ID, -1); mMailboxId = getIntent().getLongExtra(EXTRA_MAILBOX_ID, -1);
if (mMailboxId == -1) {
// Try account/type mode
long accountId = getIntent().getLongExtra(EXTRA_ACCOUNT_ID, -1);
int mailboxType = getIntent().getIntExtra(EXTRA_MAILBOX_TYPE, -1);
Cursor c = null;
try {
c = getContentResolver().query(EmailContent.Mailbox.CONTENT_URI,
EmailContent.Mailbox.CONTENT_PROJECTION,
EmailContent.MailboxColumns.ACCOUNT_KEY + "=? AND " +
EmailContent.MailboxColumns.TYPE + "=?",
new String[] { Long.toString(accountId), Integer.toString(mailboxType) },
null);
if (c.moveToFirst()) {
mMailboxId = c.getLong(EmailContent.Mailbox.CONTENT_ID_COLUMN);
}
} finally {
if (c != null) c.close();
}
}
// TODO set title to "account > mailbox (#unread)"
mLoadMessagesTask = (LoadMessagesTask) new LoadMessagesTask(mMailboxId).execute(); mLoadMessagesTask = (LoadMessagesTask) new LoadMessagesTask(mMailboxId).execute();
} }
@ -300,7 +352,7 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
// TODO this should be a call to the controller, since it may possibly kick off // TODO this should be a call to the controller, since it may possibly kick off
// more than just a DB update. Also, the DB update shouldn't be in the UI thread // more than just a DB update. Also, the DB update shouldn't be in the UI thread
// as it is here. // as it is here. Also, it needs to update the read/unread count in the mailbox?
ContentValues cv = new ContentValues(); ContentValues cv = new ContentValues();
cv.put(EmailContent.MessageColumns.FLAG_READ, isRead); cv.put(EmailContent.MessageColumns.FLAG_READ, isRead);
Uri uri = ContentUris.withAppendedId( Uri uri = ContentUris.withAppendedId(

View File

@ -16,11 +16,8 @@
package com.android.email.activity; package com.android.email.activity;
import com.android.email.Email;
import com.android.email.provider.EmailContent;
import com.android.email.provider.EmailContent; import com.android.email.provider.EmailContent;
import com.android.exchange.SyncManager; import com.android.exchange.SyncManager;
//import com.android.exchange.SyncManager;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
@ -62,8 +59,8 @@ public class Welcome extends Activity {
null, null, null); null, null, null);
if (c.getCount() == 1) { if (c.getCount() == 1) {
c.moveToFirst(); c.moveToFirst();
long id = c.getLong(EmailContent.Account.CONTENT_ID_COLUMN); long accountId = c.getLong(EmailContent.Account.CONTENT_ID_COLUMN);
FolderMessageList.actionHandleAccount(this, id, Email.INBOX); MessageList.actionHandleAccount(this, accountId, EmailContent.Mailbox.TYPE_INBOX);
finish(); finish();
return; return;
} }

View File

@ -16,10 +16,9 @@
package com.android.email.activity.setup; package com.android.email.activity.setup;
import com.android.email.Email;
import com.android.email.R; import com.android.email.R;
import com.android.email.Utility; import com.android.email.Utility;
import com.android.email.activity.FolderMessageList; import com.android.email.activity.MessageList;
import com.android.email.provider.EmailContent; import com.android.email.provider.EmailContent;
import android.app.Activity; import android.app.Activity;
@ -106,7 +105,7 @@ public class AccountSetupNames extends Activity implements OnClickListener {
} }
mAccount.setName(mName.getText().toString()); mAccount.setName(mName.getText().toString());
mAccount.saveOrUpdate(this); mAccount.saveOrUpdate(this);
FolderMessageList.actionHandleAccount(this, mAccount.mId, Email.INBOX); MessageList.actionHandleAccount(this, mAccount.mId, EmailContent.Mailbox.TYPE_INBOX);
finish(); finish();
} }

View File

@ -22,7 +22,7 @@ import com.android.email.MessagingController;
import com.android.email.MessagingListener; import com.android.email.MessagingListener;
import com.android.email.R; import com.android.email.R;
import com.android.email.activity.AccountFolderList; import com.android.email.activity.AccountFolderList;
import com.android.email.activity.FolderMessageList; import com.android.email.activity.MessageList;
import com.android.email.mail.MessagingException; import com.android.email.mail.MessagingException;
import com.android.email.mail.Store; import com.android.email.mail.Store;
import com.android.email.mail.store.LocalStore; import com.android.email.mail.store.LocalStore;
@ -282,8 +282,8 @@ public class MailService extends Service {
} else { } else {
EmailContent.Account account1 = accountsWithNewMail.keySet().iterator().next(); EmailContent.Account account1 = accountsWithNewMail.keySet().iterator().next();
int totalNewMails = accountsWithNewMail.get(account1); int totalNewMails = accountsWithNewMail.get(account1);
Intent i = FolderMessageList.actionHandleAccountIntent(context, Intent i = MessageList.actionHandleAccountIntent(context,
account1.mId, Email.INBOX); account1.mId, EmailContent.Mailbox.TYPE_INBOX);
PendingIntent pi = PendingIntent.getActivity(context, 0, i, 0); PendingIntent pi = PendingIntent.getActivity(context, 0, i, 0);
notif.setLatestEventInfo(context, getString(R.string.notification_new_title), notif.setLatestEventInfo(context, getString(R.string.notification_new_title),
getResources(). getResources().

View File

@ -52,66 +52,66 @@ public class FolderMessageListUnitTests extends AndroidTestCase {
super.tearDown(); super.tearDown();
} }
/** // /**
* Test of actionHandleAccount() variants. Make sure they generate correct intents and // * Test of actionHandleAccount() variants. Make sure they generate correct intents and
* then call startActivity() with them. // * then call startActivity() with them.
*/ // */
public void testActionHandleAccount() { // public void testActionHandleAccount() {
// Create a dummy account // // Create a dummy account
createTestAccount(); // createTestAccount();
//
// Create a mock context to catch the startActivity calls // // Create a mock context to catch the startActivity calls
MyContext mockContext = new MyContext(getContext()); // MyContext mockContext = new MyContext(getContext());
//
// First, try with no initial folder // // First, try with no initial folder
FolderMessageList.actionHandleAccount(mockContext, mAccountId); // FolderMessageList.actionHandleAccount(mockContext, mAccountId);
Intent i = mockContext.startActivityIntent; // Intent i = mockContext.startActivityIntent;
assertNotNull(i); // assertNotNull(i);
checkIntent(i, null, mAccount, null); // checkIntent(i, null, mAccount, null);
//
// Next try with initial folder specified // // Next try with initial folder specified
FolderMessageList.actionHandleAccount(mockContext, mAccountId, "test-folder-name"); // FolderMessageList.actionHandleAccount(mockContext, mAccountId, "test-folder-name");
i = mockContext.startActivityIntent; // i = mockContext.startActivityIntent;
assertNotNull(i); // assertNotNull(i);
checkIntent(i, null, mAccount, "test-folder-name"); // checkIntent(i, null, mAccount, "test-folder-name");
} // }
/** /**
* Test of actionHandleAccountIntent(). Make sure it generates correct intents. * Test of actionHandleAccountIntent(). Make sure it generates correct intents.
*/ */
public void testActionHandleAccountIntent() { // public void testActionHandleAccountIntent() {
// Create a dummy account // // Create a dummy account
createTestAccount(); // createTestAccount();
//
// First try with no initial folder // // First try with no initial folder
Intent result = FolderMessageList.actionHandleAccountIntent( // Intent result = FolderMessageList.actionHandleAccountIntent(
getContext(), mAccountId, null); // getContext(), mAccountId, null);
checkIntent(result, null, mAccount, null); // checkIntent(result, null, mAccount, null);
//
// now try with a specified initial folder // // now try with a specified initial folder
result = FolderMessageList.actionHandleAccountIntent( // result = FolderMessageList.actionHandleAccountIntent(
getContext(), mAccountId, "test-folder-name"); // getContext(), mAccountId, "test-folder-name");
checkIntent(result, null, mAccount, "test-folder-name"); // checkIntent(result, null, mAccount, "test-folder-name");
} // }
/** /**
* Test of actionHandleAccountUriIntent(). Make sure it generates correct intents. * Test of actionHandleAccountUriIntent(). Make sure it generates correct intents.
*/ */
public void testActionHandleAccountUriIntent() { // public void testActionHandleAccountUriIntent() {
// Create a dummy account // // Create a dummy account
createTestAccount(); // createTestAccount();
Uri uri = ContentUris.withAppendedId(EmailContent.Account.CONTENT_URI, mAccountId); // Uri uri = ContentUris.withAppendedId(EmailContent.Account.CONTENT_URI, mAccountId);
//
// First try with no initial folder // // First try with no initial folder
Intent result = FolderMessageList.actionHandleAccountUriIntent( // Intent result = FolderMessageList.actionHandleAccountUriIntent(
getContext(), mAccountId, null); // getContext(), mAccountId, null);
checkIntent(result, uri, null, null); // checkIntent(result, uri, null, null);
//
// now try with a specified initial folder // // now try with a specified initial folder
result = FolderMessageList.actionHandleAccountUriIntent( // result = FolderMessageList.actionHandleAccountUriIntent(
getContext(), mAccountId, "test-folder-name"); // getContext(), mAccountId, "test-folder-name");
checkIntent(result, uri, null, "test-folder-name"); // checkIntent(result, uri, null, "test-folder-name");
} // }
/** /**
* Check the values in a generated intent * Check the values in a generated intent