MessagingNotificationpublic class MessagingNotification extends Object This class is used to update the notification indicator. It will check whether
there are unread messages. If yes, it would show the notification indicator,
otherwise, hide the indicator. |
Fields Summary |
---|
public static final String | NOTIFICATION_CLICK_RECEIVER | private static final String | TAG | private static final int | NOTIFICATION_ID | public static final int | MESSAGE_FAILED_NOTIFICATION_ID | public static final int | DOWNLOAD_FAILED_NOTIFICATION_ID | private static final String[] | MMS_STATUS_PROJECTION | private static final String[] | SMS_STATUS_PROJECTION | private static final int | COLUMN_THREAD_ID | private static final int | COLUMN_DATE | private static final int | COLUMN_MMS_ID | private static final int | COLUMN_SMS_ADDRESS | private static final int | COLUMN_SUBJECT | private static final int | COLUMN_SUBJECT_CS | private static final int | COLUMN_SMS_BODY | private static final String | NEW_INCOMING_SM_CONSTRAINT | private static final String | NEW_INCOMING_MM_CONSTRAINT | private static final MmsSmsNotificationInfoComparator | INFO_COMPARATOR | private static final android.net.Uri | UNDELIVERED_URI |
Constructors Summary |
---|
private MessagingNotification()
|
Methods Summary |
---|
private static final int | accumulateNotificationInfo(java.util.SortedSet set, com.android.mms.transaction.MessagingNotification$MmsSmsNotificationInfo info)
if (info != null) {
set.add(info);
return info.mCount;
}
return 0;
| protected static java.lang.CharSequence | buildTickerMessage(android.content.Context context, java.lang.String address, java.lang.String subject, java.lang.String body)
String displayAddress = ContactInfoCache.getInstance()
.getContactName(context, address);
StringBuilder buf = new StringBuilder(
displayAddress == null
? ""
: displayAddress.replace('\n", ' ").replace('\r", ' "));
buf.append(':").append(' ");
int offset = buf.length();
if (!TextUtils.isEmpty(subject)) {
subject = subject.replace('\n", ' ").replace('\r", ' ");
buf.append(subject);
buf.append(' ");
}
if (!TextUtils.isEmpty(body)) {
body = body.replace('\n", ' ").replace('\r", ' ");
buf.append(body);
}
SpannableString spanText = new SpannableString(buf.toString());
spanText.setSpan(new StyleSpan(Typeface.BOLD), 0, offset,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return spanText;
| public static void | cancelNotification(android.content.Context context, int notificationId)
NotificationManager nm = (NotificationManager) context.getSystemService(
Context.NOTIFICATION_SERVICE);
nm.cancel(notificationId);
| private static android.content.Intent | getAppIntent()
Intent appIntent = new Intent(Intent.ACTION_MAIN, Threads.CONTENT_URI);
appIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
return appIntent;
| private static int | getDownloadFailedMessageCount(android.content.Context context)
// Look for any messages in the MMS Inbox that are of the type
// NOTIFICATION_IND (i.e. not already downloaded) and in the
// permanent failure state. If there are none, cancel any
// failed download notification.
Cursor c = SqliteWrapper.query(context, context.getContentResolver(),
Mms.Inbox.CONTENT_URI, null,
Mms.MESSAGE_TYPE + "=" +
String.valueOf(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) +
" AND " + Mms.STATUS + "=" +
String.valueOf(DownloadManager.STATE_PERMANENT_FAILURE),
null, null);
if (c == null) {
return 0;
}
int count = c.getCount();
c.close();
return count;
| public static final com.android.mms.transaction.MessagingNotification$MmsSmsNotificationInfo | getMmsNewMessageNotificationInfo(android.content.Context context, java.util.Set threads)
ContentResolver resolver = context.getContentResolver();
Cursor cursor = SqliteWrapper.query(context, resolver, Mms.CONTENT_URI,
MMS_STATUS_PROJECTION, NEW_INCOMING_MM_CONSTRAINT,
null, Mms.DATE + " desc");
if (cursor == null) {
return null;
}
try {
if (!cursor.moveToFirst()) {
return null;
}
long msgId = cursor.getLong(COLUMN_MMS_ID);
Uri msgUri = Mms.CONTENT_URI.buildUpon().appendPath(
Long.toString(msgId)).build();
String address = AddressUtils.getFrom(context, msgUri);
String subject = getMmsSubject(
cursor.getString(COLUMN_SUBJECT), cursor.getInt(COLUMN_SUBJECT_CS));
long threadId = cursor.getLong(COLUMN_THREAD_ID);
long timeMillis = cursor.getLong(COLUMN_DATE) * 1000;
MmsSmsNotificationInfo info = getNewMessageNotificationInfo(
address, subject, context,
R.drawable.stat_notify_mms, null, threadId,
timeMillis, cursor.getCount());
threads.add(threadId);
while (cursor.moveToNext()) {
threads.add(cursor.getLong(COLUMN_THREAD_ID));
}
return info;
} finally {
cursor.close();
}
| private static java.lang.String | getMmsSubject(java.lang.String sub, int charset)
return TextUtils.isEmpty(sub) ? ""
: new EncodedStringValue(charset, PduPersister.getBytes(sub)).getString();
| private static final com.android.mms.transaction.MessagingNotification$MmsSmsNotificationInfo | getNewMessageNotificationInfo(java.lang.String address, java.lang.String body, android.content.Context context, int iconResourceId, java.lang.String subject, long threadId, long timeMillis, int count)
Intent clickIntent = getAppIntent();
clickIntent.setData(
Uri.withAppendedPath(
clickIntent.getData(), Long.toString(threadId)));
clickIntent.setAction(Intent.ACTION_VIEW);
String senderInfo = buildTickerMessage(
context, address, null, null).toString();
String senderInfoName = senderInfo.substring(
0, senderInfo.length() - 2);
CharSequence ticker = buildTickerMessage(
context, address, subject, body);
return new MmsSmsNotificationInfo(
clickIntent, body, iconResourceId, ticker, timeMillis,
senderInfoName, count);
| public static final com.android.mms.transaction.MessagingNotification$MmsSmsNotificationInfo | getSmsNewMessageNotificationInfo(android.content.Context context, java.util.Set threads)
ContentResolver resolver = context.getContentResolver();
Cursor cursor = SqliteWrapper.query(context, resolver, Sms.CONTENT_URI,
SMS_STATUS_PROJECTION, NEW_INCOMING_SM_CONSTRAINT,
null, Sms.DATE + " desc");
if (cursor == null) {
return null;
}
try {
if (!cursor.moveToFirst()) {
return null;
}
String address = cursor.getString(COLUMN_SMS_ADDRESS);
String body = cursor.getString(COLUMN_SMS_BODY);
long threadId = cursor.getLong(COLUMN_THREAD_ID);
long timeMillis = cursor.getLong(COLUMN_DATE);
MmsSmsNotificationInfo info = getNewMessageNotificationInfo(
address, body, context, R.drawable.stat_notify_sms,
null, threadId, timeMillis, cursor.getCount());
threads.add(threadId);
while (cursor.moveToNext()) {
threads.add(cursor.getLong(COLUMN_THREAD_ID));
}
return info;
} finally {
cursor.close();
}
| private static int | getUndeliveredMessageCount(android.content.Context context, long[] threadIdResult)
Cursor undeliveredCursor = SqliteWrapper.query(context, context.getContentResolver(),
UNDELIVERED_URI, new String[] { Mms.THREAD_ID }, "read=0", null, null);
if (undeliveredCursor == null) {
return 0;
}
int count = undeliveredCursor.getCount();
try {
if (threadIdResult != null && undeliveredCursor.moveToFirst()) {
threadIdResult[0] = undeliveredCursor.getLong(0);
if (threadIdResult.length >= 2) {
// Test to see if all the undelivered messages belong to the same thread.
long firstId = threadIdResult[0];
while (undeliveredCursor.moveToNext()) {
if (undeliveredCursor.getLong(0) != firstId) {
firstId = 0;
break;
}
}
threadIdResult[1] = firstId; // non-zero if all ids are the same
}
}
} finally {
undeliveredCursor.close();
}
return count;
| public static void | notifyDownloadFailed(android.content.Context context, long threadId)
notifyFailed(context, true, threadId, false);
| private static void | notifyFailed(android.content.Context context, boolean isDownload, long threadId, boolean noisy)
// TODO factor out common code for creating notifications
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
boolean enabled = sp.getBoolean(MessagingPreferenceActivity.NOTIFICATION_ENABLED, true);
if (!enabled) {
return;
}
NotificationManager nm = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
// Strategy:
// a. If there is a single failure notification, tapping on the notification goes
// to the compose view.
// b. If there are two failure it stays in the thread view. Selecting one undelivered
// thread will dismiss one undelivered notification but will still display the
// notification.If you select the 2nd undelivered one it will dismiss the notification.
long[] msgThreadId = {0};
int totalFailedCount = getUndeliveredMessageCount(context, msgThreadId);
Intent failedIntent;
Notification notification = new Notification();
String title;
String description;
if (totalFailedCount > 1) {
description = context.getString(R.string.notification_failed_multiple,
Integer.toString(totalFailedCount));
title = context.getString(R.string.notification_failed_multiple_title);
failedIntent = new Intent(context, ConversationList.class);
} else {
title = isDownload ?
context.getString(R.string.message_download_failed_title) :
context.getString(R.string.message_send_failed_title);
description = context.getString(R.string.message_failed_body);
threadId = (msgThreadId[0] != 0 ? msgThreadId[0] : 0);
failedIntent = new Intent(context, ComposeMessageActivity.class);
failedIntent.putExtra("thread_id", threadId);
failedIntent.putExtra("undelivered_flag", true);
}
failedIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(
context, 0, failedIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.icon = R.drawable.stat_notify_sms_failed;
notification.tickerText = title;
notification.setLatestEventInfo(context, title, description, pendingIntent);
if (noisy) {
boolean vibrate = sp.getBoolean(MessagingPreferenceActivity.NOTIFICATION_VIBRATE, true);
if (vibrate) {
notification.defaults |= Notification.DEFAULT_VIBRATE;
}
String ringtoneStr = sp.getString(MessagingPreferenceActivity.NOTIFICATION_RINGTONE, null);
notification.sound = TextUtils.isEmpty(ringtoneStr) ? null : Uri.parse(ringtoneStr);
}
if (isDownload) {
nm.notify(DOWNLOAD_FAILED_NOTIFICATION_ID, notification);
} else {
nm.notify(MESSAGE_FAILED_NOTIFICATION_ID, notification);
}
| public static void | notifySendFailed(android.content.Context context)
notifyFailed(context, false, 0, false);
| public static void | notifySendFailed(android.content.Context context, boolean noisy)
notifyFailed(context, false, 0, noisy);
| public static void | updateAllNotifications(android.content.Context context)Updates all pending notifications, clearing or updating them as
necessary. This task is completed in the background on a worker
thread.
new Thread(new Runnable() {
public void run() {
updateNewMessageIndicator(context);
updateSendFailedNotification(context);
updateDownloadFailedNotification(context);
}
}).start();
| public static void | updateDownloadFailedNotification(android.content.Context context)
if (getDownloadFailedMessageCount(context) < 1) {
cancelNotification(context, DOWNLOAD_FAILED_NOTIFICATION_ID);
}
| public static void | updateNewMessageIndicator(android.content.Context context)Checks to see if there are any unread messages or delivery
reports. Shows the most recent notification if there is one.
updateNewMessageIndicator(context, false);
| public static void | updateNewMessageIndicator(android.content.Context context, boolean isNew)Checks to see if there are any unread messages or delivery
reports. Shows the most recent notification if there is one.
SortedSet<MmsSmsNotificationInfo> accumulator =
new TreeSet<MmsSmsNotificationInfo>(INFO_COMPARATOR);
Set<Long> threads = new HashSet<Long>(4);
int count = 0;
count += accumulateNotificationInfo(
accumulator, getMmsNewMessageNotificationInfo(context, threads));
count += accumulateNotificationInfo(
accumulator, getSmsNewMessageNotificationInfo(context, threads));
cancelNotification(context, NOTIFICATION_ID);
if (!accumulator.isEmpty()) {
accumulator.first().deliver(context, isNew, count, threads.size());
}
| public static void | updateNewMessageIndicator(android.content.Context context, long threadId)Deletes any delivery report notifications for the specified
thread, then checks to see if there are any unread messages or
delivery reports. Shows the most recent notification if there
is one.
updateNewMessageIndicator(context);
| private static void | updateNotification(android.content.Context context, android.content.Intent clickIntent, java.lang.String description, int iconRes, boolean isNew, java.lang.CharSequence ticker, long timeMillis, java.lang.String title, int messageCount, int uniqueThreadCount)
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
if (!sp.getBoolean(
MessagingPreferenceActivity.NOTIFICATION_ENABLED, true)) {
return;
}
Notification notification = new Notification(iconRes, ticker, timeMillis);
// If we have more than one unique thread, change the title (which would
// normally be the contact who sent the message) to a generic one that
// makes sense for multiple senders, and change the Intent to take the
// user to the conversation list instead of the specific thread.
if (uniqueThreadCount > 1) {
title = context.getString(R.string.notification_multiple_title);
clickIntent = getAppIntent();
clickIntent.setAction(Intent.ACTION_MAIN);
clickIntent.setType("vnd.android-dir/mms-sms");
}
// If there is more than one message, change the description (which
// would normally be a snippet of the individual message text) to
// a string indicating how many unread messages there are.
if (messageCount > 1) {
description = context.getString(R.string.notification_multiple,
Integer.toString(messageCount));
}
// Make a startActivity() PendingIntent for the notification.
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, clickIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
// Update the notification.
notification.setLatestEventInfo(context, title, description, pendingIntent);
if (isNew) {
boolean vibrate = sp.getBoolean(MessagingPreferenceActivity.NOTIFICATION_VIBRATE, true);
if (vibrate) {
notification.defaults |= Notification.DEFAULT_VIBRATE;
}
String ringtoneStr = sp
.getString(MessagingPreferenceActivity.NOTIFICATION_RINGTONE, null);
notification.sound = TextUtils.isEmpty(ringtoneStr) ? null : Uri.parse(ringtoneStr);
}
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
notification.ledARGB = 0xff00ff00;
notification.ledOnMS = 500;
notification.ledOffMS = 2000;
NotificationManager nm = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(NOTIFICATION_ID, notification);
| public static void | updateSendFailedNotification(android.content.Context context)
if (getUndeliveredMessageCount(context, null) < 1) {
cancelNotification(context, MESSAGE_FAILED_NOTIFICATION_ID);
} else {
notifySendFailed(context); // rebuild and adjust the message count if necessary.
}
| public static void | updateSendFailedNotificationForThread(android.content.Context context, long threadId)If all the undelivered messages belong to "threadId", cancel the notification.
long[] msgThreadId = {0, 0};
if (getUndeliveredMessageCount(context, msgThreadId) > 0
&& msgThreadId[0] == threadId
&& msgThreadId[1] != 0) {
cancelNotification(context, MESSAGE_FAILED_NOTIFICATION_ID);
}
|
|