1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-11-23 18:02:15 -05:00

Add "Check mail" menu items:

Accounts: Option menu->Check mail = check mail in all
   folders of all accounts
Accounts: Context (long-press on account) menu->Check mail = check mail
   in all folders of this account

Folder/Message List: Option menu->Check mail = check mail in all
   folders of this account
Folder/Message List: Contet (long-press on folder) menu->Check mail = check mail in this
   folder*

*All "Check mail" options, except for the long-press on an individual
folder, respect the normal synchronization class settings.

Eliminate all Refresh menu items.

Add progress indicators to Accounts activity.  Indeterminite progress
indicator while email checking is in progress.  Determinite progress
indicator while fetching unread counts.
This commit is contained in:
Daniel Applebaum 2009-04-01 03:25:16 +00:00
parent f699361390
commit 8ca1830afb
10 changed files with 191 additions and 45 deletions

View File

@ -2,6 +2,8 @@
<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" <item android:id="@+id/open"
android:title="@string/open_action" /> android:title="@string/open_action" />
<item android:id="@+id/check_mail"
android:title="@string/check_mail_action" />
<item android:id="@+id/empty_trash" <item android:id="@+id/empty_trash"
android:title="@string/empty_trash_action" /> android:title="@string/empty_trash_action" />
<item android:id="@+id/edit_account" <item android:id="@+id/edit_account"

View File

@ -3,7 +3,7 @@
<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/check_mail_action"
android:icon="@drawable/ic_menu_refresh" android:icon="@drawable/ic_menu_refresh"
/> />
<item <item

View File

@ -9,10 +9,13 @@
android:id="@+id/empty_trash" android:id="@+id/empty_trash"
android:title="@string/empty_trash_action" android:title="@string/empty_trash_action"
/> />
<item <item
android:id="@+id/refresh" android:id="@+id/check_mail"
android:title="@string/refresh_action" android:title="@string/check_mail_action"
/>
<item
android:id="@+id/send_messages"
android:title="@string/send_messages_action"
/> />
<item <item
android:id="@+id/folder_settings" android:id="@+id/folder_settings"

View File

@ -44,15 +44,20 @@
android:icon="@drawable/ic_menu_reverse_sort" android:icon="@drawable/ic_menu_reverse_sort"
/> />
<item <item
android:id="@+id/refresh" android:id="@+id/check_mail"
android:alphabeticShortcut="r" android:alphabeticShortcut="r"
android:title="@string/refresh_action" android:title="@string/check_mail_action"
android:icon="@drawable/ic_menu_refresh" android:icon="@drawable/ic_menu_refresh"
/> />
<item <item
android:id="@+id/accounts" android:id="@+id/accounts"
android:title="@string/accounts_action" android:title="@string/accounts_action"
android:icon="@drawable/ic_menu_account_list" android:icon="@drawable/ic_menu_account_list"
/>
<item
android:id="@+id/list_folders"
android:title="@string/list_folders_action"
android:icon="@drawable/ic_menu_refresh"
/> />
<item <item
android:id="@+id/empty_trash" android:id="@+id/empty_trash"

View File

