Integrate EAS push notifications with the main notifications.

* Use the new account-based field for number of new messages
* Add support for async notifications in MailService
* Change EAS to call MailService to notify user
This commit is contained in:
Andrew Stadler 2009-08-18 19:50:18 -07:00
parent 2cf87e6c3c
commit cbe513d430
3 changed files with 75 additions and 37 deletions

View File

@ -754,9 +754,9 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
// Reset the "new messages" count in the service, since we're seeing them now // Reset the "new messages" count in the service, since we're seeing them now
if (mMailboxKey == QUERY_ALL_INBOXES) { if (mMailboxKey == QUERY_ALL_INBOXES) {
MailService.resetNewMessageCount(-1); MailService.resetNewMessageCount(MessageList.this, -1);
} else if (mMailboxKey >= 0 && mAccountKey != -1) { } else if (mMailboxKey >= 0 && mAccountKey != -1) {
MailService.resetNewMessageCount(mAccountKey); MailService.resetNewMessageCount(MessageList.this, mAccountKey);
} }
} }
} }

View File

@ -30,6 +30,7 @@ import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.Service; import android.app.Service;
import android.content.ContentUris; import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.database.Cursor; import android.database.Cursor;
@ -56,9 +57,12 @@ public class MailService extends Service {
"com.android.email.intent.action.MAIL_SERVICE_RESCHEDULE"; "com.android.email.intent.action.MAIL_SERVICE_RESCHEDULE";
private static final String ACTION_CANCEL = private static final String ACTION_CANCEL =
"com.android.email.intent.action.MAIL_SERVICE_CANCEL"; "com.android.email.intent.action.MAIL_SERVICE_CANCEL";
private static final String ACTION_NOTIFY_MAIL =
"com.android.email.intent.action.MAIL_SERVICE_NOTIFY";
private static final String EXTRA_CHECK_ACCOUNT = "com.android.email.intent.extra.ACCOUNT"; private static final String EXTRA_CHECK_ACCOUNT = "com.android.email.intent.extra.ACCOUNT";
private static final String EXTRA_ACCOUNT_INFO = "com.android.email.intent.extra.ACCOUNT_INFO"; private static final String EXTRA_ACCOUNT_INFO = "com.android.email.intent.extra.ACCOUNT_INFO";
private static final String EXTRA_MESSAGE_COUNT = "com.android.email.intent.extra.COUNT";
private Controller.Result mControllerCallback = new ControllerResults(); private Controller.Result mControllerCallback = new ControllerResults();
@ -70,6 +74,15 @@ public class MailService extends Service {
private static HashMap<Long,AccountSyncReport> mSyncReports = private static HashMap<Long,AccountSyncReport> mSyncReports =
new HashMap<Long,AccountSyncReport>(); new HashMap<Long,AccountSyncReport>();
/**
* Simple template used for clearing new message count in accounts
*/
static ContentValues mClearNewMessages;
static {
mClearNewMessages = new ContentValues();
mClearNewMessages.put(Account.NEW_MESSAGE_COUNT, 0);
}
public static void actionReschedule(Context context) { public static void actionReschedule(Context context) {
Intent i = new Intent(); Intent i = new Intent();
i.setClass(context, MailService.class); i.setClass(context, MailService.class);
@ -85,13 +98,12 @@ public class MailService extends Service {
} }
/** /**
* Reset new message counts for one or all accounts * Reset new message counts for one or all accounts. This clears both our local copy and
* * the values (if any) stored in the account records.
* TODO what about EAS service new message counts, where are they reset?
* *
* @param accountId account to clear, or -1 for all accounts * @param accountId account to clear, or -1 for all accounts
*/ */
public static void resetNewMessageCount(long accountId) { public static void resetNewMessageCount(Context context, long accountId) {
synchronized (mSyncReports) { synchronized (mSyncReports) {
for (AccountSyncReport report : mSyncReports.values()) { for (AccountSyncReport report : mSyncReports.values()) {
if (accountId == -1 || accountId == report.accountId) { if (accountId == -1 || accountId == report.accountId) {
@ -99,20 +111,30 @@ public class MailService extends Service {
} }
} }
} }
// now do the database - all accounts, or just one of them
Uri uri;
if (accountId == -1) {
uri = Account.CONTENT_URI;
} else {
uri = ContentUris.withAppendedId(Account.CONTENT_URI, accountId);
}
context.getContentResolver().update(uri, mClearNewMessages, null, null);
} }
/** /**
* Entry point for asynchronous message services (e.g. push mode) to post notifications of new * Entry point for asynchronous message services (e.g. push mode) to post notifications of new
* messages. Note: Although this is not a blocking call, it will start the MessagingController * messages. This assumes that the push provider has already synced the messages into the
* which will attempt to load the new messages. So the Store should expect to be opened and * appropriate database - this simply triggers the notification mechanism.
* fetched from shortly after making this call.
* *
* @param context a context
* @param accountId the id of the account that is reporting new messages * @param accountId the id of the account that is reporting new messages
* @param newCount the number of new messages
*/ */
public static void actionNotifyNewMessages(Context context, long accountId) { public static void actionNotifyNewMessages(Context context, long accountId, int newCount) {
Intent i = new Intent(ACTION_CHECK_MAIL); Intent i = new Intent(ACTION_NOTIFY_MAIL);
i.setClass(context, MailService.class); i.setClass(context, MailService.class);
i.putExtra(EXTRA_CHECK_ACCOUNT, accountId); i.putExtra(EXTRA_CHECK_ACCOUNT, accountId);
i.putExtra(EXTRA_MESSAGE_COUNT, newCount);
context.startService(i); context.startService(i);
} }
@ -122,11 +144,12 @@ public class MailService extends Service {
// TODO this needs to be passed through the controller and back to us // TODO this needs to be passed through the controller and back to us
this.mStartId = startId; this.mStartId = startId;
String action = intent.getAction();
Controller controller = Controller.getInstance(getApplication()); Controller controller = Controller.getInstance(getApplication());
controller.addResultCallback(mControllerCallback); controller.addResultCallback(mControllerCallback);
if (ACTION_CHECK_MAIL.equals(intent.getAction())) { if (ACTION_CHECK_MAIL.equals(action)) {
if (Config.LOGD && Email.DEBUG) { if (Config.LOGD && Email.DEBUG) {
Log.d(Email.LOG_TAG, "*** MailService: checking mail"); Log.d(Email.LOG_TAG, "*** MailService: checking mail");
} }
@ -146,23 +169,36 @@ public class MailService extends Service {
stopSelf(startId); stopSelf(startId);
} }
} }
else if (ACTION_CANCEL.equals(intent.getAction())) { else if (ACTION_CANCEL.equals(action)) {
if (Config.LOGD && Email.DEBUG) { if (Config.LOGD && Email.DEBUG) {
Log.d(Email.LOG_TAG, "*** MailService: cancel"); Log.d(Email.LOG_TAG, "*** MailService: cancel");
} }
cancel(); cancel();
stopSelf(startId); stopSelf(startId);
} }
else if (ACTION_RESCHEDULE.equals(intent.getAction())) { else if (ACTION_RESCHEDULE.equals(action)) {
if (Config.LOGD && Email.DEBUG) { if (Config.LOGD && Email.DEBUG) {
Log.d(Email.LOG_TAG, "*** MailService: reschedule"); Log.d(Email.LOG_TAG, "*** MailService: reschedule");
} }
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE); AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
reschedule(alarmManager); reschedule(alarmManager);
stopSelf(startId); stopSelf(startId);
} else if (ACTION_NOTIFY_MAIL.equals(action)) {
long accountId = intent.getLongExtra(EXTRA_CHECK_ACCOUNT, -1);
int newMessageCount = intent.getIntExtra(EXTRA_MESSAGE_COUNT, -1);
if (Config.LOGD && Email.DEBUG) {
Log.d(Email.LOG_TAG, "*** MailService: notify accountId=" + Long.toString(accountId)
+ " count=" + newMessageCount);
}
if (accountId != -1) {
updateAccountReport(accountId, newMessageCount);
notifyNewMessages(accountId);
}
stopSelf(startId);
} }
} }
@Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
return null; return null;
} }
@ -273,6 +309,8 @@ public class MailService extends Service {
String displayName; // temporary, for debug logging String displayName; // temporary, for debug logging
@Override
public String toString() { public String toString() {
return displayName + ": prevSync=" + prevSyncTime + " nextSync=" + nextSyncTime return displayName + ": prevSync=" + prevSyncTime + " nextSync=" + nextSyncTime
+ " numNew=" + numNewMessages; + " numNew=" + numNewMessages;

View File

@ -22,11 +22,13 @@ import com.android.email.activity.MessageList;
import com.android.email.mail.Address; import com.android.email.mail.Address;
import com.android.email.provider.EmailContent; import com.android.email.provider.EmailContent;
import com.android.email.provider.EmailProvider; import com.android.email.provider.EmailProvider;
import com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.Attachment; import com.android.email.provider.EmailContent.Attachment;
import com.android.email.provider.EmailContent.Mailbox; import com.android.email.provider.EmailContent.Mailbox;
import com.android.email.provider.EmailContent.Message; import com.android.email.provider.EmailContent.Message;
import com.android.email.provider.EmailContent.MessageColumns; import com.android.email.provider.EmailContent.MessageColumns;
import com.android.email.provider.EmailContent.SyncColumns; import com.android.email.provider.EmailContent.SyncColumns;
import com.android.email.service.MailService;
import com.android.exchange.Eas; import com.android.exchange.Eas;
import com.android.exchange.EasSyncService; import com.android.exchange.EasSyncService;
@ -465,31 +467,29 @@ public class EmailSyncAdapter extends AbstractSyncAdapter {
} }
} }
// TODO Remove this temporary notification code // TODO: This should be implemented using an "add to unread messages" URI,
// and then it could be handled in the previous section as just another "op"
int totalNewCount = 0;
if (notifyCount > 0) { if (notifyCount > 0) {
NotificationManager notifMgr = Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, mAccount.mId);
(NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE); Cursor c = mContentResolver.query(uri,
Notification notif = new Notification(R.drawable.stat_notify_email_generic, new String[] { Account.NEW_MESSAGE_COUNT }, null, null, null);
mContext.getString(R.string.notification_new_title), try {
System.currentTimeMillis()); if (c.moveToNext()) {
Intent i = MessageList.actionHandleAccountIntent(mContext, mAccount.mId, -1, int oldCount = c.getInt(0);
Mailbox.TYPE_INBOX); ContentValues cv = new ContentValues();
PendingIntent pi = PendingIntent.getActivity(mContext, 0, i, 0); totalNewCount = oldCount + notifyCount;
notif.setLatestEventInfo(mContext, cv.put(Account.NEW_MESSAGE_COUNT, totalNewCount);
mContext.getString(R.string.notification_new_title), mContentResolver.update(uri, cv, null, null);
"You've got new mail!", pi); }
boolean vibrate = ((mAccount.getFlags() & EmailContent.Account.FLAGS_VIBRATE) != 0); } finally {
String ringtone = mAccount.getRingtone(); c.close();
notif.flags = Notification.FLAG_SHOW_LIGHTS;
notif.sound = TextUtils.isEmpty(ringtone) ? null : Uri.parse(ringtone);
notif.ledARGB = 0xFF00FF00;
notif.ledOnMS = 500;
notif.ledOffMS = 500;
if (vibrate) {
notif.defaults |= Notification.DEFAULT_VIBRATE;
} }
notifMgr.notify(1, notif); }
}
if (totalNewCount > 0) {
MailService.actionNotifyNewMessages(mContext, mAccount.mId, totalNewCount);
}
} }
} }