MessagingNotification.java revision b92b26763e49fd9cc34d382dee4d764ef163bde5
172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/* 272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2008 Esmertec AG. 372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * you may not use this file except in compliance with the License. 772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * You may obtain a copy of the License at 872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 1072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 1172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * See the License for the specific language governing permissions and 1572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * limitations under the License. 1672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 1772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 1872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpackage com.android.mms.transaction; 1972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 2072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND; 2172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF; 2272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 2372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.R; 2472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.ui.ComposeMessageActivity; 2572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.ui.ConversationList; 2672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.ui.MessagingPreferenceActivity; 2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.util.AddressUtils; 2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.util.ContactInfoCache; 2972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.util.DownloadManager; 3072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 3172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.EncodedStringValue; 3272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.PduHeaders; 3372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.PduPersister; 3472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.util.SqliteWrapper; 3572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 3672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.Notification; 3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.NotificationManager; 3872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.PendingIntent; 3972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentResolver; 4072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context; 4172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Intent; 4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.SharedPreferences; 4372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.Cursor; 4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.graphics.Typeface; 4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri; 4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.preference.PreferenceManager; 4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.provider.Telephony.Mms; 4872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.provider.Telephony.Sms; 4972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.provider.Telephony.Threads; 5072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.Spannable; 5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.SpannableString; 5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.TextUtils; 5372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.style.StyleSpan; 5472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log; 5572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 5672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.Comparator; 5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.SortedSet; 5872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.TreeSet; 5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 6072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/** 6172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * This class is used to update the notification indicator. It will check whether 6272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * there are unread messages. If yes, it would show the notification indicator, 6372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * otherwise, hide the indicator. 6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class MessagingNotification { 6672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final String NOTIFICATION_CLICK_RECEIVER = 6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project "com.android.mms.transaction.NotificationClickReceiver"; 6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String TAG = "MessagingNotification"; 6972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int NOTIFICATION_ID = 123; 7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final int MESSAGE_FAILED_NOTIFICATION_ID = 789; 7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final int DOWNLOAD_FAILED_NOTIFICATION_ID = 531; 7372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // This must be consistent with the column constants below. 7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String[] MMS_STATUS_PROJECTION = new String[] { 7672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Mms.THREAD_ID, Mms.DATE, Mms._ID, Mms.SUBJECT, Mms.SUBJECT_CHARSET }; 7772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // This must be consistent with the column constants below. 7972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String[] SMS_STATUS_PROJECTION = new String[] { 8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.THREAD_ID, Sms.DATE, Sms.ADDRESS, Sms.SUBJECT, Sms.BODY }; 8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 8272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // These must be consistent with MMS_STATUS_PROJECTION and 8372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // SMS_STATUS_PROJECTION. 8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_THREAD_ID = 0; 8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_DATE = 1; 8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_MMS_ID = 2; 8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_SMS_ADDRESS = 2; 8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_SUBJECT = 3; 8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_SUBJECT_CS = 4; 9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_SMS_BODY = 4; 9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String NEW_INCOMING_SM_CONSTRAINT = 9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project "(" + Sms.TYPE + " = " + Sms.MESSAGE_TYPE_INBOX 9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + " AND " + Sms.READ + " = 0)"; 9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String NEW_INCOMING_MM_CONSTRAINT = 9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project "(" + Mms.MESSAGE_BOX + "=" + Mms.MESSAGE_BOX_INBOX 9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + " AND " + Mms.READ + "=0" 9972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + " AND (" + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_NOTIFICATION_IND 10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + " OR " + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_RETRIEVE_CONF + "))"; 10172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 10272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final MmsSmsNotificationInfoComparator INFO_COMPARATOR = 10372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project new MmsSmsNotificationInfoComparator(); 10472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 10572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final Uri UNDELIVERED_URI = Uri.parse("content://mms-sms/undelivered"); 10672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 10772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private MessagingNotification() { 10872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 10972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 11072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 11172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Checks to see if there are any unread messages or delivery 11272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * reports. Shows the most recent notification if there is one. 11372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 11472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @param context the context to use 11572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static void updateNewMessageIndicator(Context context) { 11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project updateNewMessageIndicator(context, false); 11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Checks to see if there are any unread messages or delivery 12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * reports. Shows the most recent notification if there is one. 12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @param context the context to use 12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @param isNew if notify a new message comes, it should be true, otherwise, false. 12672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static void updateNewMessageIndicator(Context context, boolean isNew) { 12872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SortedSet<MmsSmsNotificationInfo> accumulator = 12972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project new TreeSet<MmsSmsNotificationInfo>(INFO_COMPARATOR); 13072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 13172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int count = 0; 13272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project count += accumulateNotificationInfo( 13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project accumulator, getMmsNewMessageNotificationInfo(context)); 13472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project count += accumulateNotificationInfo( 13572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project accumulator, getSmsNewMessageNotificationInfo(context)); 13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 13772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cancelNotification(context, NOTIFICATION_ID); 13872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!accumulator.isEmpty()) { 13972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project accumulator.first().deliver(context, isNew, count); 14072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 14172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 14272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 14435a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick * Updates all pending notifications, clearing or updating them as 14535a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick * necessary. This task is completed in the background on a worker 14635a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick * thread. 14735a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick */ 14835a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick public static void updateAllNotifications(final Context context) { 14935a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick new Thread(new Runnable() { 15035a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick public void run() { 15135a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick updateNewMessageIndicator(context); 15235a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick updateSendFailedNotification(context); 15335a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick updateDownloadFailedNotification(context); 15435a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick } 15535a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick }).start(); 15635a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick } 15735a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick 15835a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick /** 15972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Deletes any delivery report notifications for the specified 16072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * thread, then checks to see if there are any unread messages or 16172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * delivery reports. Shows the most recent notification if there 16272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * is one. 16372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 16472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @param context the context to use 16572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @param threadId the thread for which to clear delivery notifications 16672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 16772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static void updateNewMessageIndicator( 16872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Context context, long threadId) { 16972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project updateNewMessageIndicator(context); 17072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 17172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 17272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int accumulateNotificationInfo( 17372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SortedSet set, MmsSmsNotificationInfo info) { 17472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (info != null) { 17572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project set.add(info); 17672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 17772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return info.mCount; 17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 18072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return 0; 18172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 18272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 18372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final class MmsSmsNotificationInfo { 18472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public Intent mClickIntent; 18572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public String mDescription; 18672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public int mIconResourceId; 18772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public CharSequence mTicker; 18872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public long mTimeMillis; 18972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public String mTitle; 19072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public int mCount; 19172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 19272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public MmsSmsNotificationInfo( 19372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent clickIntent, String description, int iconResourceId, 19472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project CharSequence ticker, long timeMillis, String title, int count) { 19572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mClickIntent = clickIntent; 19672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mDescription = description; 19772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mIconResourceId = iconResourceId; 19872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mTicker = ticker; 19972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mTimeMillis = timeMillis; 20072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mTitle = title; 20172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mCount = count; 20272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 20372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 20472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void deliver(Context context, boolean isNew, int count) { 20572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project updateNotification( 20672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context, mClickIntent, mDescription, mIconResourceId, 20772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project isNew, mTicker, mTimeMillis, mTitle, count); 20872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 20972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 21072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public long getTime() { 21172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return mTimeMillis; 21272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 21372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 21472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 21572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final class MmsSmsNotificationInfoComparator 21672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project implements Comparator<MmsSmsNotificationInfo> { 21772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public int compare( 21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project MmsSmsNotificationInfo info1, MmsSmsNotificationInfo info2) { 21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return Long.signum(info2.getTime() - info1.getTime()); 22072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 22172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 22272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final MmsSmsNotificationInfo getMmsNewMessageNotificationInfo( 22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Context context) { 22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContentResolver resolver = context.getContentResolver(); 22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor cursor = SqliteWrapper.query(context, resolver, Mms.CONTENT_URI, 22772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project MMS_STATUS_PROJECTION, NEW_INCOMING_MM_CONSTRAINT, 22872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project null, Mms.DATE + " desc"); 22972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 23072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (cursor != null) { 23172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 23272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (cursor.moveToFirst()) { 23372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long msgId = cursor.getLong(COLUMN_MMS_ID); 23472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Uri msgUri = Mms.CONTENT_URI.buildUpon().appendPath( 23572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Long.toString(msgId)).build(); 23672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String address = AddressUtils.getFrom(context, msgUri); 23772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String subject = getMmsSubject( 23872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cursor.getString(COLUMN_SUBJECT), cursor.getInt(COLUMN_SUBJECT_CS)); 23972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long threadId = cursor.getLong(COLUMN_THREAD_ID); 24072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long timeMillis = cursor.getLong(COLUMN_DATE) * 1000; 24172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 24272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return getNewMessageNotificationInfo( 24372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project address, subject, context, 24472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project R.drawable.stat_notify_mms, null, threadId, 24572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project timeMillis, cursor.getCount()); 24672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 24772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 24872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cursor.close(); 24972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 25072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 25172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return null; 25272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 25372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 25472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final MmsSmsNotificationInfo getSmsNewMessageNotificationInfo( 25572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Context context) { 25672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContentResolver resolver = context.getContentResolver(); 25772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor cursor = SqliteWrapper.query(context, resolver, Sms.CONTENT_URI, 25872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SMS_STATUS_PROJECTION, NEW_INCOMING_SM_CONSTRAINT, 25972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project null, Sms.DATE + " desc"); 26072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 26172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (cursor != null) { 26272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 26372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (cursor.moveToFirst()) { 26472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String address = cursor.getString(COLUMN_SMS_ADDRESS); 26572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String body = cursor.getString(COLUMN_SMS_BODY); 26672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long threadId = cursor.getLong(COLUMN_THREAD_ID); 26772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long timeMillis = cursor.getLong(COLUMN_DATE); 26872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 26972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return getNewMessageNotificationInfo( 27072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project address, body, context, R.drawable.stat_notify_sms, 27172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project null, threadId, timeMillis, cursor.getCount()); 27272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 27372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 27472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cursor.close(); 27572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 27672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 27772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return null; 27872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 27972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 28072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final MmsSmsNotificationInfo getNewMessageNotificationInfo( 28172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String address, 28272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String body, 28372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Context context, 28472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int iconResourceId, 28572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String subject, 28672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long threadId, 28772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long timeMillis, 28872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int count) { 28972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent clickIntent = getAppIntent(); 29072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project clickIntent.setData( 29172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Uri.withAppendedPath( 29272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project clickIntent.getData(), Long.toString(threadId))); 29372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project clickIntent.setAction(Intent.ACTION_VIEW); 29472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 29572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String senderInfo = buildTickerMessage( 29672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context, address, null, null).toString(); 29772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String senderInfoName = senderInfo.substring( 29872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 0, senderInfo.length() - 2); 29972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project CharSequence ticker = buildTickerMessage( 30072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context, address, subject, body); 30172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 30272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return new MmsSmsNotificationInfo( 30372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project clickIntent, body, iconResourceId, ticker, timeMillis, 30472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project senderInfoName, count); 30572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 30672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 30772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static void cancelNotification(Context context, int notificationId) { 30872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project NotificationManager nm = (NotificationManager) context.getSystemService( 30972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Context.NOTIFICATION_SERVICE); 31072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 31172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project nm.cancel(notificationId); 31272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 31372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 31472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static Intent getAppIntent() { 31572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent appIntent = new Intent(Intent.ACTION_MAIN, Threads.CONTENT_URI); 31672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 317b92b26763e49fd9cc34d382dee4d764ef163bde5Ficus Kirkpatrick appIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); 31872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return appIntent; 31972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 32072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 32172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static void updateNotification( 32272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Context context, 32372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent clickIntent, 32472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String description, 32572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int iconRes, 32672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project boolean isNew, 32772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project CharSequence ticker, 32872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long timeMillis, 32972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String title, 33072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int count) { 33172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); 33272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 33372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!sp.getBoolean( 33472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project MessagingPreferenceActivity.NOTIFICATION_ENABLED, true)) { 33572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 33672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 33772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 33872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Notification notification = new Notification( 33972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project iconRes, ticker, timeMillis); 34072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PendingIntent pendingIntent; 34172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 34272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (count > 1) { 34372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String multiDescription = context.getString(R.string.notification_multiple, 34472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Integer.toString(count)); 34572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String multiTitle = context.getString(R.string.notification_multiple_title); 34672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 34772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent multiIntent = getAppIntent(); 34872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project multiIntent.setAction(Intent.ACTION_MAIN); 34972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project multiIntent.setType("vnd.android-dir/mms-sms"); 35072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project pendingIntent = 35172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PendingIntent.getActivity(context, 0, multiIntent, 0); 35272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 35372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.setLatestEventInfo(context, multiTitle, multiDescription, pendingIntent); 35472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 35572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project pendingIntent = 35672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PendingIntent.getActivity(context, 0, clickIntent, 0); 35772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 35872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.setLatestEventInfo( 35972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context, title, description, pendingIntent); 36072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 36172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 36272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isNew) { 36372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project boolean vibrate = sp.getBoolean(MessagingPreferenceActivity.NOTIFICATION_VIBRATE, true); 36472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (vibrate) { 36572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.defaults |= Notification.DEFAULT_VIBRATE; 36672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 36772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 36872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String ringtoneStr = sp 36972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project .getString(MessagingPreferenceActivity.NOTIFICATION_RINGTONE, null); 37072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.sound = TextUtils.isEmpty(ringtoneStr) ? null : Uri.parse(ringtoneStr); 37172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 37272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 37372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.flags |= Notification.FLAG_SHOW_LIGHTS; 37472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.ledARGB = 0xff00ff00; 37572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.ledOnMS = 500; 37672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.ledOffMS = 2000; 37772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 37872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project NotificationManager nm = (NotificationManager) 37972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context.getSystemService(Context.NOTIFICATION_SERVICE); 38072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 38172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project nm.notify(NOTIFICATION_ID, notification); 38272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 38372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 38472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected static CharSequence buildTickerMessage( 38572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Context context, String address, String subject, String body) { 38672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String displayAddress = ContactInfoCache.getInstance() 38772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project .getContactName(context, address); 38872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 38972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project StringBuilder buf = new StringBuilder( 39072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project displayAddress == null 39172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ? "" 39272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project : displayAddress.replace('\n', ' ').replace('\r', ' ')); 39372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project buf.append(':').append(' '); 39472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 39572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int offset = buf.length(); 39672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!TextUtils.isEmpty(subject)) { 39772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project subject = subject.replace('\n', ' ').replace('\r', ' '); 39872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project buf.append(subject); 39972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project buf.append(' '); 40072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 40172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 40272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!TextUtils.isEmpty(body)) { 40372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project body = body.replace('\n', ' ').replace('\r', ' '); 40472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project buf.append(body); 40572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 40672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 40772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SpannableString spanText = new SpannableString(buf.toString()); 40872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project spanText.setSpan(new StyleSpan(Typeface.BOLD), 0, offset, 40972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 41072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 41172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return spanText; 41272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 41372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 41472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static String getMmsSubject(String sub, int charset) { 41572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return TextUtils.isEmpty(sub) ? "" 41672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project : new EncodedStringValue(charset, PduPersister.getBytes(sub)).getString(); 41772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 41872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 41972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static void notifyDownloadFailed(Context context, long threadId) { 420b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick notifyFailed(context, true, threadId, false); 42172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 42272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 4235d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project public static void notifySendFailed(Context context) { 424b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick notifyFailed(context, false, 0, false); 42572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 42672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 427b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick public static void notifySendFailed(Context context, boolean noisy) { 428b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick notifyFailed(context, false, 0, noisy); 429b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick } 430b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick 431b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick private static void notifyFailed(Context context, boolean isDownload, long threadId, 432b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick boolean noisy) { 43372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO factor out common code for creating notifications 43472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); 43572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 43672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project boolean enabled = sp.getBoolean(MessagingPreferenceActivity.NOTIFICATION_ENABLED, true); 43772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!enabled) { 43872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 43972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 44072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 44172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project NotificationManager nm = (NotificationManager) 44272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context.getSystemService(Context.NOTIFICATION_SERVICE); 44372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 44472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Strategy: 44572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // a. If there is a single failure notification, tapping on the notification goes 44672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // to the compose view. 44772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // b. If there are two failure it stays in the thread view. Selecting one undelivered 44872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // thread will dismiss one undelivered notification but will still display the 44972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // notification.If you select the 2nd undelivered one it will dismiss the notification. 45072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 4512f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project long[] msgThreadId = {0}; 45272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int totalFailedCount = getUndeliveredMessageCount(context, msgThreadId); 45372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 45472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent failedIntent; 45572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Notification notification = new Notification(); 45672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String title; 45772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String description; 45872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (totalFailedCount > 1) { 45972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project description = context.getString(R.string.notification_failed_multiple, 46072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Integer.toString(totalFailedCount)); 46172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project title = context.getString(R.string.notification_failed_multiple_title); 46272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 46372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project failedIntent = new Intent(context, ConversationList.class); 46472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 46572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project title = isDownload ? 46672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context.getString(R.string.message_download_failed_title) : 46772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context.getString(R.string.message_send_failed_title); 46872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 46972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project description = context.getString(R.string.message_failed_body); 47072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project threadId = (msgThreadId[0] != 0 ? msgThreadId[0] : 0); 471836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project 472836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project failedIntent = new Intent(context, ComposeMessageActivity.class); 473836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project failedIntent.putExtra("thread_id", threadId); 474836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project failedIntent.putExtra("undelivered_flag", true); 47572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 47672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 477b92b26763e49fd9cc34d382dee4d764ef163bde5Ficus Kirkpatrick failedIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); 47872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PendingIntent pendingIntent = PendingIntent.getActivity( 47972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context, 0, failedIntent, 0); 48072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 48172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.icon = R.drawable.stat_notify_sms_failed; 48272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 48372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.tickerText = title; 48472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 48572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.setLatestEventInfo(context, title, description, pendingIntent); 48672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 487b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick if (noisy) { 488b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick boolean vibrate = sp.getBoolean(MessagingPreferenceActivity.NOTIFICATION_VIBRATE, true); 489b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick if (vibrate) { 490b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick notification.defaults |= Notification.DEFAULT_VIBRATE; 491b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick } 49272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 493b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick String ringtoneStr = sp.getString(MessagingPreferenceActivity.NOTIFICATION_RINGTONE, null); 494b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick notification.sound = TextUtils.isEmpty(ringtoneStr) ? null : Uri.parse(ringtoneStr); 495b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick } 496b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick 49772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isDownload) { 49872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project nm.notify(DOWNLOAD_FAILED_NOTIFICATION_ID, notification); 49972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 50072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project nm.notify(MESSAGE_FAILED_NOTIFICATION_ID, notification); 50172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 50272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 50372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 5042f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project // threadIdResult[0] contains the thread id of the first message. 5052f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project // threadIdResult[1] is nonzero if the thread ids of all the messages are the same. 5062f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project // You can pass in null for threadIdResult. 5072f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project // You can pass in a threadIdResult of size 1 to avoid the comparison of each thread id. 50872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static int getUndeliveredMessageCount(Context context, long[] threadIdResult) { 50972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor undeliveredCursor = SqliteWrapper.query(context, context.getContentResolver(), 51035a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick UNDELIVERED_URI, new String[] { Mms.THREAD_ID }, "read=0", null, null); 51172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (undeliveredCursor == null) { 51272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return 0; 51372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 51472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int count = undeliveredCursor.getCount(); 51572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 51672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (threadIdResult != null && undeliveredCursor.moveToFirst()) { 51772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project threadIdResult[0] = undeliveredCursor.getLong(0); 5182f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project 5192f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project if (threadIdResult.length >= 2) { 5202f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project // Test to see if all the undelivered messages belong to the same thread. 5212f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project long firstId = threadIdResult[0]; 5222f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project while (undeliveredCursor.moveToNext()) { 5232f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project if (undeliveredCursor.getLong(0) != firstId) { 5242f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project firstId = 0; 5252f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project break; 5262f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project } 5272f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project } 5282f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project threadIdResult[1] = firstId; // non-zero if all ids are the same 5292f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project } 53072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 53172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 53272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project undeliveredCursor.close(); 53372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 53472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return count; 53572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 53672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 53772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static void updateSendFailedNotification(Context context) { 53872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (getUndeliveredMessageCount(context, null) < 1) { 53972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cancelNotification(context, MESSAGE_FAILED_NOTIFICATION_ID); 5405d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project } else { 5415d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project notifySendFailed(context); // rebuild and adjust the message count if necessary. 54272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 54372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 54472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 5452f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project /** 5462f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project * If all the undelivered messages belong to "threadId", cancel the notification. 5472f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project */ 5482f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project public static void updateSendFailedNotificationForThread(Context context, long threadId) { 5492f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project long[] msgThreadId = {0, 0}; 5502f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project if (getUndeliveredMessageCount(context, msgThreadId) > 0 5512f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project && msgThreadId[0] == threadId 5522f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project && msgThreadId[1] != 0) { 5532f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project cancelNotification(context, MESSAGE_FAILED_NOTIFICATION_ID); 5542f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project } 5552f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project } 5562f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project 55772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static int getDownloadFailedMessageCount(Context context) { 55872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Look for any messages in the MMS Inbox that are of the type 55972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // NOTIFICATION_IND (i.e. not already downloaded) and in the 56072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // permanent failure state. If there are none, cancel any 56172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // failed download notification. 56272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor c = SqliteWrapper.query(context, context.getContentResolver(), 56372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Mms.Inbox.CONTENT_URI, null, 56472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Mms.MESSAGE_TYPE + "=" + 56572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String.valueOf(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) + 56672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project " AND " + Mms.STATUS + "=" + 56772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String.valueOf(DownloadManager.STATE_PERMANENT_FAILURE), 56872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project null, null); 56972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (c == null) { 57072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return 0; 57172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 57272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int count = c.getCount(); 57372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project c.close(); 57472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return count; 57572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 57672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 57772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static void updateDownloadFailedNotification(Context context) { 57872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (getDownloadFailedMessageCount(context) < 1) { 57972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cancelNotification(context, DOWNLOAD_FAILED_NOTIFICATION_ID); 58072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 58172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 58272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project} 583