@ -11,7 +11,7 @@
<string name="read_attachment_desc">Allows this application to read your Email attachments.</string> <string name="read_attachment_desc">Allows this application to read your Email attachments.</string>
<string name="about_title_fmt">About <xliff:g id="app_name">%s</xliff:g></string> <string name="about_title_fmt">About <xliff:g id="app_name">%s</xliff:g></string>
<string name="accounts_title">Your accounts</string> <string name="accounts_title">Accounts</string>
<string name="compose_title">Compose</string> <string name="compose_title">Compose</string>
<string name="debug_title">Debug</string> <string name="debug_title">Debug</string>
<string name="choose_folder_title">Choose Folder</string> <string name="choose_folder_title">Choose Folder</string>
@ -32,6 +32,9 @@
<string name="save_draft_action">Save as draft</string> <string name="save_draft_action">Save as draft</string>
<string name="retry_action">Retry</string> <string name="retry_action">Retry</string>
<string name="refresh_action">Refresh</string> <string name="refresh_action">Refresh</string>
<string name="check_mail_action">Check mail</string>
<string name="send_messages_action">Send messages</string>
<string name="list_folders_action">List folders</string>
<string name="mark_all_as_read_action">Mark all messages as read</string> <string name="mark_all_as_read_action">Mark all messages as read</string>
<string name="add_account_action">Add account</string> <string name="add_account_action">Add account</string>
<string name="compose_action">Compose</string> <string name="compose_action">Compose</string>
@ -130,6 +133,7 @@ Welcome to K-9 Mail setup. K-9 is an open source email client for Android based
\n \n
\nK-9's improved features include: \nK-9's improved features include:
* Better performance * Better performance
* Message refiling
* Email signatures * Email signatures
* Bcc-to-self * Bcc-to-self
* Folder subscriptions * Folder subscriptions

View File

@ -118,6 +118,8 @@ public class Email extends Application {
* Max time (in millis) the wake lock will be held for when background sync is happening * Max time (in millis) the wake lock will be held for when background sync is happening
*/ */
public static final int WAKE_LOCK_TIMEOUT = 600000; public static final int WAKE_LOCK_TIMEOUT = 600000;
public static final int MANUAL_WAKE_LOCK_TIMEOUT = 120000;
/** /**
* LED color used for the new email notitication * LED color used for the new email notitication

View File

@ -26,7 +26,9 @@ import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.PowerManager;
import android.os.Process; import android.os.Process;
import android.os.PowerManager.WakeLock;
import android.util.Config; import android.util.Config;
import android.util.Log; import android.util.Log;
@ -756,12 +758,6 @@ public class MessagingController implements Runnable {
remoteUidMap.put(message.getUid(), message); remoteUidMap.put(message.getUid(), message);
} }
/* /*
* Get a list of the messages that are in the remote list but not on the * Get a list of the messages that are in the remote list but not on the
* local store, or messages that are in the local store but failed to download * local store, or messages that are in the local store but failed to download
@ -781,8 +777,6 @@ public class MessagingController implements Runnable {
} }
} }
/* /*
* A list of messages that were downloaded and which did not have the Seen flag set. * A list of messages that were downloaded and which did not have the Seen flag set.
* This will serve to indicate the true "new" message count that will be reported to * This will serve to indicate the true "new" message count that will be reported to
@ -2442,9 +2436,7 @@ s * critical data as fast as possible, and then we'll fill in the de
}); });
} }
/** /**
* Checks mail for one or multiple accounts. If account is null all accounts * Checks mail for one or multiple accounts. If account is null all accounts
* are checked. * are checked.
@ -2453,9 +2445,19 @@ s * critical data as fast as possible, and then we'll fill in the de
* @param account * @param account
* @param listener * @param listener
*/ */
public void checkMail(final Context context, final Account account, public void checkMail(final Context context, final Account account,
final boolean ignoreLastCheckedTime,
final boolean useManualWakeLock,
final MessagingListener listener) { final MessagingListener listener) {
if (useManualWakeLock) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Email");
wakeLock.setReferenceCounted(false);
wakeLock.acquire(Email.MANUAL_WAKE_LOCK_TIMEOUT);
}
for (MessagingListener l : getListeners()) { for (MessagingListener l : getListeners()) {
l.checkMailStarted(context, account); l.checkMailStarted(context, account);
} }
@ -2480,7 +2482,7 @@ s * critical data as fast as possible, and then we'll fill in the de
for (final Account account : accounts) { for (final Account account : accounts) {
final long accountInterval = account.getAutomaticCheckIntervalMinutes() * 60 * 1000; final long accountInterval = account.getAutomaticCheckIntervalMinutes() * 60 * 1000;
if (accountInterval <= 0) if (ignoreLastCheckedTime == false && accountInterval <= 0)
{ {
if (Config.LOGV || true) if (Config.LOGV || true)
{ {
@ -2582,7 +2584,7 @@ s * critical data as fast as possible, and then we'll fill in the de
new Date(folder.getLastChecked())); new Date(folder.getLastChecked()));
} }
if (folder.getLastChecked() > if (ignoreLastCheckedTime == false && folder.getLastChecked() >
(System.currentTimeMillis() - accountInterval)) (System.currentTimeMillis() - accountInterval))
{ {
if (Config.LOGV) { if (Config.LOGV) {
@ -2603,7 +2605,7 @@ s * critical data as fast as possible, and then we'll fill in the de
LocalFolder tLocalFolder = (LocalFolder) localStore.getFolder(folder.getName()); LocalFolder tLocalFolder = (LocalFolder) localStore.getFolder(folder.getName());
tLocalFolder.open(Folder.OpenMode.READ_WRITE); tLocalFolder.open(Folder.OpenMode.READ_WRITE);
if (tLocalFolder.getLastChecked() > if (ignoreLastCheckedTime == false && tLocalFolder.getLastChecked() >
(System.currentTimeMillis() - accountInterval)) (System.currentTimeMillis() - accountInterval))
{ {
if (Config.LOGV) { if (Config.LOGV) {

View File

@ -15,6 +15,8 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.Menu; import android.view.Menu;
@ -52,6 +54,8 @@ import com.android.email.mail.store.LocalStore.LocalFolder;
public class Accounts extends ListActivity implements OnItemClickListener, OnClickListener { public class Accounts extends ListActivity implements OnItemClickListener, OnClickListener {
private static final int DIALOG_REMOVE_ACCOUNT = 1; private static final int DIALOG_REMOVE_ACCOUNT = 1;
private ConcurrentHashMap<String, Integer> unreadMessageCounts = new ConcurrentHashMap<String, Integer>(); private ConcurrentHashMap<String, Integer> unreadMessageCounts = new ConcurrentHashMap<String, Integer>();
private ConcurrentHashMap<Account, String> pendingWork = new ConcurrentHashMap<Account, String>();
/** /**
* Key codes used to open a debug settings screen. * Key codes used to open a debug settings screen.
*/ */
@ -77,6 +81,9 @@ public class Accounts extends ListActivity implements OnItemClickListener, OnCli
private static final int DATA_CHANGED = 1; private static final int DATA_CHANGED = 1;
private static final int MSG_ACCOUNT_SIZE_CHANGED = 2; private static final int MSG_ACCOUNT_SIZE_CHANGED = 2;
private static final int MSG_WORKING_ACCOUNT = 3; private static final int MSG_WORKING_ACCOUNT = 3;
private static final int MSG_PROGRESS = 4;
private static final int MSG_FOLDER_SYNCING = 5;
private static final int MSG_DEFINITE_PROGRESS = 6;
public void handleMessage(android.os.Message msg) public void handleMessage(android.os.Message msg)
{ {
@ -111,6 +118,26 @@ public class Accounts extends ListActivity implements OnItemClickListener, OnCli
toast.show(); toast.show();
break; break;
} }
case MSG_FOLDER_SYNCING:
{
String folderName = (String) ((Object[]) msg.obj)[0];
String dispString;
dispString = getString(R.string.accounts_title);
if (folderName != null)
{
dispString += " (" + getString(R.string.status_loading)
+ folderName + ")";
}
setTitle(dispString);
break;
}
case MSG_PROGRESS:
setProgressBarIndeterminateVisibility(msg.arg1 != 0);
//setProgressBarVisibility(msg.arg1 != 0);
break;
case MSG_DEFINITE_PROGRESS:
getWindow().setFeatureInt(Window.FEATURE_PROGRESS, msg.arg1);
break;
default: default:
super.handleMessage(msg); super.handleMessage(msg);
} }
@ -142,6 +169,29 @@ public class Accounts extends ListActivity implements OnItemClickListener, OnCli
msg.obj = holder; msg.obj = holder;
sendMessage(msg); sendMessage(msg);
} }
public void progress(boolean progress)
{
android.os.Message msg = new android.os.Message();
msg.what = MSG_PROGRESS;
msg.arg1 = progress ? 1 : 0;
sendMessage(msg);
}
public void progress(int progress)
{
android.os.Message msg = new android.os.Message();
msg.what = MSG_DEFINITE_PROGRESS;
msg.arg1 = progress ;
sendMessage(msg);
}
public void folderSyncing(String folder)
{
android.os.Message msg = new android.os.Message();
msg.what = MSG_FOLDER_SYNCING;
msg.obj = new String[]
{ folder };
sendMessage(msg);
}
} }
@ -151,6 +201,17 @@ public class Accounts extends ListActivity implements OnItemClickListener, OnCli
{ {
unreadMessageCounts.put(account.getUuid(), unreadMessageCount); unreadMessageCounts.put(account.getUuid(), unreadMessageCount);
mHandler.dataChanged(); mHandler.dataChanged();
pendingWork.remove(account);
if (pendingWork.isEmpty())
{
mHandler.progress(Window.PROGRESS_END);
}
else {
int level = (Window.PROGRESS_END / mAdapter.getCount()) * (mAdapter.getCount() - pendingWork.size()) ;
mHandler.progress(level);
}
} }
@Override @Override
@ -168,7 +229,27 @@ public class Accounts extends ListActivity implements OnItemClickListener, OnCli
int totalMessagesInMailbox, int totalMessagesInMailbox,
int numNewMessages) { int numNewMessages) {
MessagingController.getInstance(getApplication()).getAccountUnreadCount(Accounts.this, account, mListener); MessagingController.getInstance(getApplication()).getAccountUnreadCount(Accounts.this, account, mListener);
mHandler.progress(false);
mHandler.folderSyncing(null);
} }
@Override
public void synchronizeMailboxStarted(Account account, String folder)
{
mHandler.progress(true);
mHandler.folderSyncing(account.getDescription()
+ getString(R.string.notification_bg_title_separator) + folder);
}
@Override
public void synchronizeMailboxFailed(Account account, String folder,
String message)
{
mHandler.progress(false);
mHandler.folderSyncing(null);
}
}; };
private static String UNREAD_MESSAGE_COUNTS = "unreadMessageCounts"; private static String UNREAD_MESSAGE_COUNTS = "unreadMessageCounts";
@ -176,6 +257,10 @@ public class Accounts extends ListActivity implements OnItemClickListener, OnCli
@Override @Override
public void onCreate(Bundle icicle) { public void onCreate(Bundle icicle) {
super.onCreate(icicle); super.onCreate(icicle);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
requestWindowFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.accounts); setContentView(R.layout.accounts);
ListView listView = getListView(); ListView listView = getListView();
listView.setOnItemClickListener(this); listView.setOnItemClickListener(this);
@ -226,10 +311,14 @@ public class Accounts extends ListActivity implements OnItemClickListener, OnCli
Account[] accounts = Preferences.getPreferences(this).getAccounts(); Account[] accounts = Preferences.getPreferences(this).getAccounts();
mAdapter = new AccountsAdapter(accounts); mAdapter = new AccountsAdapter(accounts);
getListView().setAdapter(mAdapter); getListView().setAdapter(mAdapter);
if (accounts.length > 0) {
mHandler.progress(Window.PROGRESS_START);
}
for (Account account : accounts) for (Account account : accounts)
{ {
MessagingController.getInstance(getApplication()).getAccountUnreadCount(Accounts.this, account, mListener); MessagingController.getInstance(getApplication()).getAccountUnreadCount(Accounts.this, account, mListener);
pendingWork.put(account, "true");
} }
} }
@ -242,8 +331,9 @@ public class Accounts extends ListActivity implements OnItemClickListener, OnCli
AccountSettings.actionSettings(this, account); AccountSettings.actionSettings(this, account);
} }
private void onRefresh() { private void onCheckMail(Account account) {
MessagingController.getInstance(getApplication()).checkMail(this, null, null);
MessagingController.getInstance(getApplication()).checkMail(this, account, true, true, null);
} }
private void onClearCommands(Account account) { private void onClearCommands(Account account) {
@ -268,7 +358,9 @@ public class Accounts extends ListActivity implements OnItemClickListener, OnCli
} }
private void onOpenAccount(Account account) { private void onOpenAccount(Account account) {
FolderMessageList.actionHandleAccount(this, account, Email.INBOX); //FolderMessageList.actionHandleAccount(this, account); // Dan's way
FolderMessageList.actionHandleAccount(this, account, Email.INBOX); // Everbody else's way
} }
public void onClick(View view) { public void onClick(View view) {
@ -332,6 +424,9 @@ public class Accounts extends ListActivity implements OnItemClickListener, OnCli
case R.id.open: case R.id.open:
onOpenAccount(account); onOpenAccount(account);
break; break;
case R.id.check_mail:
onCheckMail(account);
break;
case R.id.clear_pending: case R.id.clear_pending:
onClearCommands(account); onClearCommands(account);
break; break;
@ -373,7 +468,7 @@ public class Accounts extends ListActivity implements OnItemClickListener, OnCli
onAddNewAccount(); onAddNewAccount();
break; break;
case R.id.check_mail: case R.id.check_mail:
onRefresh(); onCheckMail(null);
break; break;
case R.id.compose: case R.id.compose:
onCompose(); onCompose();

View File

@ -1121,14 +1121,27 @@ public class FolderMessageList extends ExpandableListActivity
mHandler.dataChanged(); mHandler.dataChanged();
} }
private void checkMail(final Account account)
{
MessagingController.getInstance(getApplication()).checkMail(this, account, true, true, mAdapter.mListener);
}
private void checkMail(Account account, String folderName)
{
MessagingController.getInstance(getApplication()).synchronizeMailbox(
account, folderName, mAdapter.mListener);
}
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) public boolean onOptionsItemSelected(MenuItem item)
{ {
switch (item.getItemId()) switch (item.getItemId())
{ {
case R.id.refresh: case R.id.check_mail:
onRefresh(true); checkMail(mAccount);
return true; return true;
case R.id.list_folders:
onRefresh(true);
return true;
case R.id.accounts: case R.id.accounts:
onAccounts(); onAccounts();
return true; return true;
@ -1247,18 +1260,13 @@ public class FolderMessageList extends ExpandableListActivity
{ {
switch (item.getItemId()) switch (item.getItemId())
{ {
case R.id.refresh: case R.id.send_messages:
if (folder.outbox) Log.i(Email.LOG_TAG, "sending pending messages from " + folder.name);
{ MessagingController.getInstance(getApplication()).sendPendingMessages(mAccount, null);
Log.i(Email.LOG_TAG, "sending pending messages from " + folder.name); break;
MessagingController.getInstance(getApplication()) case R.id.check_mail:
.sendPendingMessages(mAccount, null);
}
else
{
Log.i(Email.LOG_TAG, "refresh folder " + folder.name); Log.i(Email.LOG_TAG, "refresh folder " + folder.name);
new Thread(new FolderUpdateWorker(folder.name, true)).start(); new Thread(new FolderUpdateWorker(folder.name, true)).start();
}
break; break;
case R.id.folder_settings: case R.id.folder_settings:
Log.i(Email.LOG_TAG, "edit folder settings for " + folder.name); Log.i(Email.LOG_TAG, "edit folder settings for " + folder.name);
@ -1341,6 +1349,13 @@ public class FolderMessageList extends ExpandableListActivity
{ {
menu.findItem(R.id.empty_trash).setVisible(false); menu.findItem(R.id.empty_trash).setVisible(false);
} }
if (folder.outbox)
{
menu.findItem(R.id.check_mail).setVisible(false);
}
else {
menu.findItem(R.id.send_messages).setVisible(false);
}
menu.setHeaderTitle(R.string.folder_context_menu_title); menu.setHeaderTitle(R.string.folder_context_menu_title);
} }
} }

View File

@ -85,7 +85,7 @@ public class MailService extends Service {
mListener.wakeLockAcquire(); mListener.wakeLockAcquire();
controller.setCheckMailListener(mListener); controller.setCheckMailListener(mListener);
controller.checkMail(this, null, mListener); controller.checkMail(this, null, false, false, mListener);
} }
else else
{ {
@ -157,9 +157,18 @@ public class MailService extends Service {
long delay = (shortestInterval * (60 * 1000)); long delay = (shortestInterval * (60 * 1000));
long nextTime = System.currentTimeMillis() + delay; long nextTime = System.currentTimeMillis() + delay;
String checkString = "Next check for package " + getApplication().getPackageName() + " scheduled for " + new Date(nextTime); try
Log.v(Email.LOG_TAG, checkString); {
MessagingController.getInstance(getApplication()).log(checkString); String checkString = "Next check for package " + getApplication().getPackageName() + " scheduled for " + new Date(nextTime);
Log.v(Email.LOG_TAG, checkString);
MessagingController.getInstance(getApplication()).log(checkString);
}
catch (Exception e)
{
// I once got a NullPointerException deep in new Date();
Log.e(Email.LOG_TAG, "Exception while logging", e);
}
alarmMgr.set(AlarmManager.RTC_WAKEUP, nextTime, pi); alarmMgr.set(AlarmManager.RTC_WAKEUP, nextTime, pi);
} }
@ -235,10 +244,11 @@ public class MailService extends Service {
//since only the one that require so are in this map //since only the one that require so are in this map
if (accountsWithNewMail.containsKey(thisAccount.getUuid())) if (accountsWithNewMail.containsKey(thisAccount.getUuid()))
{ {
int unreadMessageCount = 0;
String notice = null; String notice = null;
try try
{ {
int unreadMessageCount = thisAccount.getUnreadMessageCount(context, getApplication()); unreadMessageCount = thisAccount.getUnreadMessageCount(context, getApplication());
if (unreadMessageCount > 0) if (unreadMessageCount > 0)
{ {
notice = getString(R.string.notification_new_one_account_fmt, unreadMessageCount, notice = getString(R.string.notification_new_one_account_fmt, unreadMessageCount,
@ -259,9 +269,12 @@ public class MailService extends Service {
Notification notif = new Notification(R.drawable.stat_notify_email_generic, Notification notif = new Notification(R.drawable.stat_notify_email_generic,
getString(R.string.notification_new_title), System.currentTimeMillis() + (index*1000)); getString(R.string.notification_new_title), System.currentTimeMillis() + (index*1000));
notif.number = (int)accountsWithNewMail.get(thisAccount.getUuid()); if (unreadMessageCount > 0)
{
notif.number = unreadMessageCount;
Intent i = FolderMessageList.actionHandleAccountIntent(context, thisAccount, Email.INBOX); Intent i = FolderMessageList.actionHandleAccountIntent(context, thisAccount);
PendingIntent pi = PendingIntent.getActivity(context, 0, i, 0); PendingIntent pi = PendingIntent.getActivity(context, 0, i, 0);
@ -280,6 +293,11 @@ public class MailService extends Service {
notif.ledOffMS = Email.NOTIFICATION_LED_OFF_TIME; notif.ledOffMS = Email.NOTIFICATION_LED_OFF_TIME;
notifMgr.notify(thisAccount.getAccountNumber(), notif); notifMgr.notify(thisAccount.getAccountNumber(), notif);
}
else
{
notifMgr.cancel(thisAccount.getAccountNumber());
}
} }
}//for accounts }//for accounts
}//checkMailDone }//checkMailDone