MessagingNotification.java revision 2d65e7eb956e60c058de876ddbfff504620ce7a3
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 20f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND; 21f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF; 2272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 23d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.util.ArrayList; 24d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.util.Comparator; 25d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.util.HashSet; 26d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.util.Iterator; 27d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.util.Set; 28d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.util.SortedSet; 29d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.util.TreeSet; 3072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 3172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.Notification; 3272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.NotificationManager; 3372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.PendingIntent; 346cc254afc74dee97c7ef356612ae9ec7bc8b77ceTom Taylorimport android.app.TaskStackBuilder; 35d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.content.BroadcastReceiver; 3672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentResolver; 3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context; 3872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Intent; 3970f5af8fd89d66ae246a805d10a50540746319aaWei Huangimport android.content.IntentFilter; 40d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.content.SharedPreferences; 41ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylorimport android.content.res.Resources; 4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.Cursor; 43d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.database.sqlite.SqliteWrapper; 44429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylorimport android.graphics.Bitmap; 4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.graphics.Typeface; 46429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylorimport android.graphics.drawable.BitmapDrawable; 47006d49271549ed639ffcd70d94c7650bb3514796Jim Shumaimport android.media.AudioManager; 4872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri; 49b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylorimport android.os.AsyncTask; 505a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylorimport android.os.Handler; 5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.preference.PreferenceManager; 52f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Mms; 53f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Sms; 5472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.Spannable; 5572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.SpannableString; 56429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylorimport android.text.SpannableStringBuilder; 5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.TextUtils; 5872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.style.StyleSpan; 59ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylorimport android.text.style.TextAppearanceSpan; 6072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log; 61800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERTimport android.widget.Toast; 6272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 63d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.LogTag; 64d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.R; 65d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.data.Contact; 66d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.data.Conversation; 67d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.data.WorkingMessage; 68d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.model.SlideModel; 69d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.model.SlideshowModel; 70d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.ui.ComposeMessageActivity; 71d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.ui.ConversationList; 723c307cabb5bd96ed174930ebf17f533bf2a79de7Tom Taylorimport com.android.mms.ui.MessageUtils; 73d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.ui.MessagingPreferenceActivity; 74d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.util.AddressUtils; 75d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.util.DownloadManager; 76d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.widget.MmsWidgetProvider; 77d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.MmsException; 78d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.pdu.EncodedStringValue; 79d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.pdu.GenericPdu; 80d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.pdu.MultimediaMessagePdu; 81d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.pdu.PduHeaders; 82d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.pdu.PduPersister; 8372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/** 8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * This class is used to update the notification indicator. It will check whether 8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * there are unread messages. If yes, it would show the notification indicator, 8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * otherwise, hide the indicator. 8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class MessagingNotification { 90c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 91812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang private static final String TAG = LogTag.APP; 926d2ba55a4bd1937bbec101ab2a4c005b566b43f8Tom Taylor private static final boolean DEBUG = true; // TODO turn off before ship 9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int NOTIFICATION_ID = 123; 9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final int MESSAGE_FAILED_NOTIFICATION_ID = 789; 9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final int DOWNLOAD_FAILED_NOTIFICATION_ID = 531; 97c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev /** 98c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * This is the volume at which to play the in-conversation notification sound, 99c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * expressed as a fraction of the system notification volume. 100c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev */ 101c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev private static final float IN_CONVERSATION_NOTIFICATION_VOLUME = 0.25f; 10272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 10372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // This must be consistent with the column constants below. 10472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String[] MMS_STATUS_PROJECTION = new String[] { 10572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Mms.THREAD_ID, Mms.DATE, Mms._ID, Mms.SUBJECT, Mms.SUBJECT_CHARSET }; 10672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 10772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // This must be consistent with the column constants below. 10872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String[] SMS_STATUS_PROJECTION = new String[] { 10972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.THREAD_ID, Sms.DATE, Sms.ADDRESS, Sms.SUBJECT, Sms.BODY }; 11072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 11172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // These must be consistent with MMS_STATUS_PROJECTION and 11272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // SMS_STATUS_PROJECTION. 11372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_THREAD_ID = 0; 11472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_DATE = 1; 11572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_MMS_ID = 2; 11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_SMS_ADDRESS = 2; 11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_SUBJECT = 3; 11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_SUBJECT_CS = 4; 11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_SMS_BODY = 4; 12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 121c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev private static final String[] SMS_THREAD_ID_PROJECTION = new String[] { Sms.THREAD_ID }; 122c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev private static final String[] MMS_THREAD_ID_PROJECTION = new String[] { Mms.THREAD_ID }; 123c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String NEW_INCOMING_SM_CONSTRAINT = 12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project "(" + Sms.TYPE + " = " + Sms.MESSAGE_TYPE_INBOX 126627007213deb59ef938c80353c8f3598b01478b3Wei Huang + " AND " + Sms.SEEN + " = 0)"; 12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 128800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT private static final String NEW_DELIVERY_SM_CONSTRAINT = 129c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor "(" + Sms.TYPE + " = " + Sms.MESSAGE_TYPE_SENT 130c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor + " AND " + Sms.STATUS + " = "+ Sms.STATUS_COMPLETE +")"; 131800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 13272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String NEW_INCOMING_MM_CONSTRAINT = 13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project "(" + Mms.MESSAGE_BOX + "=" + Mms.MESSAGE_BOX_INBOX 134627007213deb59ef938c80353c8f3598b01478b3Wei Huang + " AND " + Mms.SEEN + "=0" 13572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + " AND (" + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_NOTIFICATION_IND 13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + " OR " + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_RETRIEVE_CONF + "))"; 13772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 138429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor private static final NotificationInfoComparator INFO_COMPARATOR = 139429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor new NotificationInfoComparator(); 1405a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 14172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final Uri UNDELIVERED_URI = Uri.parse("content://mms-sms/undelivered"); 14272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 14370f5af8fd89d66ae246a805d10a50540746319aaWei Huang 14470f5af8fd89d66ae246a805d10a50540746319aaWei Huang private final static String NOTIFICATION_DELETED_ACTION = 14570f5af8fd89d66ae246a805d10a50540746319aaWei Huang "com.android.mms.NOTIFICATION_DELETED_ACTION"; 14670f5af8fd89d66ae246a805d10a50540746319aaWei Huang 14770f5af8fd89d66ae246a805d10a50540746319aaWei Huang public static class OnDeletedReceiver extends BroadcastReceiver { 148c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev @Override 14970f5af8fd89d66ae246a805d10a50540746319aaWei Huang public void onReceive(Context context, Intent intent) { 15070f5af8fd89d66ae246a805d10a50540746319aaWei Huang if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) { 15170f5af8fd89d66ae246a805d10a50540746319aaWei Huang Log.d(TAG, "[MessagingNotification] clear notification: mark all msgs seen"); 15270f5af8fd89d66ae246a805d10a50540746319aaWei Huang } 15370f5af8fd89d66ae246a805d10a50540746319aaWei Huang 15470f5af8fd89d66ae246a805d10a50540746319aaWei Huang Conversation.markAllConversationsAsSeen(context); 15570f5af8fd89d66ae246a805d10a50540746319aaWei Huang } 156c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 157c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 158c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public static final long THREAD_ALL = -1; 159c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public static final long THREAD_NONE = -2; 160c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev /** 161c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * Keeps track of the thread ID of the conversation that's currently displayed to the user 162c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev */ 163c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev private static long sCurrentlyDisplayedThreadId; 164c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev private static final Object sCurrentlyDisplayedThreadLock = new Object(); 165c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 16670f5af8fd89d66ae246a805d10a50540746319aaWei Huang private static OnDeletedReceiver sNotificationDeletedReceiver = new OnDeletedReceiver(); 16770f5af8fd89d66ae246a805d10a50540746319aaWei Huang private static Intent sNotificationOnDeleteIntent; 168429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor private static Handler sToastHandler = new Handler(); 169429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor private static PduPersister sPduPersister; 170429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor private static final int MAX_BITMAP_DIMEN_DP = 360; 171429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor private static float sScreenDensity; 172429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor 173ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor private static final int MAX_MESSAGES_TO_SHOW = 8; // the maximum number of new messages to 174429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor // show in a single notification. 175429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor 17670f5af8fd89d66ae246a805d10a50540746319aaWei Huang 17772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private MessagingNotification() { 17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 18070f5af8fd89d66ae246a805d10a50540746319aaWei Huang public static void init(Context context) { 18170f5af8fd89d66ae246a805d10a50540746319aaWei Huang // set up the intent filter for notification deleted action 18270f5af8fd89d66ae246a805d10a50540746319aaWei Huang IntentFilter intentFilter = new IntentFilter(); 18370f5af8fd89d66ae246a805d10a50540746319aaWei Huang intentFilter.addAction(NOTIFICATION_DELETED_ACTION); 184429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor 185429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor // TODO: should we unregister when the app gets killed? 18670f5af8fd89d66ae246a805d10a50540746319aaWei Huang context.registerReceiver(sNotificationDeletedReceiver, intentFilter); 187429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor sPduPersister = PduPersister.getPduPersister(context); 18870f5af8fd89d66ae246a805d10a50540746319aaWei Huang 18970f5af8fd89d66ae246a805d10a50540746319aaWei Huang // initialize the notification deleted action 19070f5af8fd89d66ae246a805d10a50540746319aaWei Huang sNotificationOnDeleteIntent = new Intent(NOTIFICATION_DELETED_ACTION); 191429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor 192429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor sScreenDensity = context.getResources().getDisplayMetrics().density; 19370f5af8fd89d66ae246a805d10a50540746319aaWei Huang } 19470f5af8fd89d66ae246a805d10a50540746319aaWei Huang 19572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 196c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * Specifies which message thread is currently being viewed by the user. New messages in that 197c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * thread will not generate a notification icon and will play the notification sound at a lower 198c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * volume. Make sure you set this to THREAD_NONE when the UI component that shows the thread is 199c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * no longer visible to the user (e.g. Activity.onPause(), etc.) 200c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * @param threadId The ID of the thread that the user is currently viewing. Pass THREAD_NONE 201c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * if the user is not viewing a thread, or THREAD_ALL if the user is viewing the conversation 202c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * list (note: that latter one has no effect as of this implementation) 203c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev */ 204c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public static void setCurrentlyDisplayedThreadId(long threadId) { 205c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev synchronized (sCurrentlyDisplayedThreadLock) { 206c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev sCurrentlyDisplayedThreadId = threadId; 2072d65e7eb956e60c058de876ddbfff504620ce7a3Tom Taylor if (DEBUG) { 2082d65e7eb956e60c058de876ddbfff504620ce7a3Tom Taylor Log.d(TAG, "setCurrentlyDisplayedThreadId: " + sCurrentlyDisplayedThreadId); 2092d65e7eb956e60c058de876ddbfff504620ce7a3Tom Taylor } 210c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 211c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 212c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 213c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev /** 214627007213deb59ef938c80353c8f3598b01478b3Wei Huang * Checks to see if there are any "unseen" messages or delivery 21572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * reports. Shows the most recent notification if there is one. 2163b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor * Does its work and query in a worker thread. 21772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @param context the context to use 21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 2203b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor public static void nonBlockingUpdateNewMessageIndicator(final Context context, 221c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev final long newMsgThreadId, 2223b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor final boolean isStatusMessage) { 2233b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor new Thread(new Runnable() { 224c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev @Override 2253b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor public void run() { 226c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev blockingUpdateNewMessageIndicator(context, newMsgThreadId, isStatusMessage); 2273b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor } 228ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev }, "MessagingNotification.nonBlockingUpdateNewMessageIndicator").start(); 22972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 23072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 23172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 232627007213deb59ef938c80353c8f3598b01478b3Wei Huang * Checks to see if there are any "unseen" messages or delivery 233429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor * reports and builds a sorted (by delivery date) list of unread notifications. 23472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 23572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @param context the context to use 236c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * @param newMsgThreadId The thread ID of a new message that we're to notify about; if there's 237c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * no new message, use THREAD_NONE. If we should notify about multiple or unknown thread IDs, 238c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * use THREAD_ALL. 239c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * @param isStatusMessage 24072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 241c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public static void blockingUpdateNewMessageIndicator(Context context, long newMsgThreadId, 242c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor boolean isStatusMessage) { 243c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev synchronized (sCurrentlyDisplayedThreadLock) { 244c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev if (newMsgThreadId > 0 && newMsgThreadId == sCurrentlyDisplayedThreadId) { 2459ab4d755b862392724b7dbb12e636235a05cb3bdTom Taylor if (DEBUG) { 2469ab4d755b862392724b7dbb12e636235a05cb3bdTom Taylor Log.d(TAG, "blockingUpdateNewMessageIndicator: newMsgThreadId == " + 2479ab4d755b862392724b7dbb12e636235a05cb3bdTom Taylor "sCurrentlyDisplayedThreadId so NOT showing notification," + 2489ab4d755b862392724b7dbb12e636235a05cb3bdTom Taylor " but playing soft sound. threadId: " + newMsgThreadId); 2499ab4d755b862392724b7dbb12e636235a05cb3bdTom Taylor } 250c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev playInConversationNotificationSound(context); 251c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev return; 252c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 253c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 2544c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor // notificationSet is kept sorted by the incoming message delivery time, with the 2554c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor // most recent message first. 2564c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor SortedSet<NotificationInfo> notificationSet = 2574c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor new TreeSet<NotificationInfo>(INFO_COMPARATOR); 258c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 259b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick Set<Long> threads = new HashSet<Long>(4); 2605a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 2614c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor addMmsNotificationInfos(context, threads, notificationSet); 2624c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor addSmsNotificationInfos(context, threads, notificationSet); 26372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 26472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cancelNotification(context, NOTIFICATION_ID); 2654c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor if (!notificationSet.isEmpty()) { 2666d2ba55a4bd1937bbec101ab2a4c005b566b43f8Tom Taylor if (DEBUG || Log.isLoggable(LogTag.APP, Log.VERBOSE)) { 2676d2ba55a4bd1937bbec101ab2a4c005b566b43f8Tom Taylor Log.d(TAG, "blockingUpdateNewMessageIndicator: count=" + notificationSet.size() + 268c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev ", newMsgThreadId=" + newMsgThreadId); 269e14b79584cca1bf7ba60c53bd7e3d6386adbfc59Wei Huang } 2704c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor updateNotification(context, newMsgThreadId != THREAD_NONE, threads.size(), 2714c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor notificationSet); 27272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 2735a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 2743b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor // And deals with delivery reports (which use Toasts). It's safe to call in a worker 2753b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor // thread because the toast will eventually get posted to a handler. 2764c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor MmsSmsDeliveryInfo delivery = getSmsNewDeliveryInfo(context); 277627007213deb59ef938c80353c8f3598b01478b3Wei Huang if (delivery != null) { 278c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor delivery.deliver(context, isStatusMessage); 279627007213deb59ef938c80353c8f3598b01478b3Wei Huang } 28072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 28172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 28272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 283c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * Play the in-conversation notification sound (it's the regular notification sound, but 284c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * played at half-volume 285c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev */ 286c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev private static void playInConversationNotificationSound(Context context) { 287c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); 288c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev String ringtoneStr = sp.getString(MessagingPreferenceActivity.NOTIFICATION_RINGTONE, 289c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev null); 290c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev if (TextUtils.isEmpty(ringtoneStr)) { 291c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev // Nothing to play 292c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev return; 293c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 294c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev Uri ringtoneUri = Uri.parse(ringtoneStr); 295c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev NotificationPlayer player = new NotificationPlayer(LogTag.APP); 296c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev player.play(context, ringtoneUri, false, AudioManager.STREAM_NOTIFICATION, 297c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev IN_CONVERSATION_NOTIFICATION_VOLUME); 298c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 299c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 300c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev /** 30135a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick * Updates all pending notifications, clearing or updating them as 3023b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor * necessary. 30335a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick */ 304627007213deb59ef938c80353c8f3598b01478b3Wei Huang public static void blockingUpdateAllNotifications(final Context context) { 305c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev nonBlockingUpdateNewMessageIndicator(context, THREAD_NONE, false); 306b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor nonBlockingUpdateSendFailedNotification(context); 307627007213deb59ef938c80353c8f3598b01478b3Wei Huang updateDownloadFailedNotification(context); 308c7aa632be8e7d3ebe71f236f534ea2f0af71e04aTom Taylor MmsWidgetProvider.notifyDatasetChanged(context); 30935a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick } 3105a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 311800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT private static final class MmsSmsDeliveryInfo { 312c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor public CharSequence mTicker; 313c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor public long mTimeMillis; 314c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor 315c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor public MmsSmsDeliveryInfo(CharSequence ticker, long timeMillis) { 316c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor mTicker = ticker; 317c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor mTimeMillis = timeMillis; 318c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor } 319c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor 320c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor public void deliver(Context context, boolean isStatusMessage) { 321c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor updateDeliveryNotification( 322c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor context, isStatusMessage, mTicker, mTimeMillis); 323c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor } 324800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT } 325800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 326429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor private static final class NotificationInfo { 327c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public final Intent mClickIntent; 328ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor public final String mMessage; 329c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public final CharSequence mTicker; 330c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public final long mTimeMillis; 331c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public final String mTitle; 332429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor public final Bitmap mAttachmentBitmap; 333429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor public final Contact mSender; 334429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor public final boolean mIsSms; 335ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor public final int mAttachmentType; 336ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor public final String mSubject; 337ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor public final long mThreadId; 338429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor 339429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor /** 340429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor * @param isSms true if sms, false if mms 341429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor * @param clickIntent where to go when the user taps the notification 342ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor * @param message for a single message, this is the message text 343ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor * @param subject text of mms subject 344429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor * @param ticker text displayed ticker-style across the notification, typically formatted 345429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor * as sender: message 346429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor * @param timeMillis date the message was received 347429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor * @param title for a single message, this is the sender 348429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor * @param attachmentBitmap a bitmap of an attachment, such as a picture or video 349ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor * @param sender contact of the sender 350ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor * @param attachmentType of the mms attachment 351ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor * @param threadId thread this message belongs to 352429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor */ 353429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor public NotificationInfo(boolean isSms, 354ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor Intent clickIntent, String message, String subject, 355429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor CharSequence ticker, long timeMillis, String title, 356ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor Bitmap attachmentBitmap, Contact sender, 357ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor int attachmentType, long threadId) { 358429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor mIsSms = isSms; 35972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mClickIntent = clickIntent; 360ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor mMessage = message; 361ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor mSubject = subject; 36272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mTicker = ticker; 36372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mTimeMillis = timeMillis; 36472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mTitle = title; 365429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor mAttachmentBitmap = attachmentBitmap; 366429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor mSender = sender; 367ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor mAttachmentType = attachmentType; 368ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor mThreadId = threadId; 36972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 37072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 37172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public long getTime() { 37272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return mTimeMillis; 37372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 374ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 375ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // This is the message string used in bigText and bigPicture notifications. 376ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor public CharSequence formatBigMessage(Context context) { 377ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor final TextAppearanceSpan notificationSubjectSpan = new TextAppearanceSpan( 378ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor context, R.style.NotificationPrimaryText); 379ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 380ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // Change multiple newlines (with potential white space between), into a single new line 381ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor final String message = 382ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor !TextUtils.isEmpty(mMessage) ? mMessage.replaceAll("\\n\\s+", "\n") : ""; 383ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 384ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(); 385ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (!TextUtils.isEmpty(mSubject)) { 386ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.append(mSubject); 387ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.setSpan(notificationSubjectSpan, 0, mSubject.length(), 0); 388ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 389ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (mAttachmentType > WorkingMessage.TEXT) { 390ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (spannableStringBuilder.length() > 0) { 391ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.append('\n'); 392ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 393ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.append(getAttachmentTypeString(context, mAttachmentType)); 394ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 395ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (mMessage != null) { 396ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (spannableStringBuilder.length() > 0) { 397ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.append('\n'); 398ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 399ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.append(mMessage); 400ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 401ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor return spannableStringBuilder; 402ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 403ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 404ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // This is the message string used in each line of an inboxStyle notification. 405ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor public CharSequence formatInboxMessage(Context context) { 406ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor final TextAppearanceSpan notificationSenderSpan = new TextAppearanceSpan( 407ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor context, R.style.NotificationPrimaryText); 408ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 409ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor final TextAppearanceSpan notificationSubjectSpan = new TextAppearanceSpan( 410ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor context, R.style.NotificationSubjectText); 411ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 412ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // Change multiple newlines (with potential white space between), into a single new line 413ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor final String message = 414ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor !TextUtils.isEmpty(mMessage) ? mMessage.replaceAll("\\n\\s+", "\n") : ""; 415ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 416ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(); 417ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor final String sender = mSender.getName(); 418ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (!TextUtils.isEmpty(sender)) { 419ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.append(sender); 420ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.setSpan(notificationSenderSpan, 0, sender.length(), 0); 421ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 422ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor String separator = context.getString(R.string.notification_separator); 423ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (!mIsSms) { 424ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (!TextUtils.isEmpty(mSubject)) { 425ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (spannableStringBuilder.length() > 0) { 426ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.append(separator); 427ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 428ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor int start = spannableStringBuilder.length(); 429ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.append(mSubject); 430ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.setSpan(notificationSubjectSpan, start, 431ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor start + mSubject.length(), 0); 432ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 433ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (mAttachmentType > WorkingMessage.TEXT) { 434ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (spannableStringBuilder.length() > 0) { 435ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.append(separator); 436ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 437ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.append(getAttachmentTypeString(context, mAttachmentType)); 438ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 439ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 440ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (message.length() > 0) { 441ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (spannableStringBuilder.length() > 0) { 442ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.append(separator); 443ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 444ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor int start = spannableStringBuilder.length(); 445ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.append(message); 446ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.setSpan(notificationSubjectSpan, start, 447ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor start + message.length(), 0); 448ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 449ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor return spannableStringBuilder; 450ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 451ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 452ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // This is the summary string used in bigPicture notifications. 453ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor public CharSequence formatPictureMessage(Context context) { 454ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor final TextAppearanceSpan notificationSubjectSpan = new TextAppearanceSpan( 455ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor context, R.style.NotificationPrimaryText); 456ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 457ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // Change multiple newlines (with potential white space between), into a single new line 458ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor final String message = 459ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor !TextUtils.isEmpty(mMessage) ? mMessage.replaceAll("\\n\\s+", "\n") : ""; 460ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 461ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // Show the subject or the message (if no subject) 462ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(); 463ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (!TextUtils.isEmpty(mSubject)) { 464ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.append(mSubject); 465ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.setSpan(notificationSubjectSpan, 0, mSubject.length(), 0); 466ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 467ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (message.length() > 0 && spannableStringBuilder.length() == 0) { 468ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.append(message); 469ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.setSpan(notificationSubjectSpan, 0, message.length(), 0); 470ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 471ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor return spannableStringBuilder; 472ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 47372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 47472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 475ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // Return a formatted string with all the sender names separated by commas. 476ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor private static CharSequence formatSenders(Context context, 477ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor ArrayList<NotificationInfo> senders) { 478ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor final TextAppearanceSpan notificationSenderSpan = new TextAppearanceSpan( 479ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor context, R.style.NotificationPrimaryText); 480ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 481ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor String separator = context.getString(R.string.enumeration_comma); // ", " 482ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(); 483ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor int len = senders.size(); 484ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor for (int i = 0; i < len; i++) { 485ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (i > 0) { 486ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.append(separator); 487ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 488ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.append(senders.get(i).mSender.getName()); 489ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 490ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.setSpan(notificationSenderSpan, 0, 491ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableStringBuilder.length(), 0); 492ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor return spannableStringBuilder; 493ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 494ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 495ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // Return a formatted string with the attachmentType spelled out as a string. For 496ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // no attachment (or just text), return null. 497ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor private static CharSequence getAttachmentTypeString(Context context, int attachmentType) { 498ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor final TextAppearanceSpan notificationAttachmentSpan = new TextAppearanceSpan( 499ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor context, R.style.NotificationSecondaryText); 500ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor int id = 0; 501ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor switch (attachmentType) { 502ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor case WorkingMessage.AUDIO: id = R.string.attachment_audio; break; 503ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor case WorkingMessage.VIDEO: id = R.string.attachment_video; break; 504ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor case WorkingMessage.SLIDESHOW: id = R.string.attachment_slideshow; break; 505ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor case WorkingMessage.IMAGE: id = R.string.attachment_picture; break; 506ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 507ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (id > 0) { 508ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor final SpannableString spannableString = new SpannableString(context.getString(id)); 509ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor spannableString.setSpan(notificationAttachmentSpan, 510ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 0, spannableString.length(), 0); 511ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor return spannableString; 512ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 513ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor return null; 514ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 515ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 516429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor /** 517429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor * 518429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor * Sorts by the time a notification was received in descending order -- newer first. 519429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor * 520429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor */ 521429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor private static final class NotificationInfoComparator 522429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor implements Comparator<NotificationInfo> { 523c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev @Override 52472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public int compare( 525429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor NotificationInfo info1, NotificationInfo info2) { 52672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return Long.signum(info2.getTime() - info1.getTime()); 52772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 52872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 52972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 530429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor private static final void addMmsNotificationInfos( 5314c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor Context context, Set<Long> threads, SortedSet<NotificationInfo> notificationSet) { 53272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContentResolver resolver = context.getContentResolver(); 5333b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor 5343b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor // This query looks like this when logged: 5353b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor // I/Database( 147): elapsedTime4Sql|/data/data/com.android.providers.telephony/databases/ 5363b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor // mmssms.db|0.362 ms|SELECT thread_id, date, _id, sub, sub_cs FROM pdu WHERE ((msg_box=1 5373b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor // AND seen=0 AND (m_type=130 OR m_type=132))) ORDER BY date desc 5383b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor 53972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor cursor = SqliteWrapper.query(context, resolver, Mms.CONTENT_URI, 54072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project MMS_STATUS_PROJECTION, NEW_INCOMING_MM_CONSTRAINT, 54172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project null, Mms.DATE + " desc"); 54272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 543b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick if (cursor == null) { 544429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor return; 545b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick } 5465a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 547b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick try { 548429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor while (cursor.moveToNext()) { 549c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 550429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor long msgId = cursor.getLong(COLUMN_MMS_ID); 551429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor Uri msgUri = Mms.CONTENT_URI.buildUpon().appendPath( 552429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor Long.toString(msgId)).build(); 553429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor String address = AddressUtils.getFrom(context, msgUri); 5541b8df494e49bf934fe160baea54ab5afc2ff3100Tom Taylor 555429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor Contact contact = Contact.get(address, false); 556429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor if (contact.getSendToVoicemail()) { 557429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor // don't notify, skip this one 558429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor continue; 559429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor } 5601b8df494e49bf934fe160baea54ab5afc2ff3100Tom Taylor 561429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor String subject = getMmsSubject( 562429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor cursor.getString(COLUMN_SUBJECT), cursor.getInt(COLUMN_SUBJECT_CS)); 5633c307cabb5bd96ed174930ebf17f533bf2a79de7Tom Taylor subject = MessageUtils.cleanseMmsSubject(context, subject); 5643c307cabb5bd96ed174930ebf17f533bf2a79de7Tom Taylor 565429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor long threadId = cursor.getLong(COLUMN_THREAD_ID); 566429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor long timeMillis = cursor.getLong(COLUMN_DATE) * 1000; 567b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick 568429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) { 569429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor Log.d(TAG, "addMmsNotificationInfos: count=" + cursor.getCount() + 570429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor ", addr = " + address + ", thread_id=" + threadId); 571429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor } 572e14b79584cca1bf7ba60c53bd7e3d6386adbfc59Wei Huang 573429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor // Extract the message and/or an attached picture from the first slide 574429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor Bitmap attachedPicture = null; 575429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor String messageBody = null; 576ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor int attachmentType = WorkingMessage.TEXT; 577429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor try { 578429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor GenericPdu pdu = sPduPersister.load(msgUri); 579f677c24f07befa52ae977461c56fedeb0ad3eb47Tom Taylor if (pdu != null && pdu instanceof MultimediaMessagePdu) { 580429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor SlideshowModel slideshow = SlideshowModel.createFromPduBody(context, 581429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor ((MultimediaMessagePdu)pdu).getBody()); 582ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor attachmentType = getAttachmentType(slideshow); 583429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor SlideModel firstSlide = slideshow.get(0); 584429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor if (firstSlide != null) { 585429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor if (firstSlide.hasImage()) { 586429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor int maxDim = dp2Pixels(MAX_BITMAP_DIMEN_DP); 587429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor attachedPicture = firstSlide.getImage().getBitmap(maxDim, maxDim); 588429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor } 589429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor if (firstSlide.hasText()) { 590429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor messageBody = firstSlide.getText().getText(); 591429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor } 592429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor } 593429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor } 594429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor } catch (final MmsException e) { 595429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor Log.e(TAG, "MmsException loading uri: " + msgUri, e); 596429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor } 597b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick 598ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor NotificationInfo info = getNewMessageNotificationInfo(context, 599ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor false /* isSms */, 600429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor address, 601ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor messageBody, subject, 602ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor threadId, 603ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor timeMillis, 604ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor attachedPicture, 605ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor contact, 606ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor attachmentType); 607429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor 6084c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor notificationSet.add(info); 609b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick 610429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor threads.add(threadId); 611429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor } 612b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick } finally { 613b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick cursor.close(); 61472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 61572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 61672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 617ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // Look at the passed in slideshow and determine what type of attachment it is. 618ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor private static int getAttachmentType(SlideshowModel slideshow) { 619ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor int slideCount = slideshow.size(); 620ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 621ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (slideCount == 0) { 622ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor return WorkingMessage.TEXT; 623ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } else if (slideCount > 1) { 624ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor return WorkingMessage.SLIDESHOW; 625ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } else { 626ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor SlideModel slide = slideshow.get(0); 627ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (slide.hasImage()) { 628ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor return WorkingMessage.IMAGE; 629ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } else if (slide.hasVideo()) { 630ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor return WorkingMessage.VIDEO; 631ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } else if (slide.hasAudio()) { 632ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor return WorkingMessage.AUDIO; 633ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 634ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 635ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor return WorkingMessage.TEXT; 636ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 637ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 638429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor private static final int dp2Pixels(int dip) { 639429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor return (int) (dip * sScreenDensity + 0.5f); 640429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor } 641429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor 6423b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor private static final MmsSmsDeliveryInfo getSmsNewDeliveryInfo(Context context) { 643627007213deb59ef938c80353c8f3598b01478b3Wei Huang ContentResolver resolver = context.getContentResolver(); 644627007213deb59ef938c80353c8f3598b01478b3Wei Huang Cursor cursor = SqliteWrapper.query(context, resolver, Sms.CONTENT_URI, 645627007213deb59ef938c80353c8f3598b01478b3Wei Huang SMS_STATUS_PROJECTION, NEW_DELIVERY_SM_CONSTRAINT, 6466a9c779f0c0dc6cf3ae942ff70fb6c806aa166dcBanavathu, Srinivas Naik null, Sms.DATE); 647800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 648ac9a5e52dc349faae2a7d8a990ff2b674c61f027Alexander Blom if (cursor == null) { 649627007213deb59ef938c80353c8f3598b01478b3Wei Huang return null; 650ac9a5e52dc349faae2a7d8a990ff2b674c61f027Alexander Blom } 651800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 652627007213deb59ef938c80353c8f3598b01478b3Wei Huang try { 653ac9a5e52dc349faae2a7d8a990ff2b674c61f027Alexander Blom if (!cursor.moveToLast()) { 654ac9a5e52dc349faae2a7d8a990ff2b674c61f027Alexander Blom return null; 655ac9a5e52dc349faae2a7d8a990ff2b674c61f027Alexander Blom } 656800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 657627007213deb59ef938c80353c8f3598b01478b3Wei Huang String address = cursor.getString(COLUMN_SMS_ADDRESS); 658627007213deb59ef938c80353c8f3598b01478b3Wei Huang long timeMillis = 3000; 659800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 660ac9a5e52dc349faae2a7d8a990ff2b674c61f027Alexander Blom Contact contact = Contact.get(address, false); 661ac9a5e52dc349faae2a7d8a990ff2b674c61f027Alexander Blom String name = contact.getNameAndNumber(); 662ac9a5e52dc349faae2a7d8a990ff2b674c61f027Alexander Blom 663ac9a5e52dc349faae2a7d8a990ff2b674c61f027Alexander Blom return new MmsSmsDeliveryInfo(context.getString(R.string.delivery_toast_body, name), 664627007213deb59ef938c80353c8f3598b01478b3Wei Huang timeMillis); 665800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 666627007213deb59ef938c80353c8f3598b01478b3Wei Huang } finally { 667627007213deb59ef938c80353c8f3598b01478b3Wei Huang cursor.close(); 668627007213deb59ef938c80353c8f3598b01478b3Wei Huang } 669800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT } 670800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 671429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor private static final void addSmsNotificationInfos( 6724c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor Context context, Set<Long> threads, SortedSet<NotificationInfo> notificationSet) { 67372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContentResolver resolver = context.getContentResolver(); 67472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor cursor = SqliteWrapper.query(context, resolver, Sms.CONTENT_URI, 67572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SMS_STATUS_PROJECTION, NEW_INCOMING_SM_CONSTRAINT, 67672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project null, Sms.DATE + " desc"); 67772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 678b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick if (cursor == null) { 679429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor return; 680b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick } 6815a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 682b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick try { 683429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor while (cursor.moveToNext()) { 684429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor String address = cursor.getString(COLUMN_SMS_ADDRESS); 685b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick 686429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor Contact contact = Contact.get(address, false); 687429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor if (contact.getSendToVoicemail()) { 688429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor // don't notify, skip this one 689429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor continue; 690429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor } 6911b8df494e49bf934fe160baea54ab5afc2ff3100Tom Taylor 692ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor String message = cursor.getString(COLUMN_SMS_BODY); 693429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor long threadId = cursor.getLong(COLUMN_THREAD_ID); 694429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor long timeMillis = cursor.getLong(COLUMN_DATE); 6951b8df494e49bf934fe160baea54ab5afc2ff3100Tom Taylor 696429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) 697429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor { 698429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor Log.d(TAG, "addSmsNotificationInfos: count=" + cursor.getCount() + 699429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor ", addr=" + address + ", thread_id=" + threadId); 700429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor } 701b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick 702e14b79584cca1bf7ba60c53bd7e3d6386adbfc59Wei Huang 703ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor NotificationInfo info = getNewMessageNotificationInfo(context, true /* isSms */, 704ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor address, message, null /* subject */, 705ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor threadId, timeMillis, null /* attachmentBitmap */, 706ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor contact, WorkingMessage.TEXT); 707b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick 7084c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor notificationSet.add(info); 709429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor 710429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor threads.add(threadId); 711b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick threads.add(cursor.getLong(COLUMN_THREAD_ID)); 71272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 713b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick } finally { 714b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick cursor.close(); 71572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 71672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 71772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 718429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor private static final NotificationInfo getNewMessageNotificationInfo( 719ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor Context context, 720429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor boolean isSms, 72172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String address, 722ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor String message, 72372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String subject, 72472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long threadId, 72572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long timeMillis, 726429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor Bitmap attachmentBitmap, 727ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor Contact contact, 728ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor int attachmentType) { 729812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang Intent clickIntent = ComposeMessageActivity.createIntent(context, threadId); 730812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang clickIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 731812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang | Intent.FLAG_ACTIVITY_SINGLE_TOP 732812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang | Intent.FLAG_ACTIVITY_CLEAR_TOP); 73372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 73472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String senderInfo = buildTickerMessage( 73572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context, address, null, null).toString(); 73672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String senderInfoName = senderInfo.substring( 73772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 0, senderInfo.length() - 2); 73872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project CharSequence ticker = buildTickerMessage( 739ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor context, address, subject, message); 74072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 741429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor return new NotificationInfo(isSms, 742ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor clickIntent, message, subject, ticker, timeMillis, 743ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor senderInfoName, attachmentBitmap, contact, attachmentType, threadId); 74472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 74572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 74672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static void cancelNotification(Context context, int notificationId) { 74772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project NotificationManager nm = (NotificationManager) context.getSystemService( 74872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Context.NOTIFICATION_SERVICE); 74972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 75072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project nm.cancel(notificationId); 75172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 75272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7535a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor private static void updateDeliveryNotification(final Context context, 754c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor boolean isStatusMessage, 7555a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor final CharSequence message, 7565a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor final long timeMillis) { 757c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor if (!isStatusMessage) { 758c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor return; 759c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor } 760c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor 761800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 762d83675687b1ef742c33bffe8195d7b1852c2c01dTom Taylor if (!MessagingPreferenceActivity.getNotificationEnabled(context)) { 76370f5af8fd89d66ae246a805d10a50540746319aaWei Huang return; 76470f5af8fd89d66ae246a805d10a50540746319aaWei Huang } 765800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 766429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor sToastHandler.post(new Runnable() { 767c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev @Override 768c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor public void run() { 769c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor Toast.makeText(context, message, (int)timeMillis).show(); 770c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor } 771c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor }); 772800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT } 773800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 774429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor /** 775429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor * updateNotification is *the* main function for building the actual notification handed to 776429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor * the NotificationManager 777429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor * @param context 778429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor * @param isNew if we've got a new message, show the ticker 779429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor * @param uniqueThreadCount 7804c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor * @param notificationSet the set of notifications to display 781429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor */ 78272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static void updateNotification( 78372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Context context, 78472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project boolean isNew, 7854c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor int uniqueThreadCount, 7864c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor SortedSet<NotificationInfo> notificationSet) { 787429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor // If the user has turned off notifications in settings, don't do any notifying. 788d83675687b1ef742c33bffe8195d7b1852c2c01dTom Taylor if (!MessagingPreferenceActivity.getNotificationEnabled(context)) { 7899ab4d755b862392724b7dbb12e636235a05cb3bdTom Taylor if (DEBUG) { 7909ab4d755b862392724b7dbb12e636235a05cb3bdTom Taylor Log.d(TAG, "updateNotification: notifications turned off in prefs, bailing"); 7919ab4d755b862392724b7dbb12e636235a05cb3bdTom Taylor } 79272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 79372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 79472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 795429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor // Figure out what we've got -- whether all sms's, mms's, or a mixture of both. 7964c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor final int messageCount = notificationSet.size(); 7974c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor NotificationInfo mostRecentNotification = notificationSet.first(); 798429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor 799674b5045f39aedf85e6a7e38237860d000f46de0Daniel Sandler final Notification.Builder noti = new Notification.Builder(context) 800429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor .setWhen(mostRecentNotification.mTimeMillis); 801674b5045f39aedf85e6a7e38237860d000f46de0Daniel Sandler 802429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor if (isNew) { 803ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor noti.setTicker(mostRecentNotification.mTicker); 804429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor } 805fb7068020e74e431acc9511212d2a6d17258ab9eAdam Powell TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(context); 806b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick 807b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick // If we have more than one unique thread, change the title (which would 808b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick // normally be the contact who sent the message) to a generic one that 809b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick // makes sense for multiple senders, and change the Intent to take the 810b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick // user to the conversation list instead of the specific thread. 811674b5045f39aedf85e6a7e38237860d000f46de0Daniel Sandler 812429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor // Cases: 813429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor // 1) single message from single thread - intent goes to ComposeMessageActivity 814429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor // 2) multiple messages from single thread - intent goes to ComposeMessageActivity 815429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor // 3) messages from multiple threads - intent goes to ConversationList 816429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor 817ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor final Resources res = context.getResources(); 818429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor String title = null; 81964fefc1c9b26bd6778c318e83cec696abb389c22Daniel Sandler Bitmap avatar = null; 820429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor if (uniqueThreadCount > 1) { // messages from multiple threads 8211fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor Intent mainActivityIntent = new Intent(Intent.ACTION_MAIN); 822812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang 8231fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor mainActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 824812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang | Intent.FLAG_ACTIVITY_SINGLE_TOP 825812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang | Intent.FLAG_ACTIVITY_CLEAR_TOP); 826812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang 8271fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor mainActivityIntent.setType("vnd.android-dir/mms-sms"); 8286cc254afc74dee97c7ef356612ae9ec7bc8b77ceTom Taylor taskStackBuilder.addNextIntent(mainActivityIntent); 829ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor title = context.getString(R.string.message_count_notification, messageCount); 830429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor } else { // same thread, single or multiple messages 831ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor title = mostRecentNotification.mTitle; 832429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor BitmapDrawable contactDrawable = (BitmapDrawable)mostRecentNotification.mSender 833429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor .getAvatar(context, null); 834ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (contactDrawable != null) { 835ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // Show the sender's avatar as the big icon. Contact bitmaps are 96x96 so we 836ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // have to scale 'em up to 128x128 to fill the whole notification large icon. 83764fefc1c9b26bd6778c318e83cec696abb389c22Daniel Sandler avatar = contactDrawable.getBitmap(); 838ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (avatar != null) { 839ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor final int idealIconHeight = 840ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor res.getDimensionPixelSize(android.R.dimen.notification_large_icon_height); 841ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor final int idealIconWidth = 842ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor res.getDimensionPixelSize(android.R.dimen.notification_large_icon_width); 843ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (avatar.getHeight() < idealIconHeight) { 844ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // Scale this image to fit the intended size 845ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor avatar = Bitmap.createScaledBitmap( 846ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor avatar, idealIconWidth, idealIconHeight, true); 847ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 848ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (avatar != null) { 849ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor noti.setLargeIcon(avatar); 850ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 851ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 852ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 853429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor 8546cc254afc74dee97c7ef356612ae9ec7bc8b77ceTom Taylor taskStackBuilder.addParentStack(ComposeMessageActivity.class); 8556cc254afc74dee97c7ef356612ae9ec7bc8b77ceTom Taylor taskStackBuilder.addNextIntent(mostRecentNotification.mClickIntent); 856b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick } 857ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // Always have to set the small icon or the notification is ignored 858ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor noti.setSmallIcon(R.drawable.stat_notify_sms); 859ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 860429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor NotificationManager nm = (NotificationManager) 861429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor context.getSystemService(Context.NOTIFICATION_SERVICE); 86272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 863b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick // Update the notification. 864674b5045f39aedf85e6a7e38237860d000f46de0Daniel Sandler noti.setContentTitle(title) 8656cc254afc74dee97c7ef356612ae9ec7bc8b77ceTom Taylor .setContentIntent( 8666cc254afc74dee97c7ef356612ae9ec7bc8b77ceTom Taylor taskStackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)) 867429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor .addKind(Notification.KIND_MESSAGE) 868ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor .setPriority(Notification.PRIORITY_DEFAULT); // TODO: set based on contact coming 869ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // from a favorite. 870429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor 871674b5045f39aedf85e6a7e38237860d000f46de0Daniel Sandler int defaults = 0; 87272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 87372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isNew) { 874d83675687b1ef742c33bffe8195d7b1852c2c01dTom Taylor SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); 875006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma String vibrateWhen; 876006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma if (sp.contains(MessagingPreferenceActivity.NOTIFICATION_VIBRATE_WHEN)) { 877006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma vibrateWhen = 878006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma sp.getString(MessagingPreferenceActivity.NOTIFICATION_VIBRATE_WHEN, null); 879006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma } else if (sp.contains(MessagingPreferenceActivity.NOTIFICATION_VIBRATE)) { 880429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor vibrateWhen = 881429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor sp.getBoolean(MessagingPreferenceActivity.NOTIFICATION_VIBRATE, false) ? 882006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma context.getString(R.string.prefDefault_vibrate_true) : 883006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma context.getString(R.string.prefDefault_vibrate_false); 884006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma } else { 885006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma vibrateWhen = context.getString(R.string.prefDefault_vibrateWhen); 886006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma } 887006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma 888006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma boolean vibrateAlways = vibrateWhen.equals("always"); 889006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma boolean vibrateSilent = vibrateWhen.equals("silent"); 890006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma AudioManager audioManager = 891006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma (AudioManager)context.getSystemService(Context.AUDIO_SERVICE); 892006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma boolean nowSilent = 893006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma audioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE; 894006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma 895006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma if (vibrateAlways || vibrateSilent && nowSilent) { 896674b5045f39aedf85e6a7e38237860d000f46de0Daniel Sandler defaults |= Notification.DEFAULT_VIBRATE; 89772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 89872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 899627007213deb59ef938c80353c8f3598b01478b3Wei Huang String ringtoneStr = sp.getString(MessagingPreferenceActivity.NOTIFICATION_RINGTONE, 900627007213deb59ef938c80353c8f3598b01478b3Wei Huang null); 901674b5045f39aedf85e6a7e38237860d000f46de0Daniel Sandler noti.setSound(TextUtils.isEmpty(ringtoneStr) ? null : Uri.parse(ringtoneStr)); 9029ab4d755b862392724b7dbb12e636235a05cb3bdTom Taylor if (DEBUG) { 9039ab4d755b862392724b7dbb12e636235a05cb3bdTom Taylor Log.d(TAG, "updateNotification: new message, adding sound to the notification"); 9049ab4d755b862392724b7dbb12e636235a05cb3bdTom Taylor } 90572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 90672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 907674b5045f39aedf85e6a7e38237860d000f46de0Daniel Sandler defaults |= Notification.DEFAULT_LIGHTS; 908674b5045f39aedf85e6a7e38237860d000f46de0Daniel Sandler 909674b5045f39aedf85e6a7e38237860d000f46de0Daniel Sandler noti.setDefaults(defaults); 91072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 91170f5af8fd89d66ae246a805d10a50540746319aaWei Huang // set up delete intent 912674b5045f39aedf85e6a7e38237860d000f46de0Daniel Sandler noti.setDeleteIntent(PendingIntent.getBroadcast(context, 0, 913674b5045f39aedf85e6a7e38237860d000f46de0Daniel Sandler sNotificationOnDeleteIntent, 0)); 91470f5af8fd89d66ae246a805d10a50540746319aaWei Huang 915674b5045f39aedf85e6a7e38237860d000f46de0Daniel Sandler final Notification notification; 916429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor 917ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (messageCount == 1) { 918ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // We've got a single message 919ca7b54a002b5bc627171d1b275cb016bf1105da2Daniel Sandler 920ca7b54a002b5bc627171d1b275cb016bf1105da2Daniel Sandler // This sets the text for the collapsed form: 921ca7b54a002b5bc627171d1b275cb016bf1105da2Daniel Sandler noti.setContentText(mostRecentNotification.formatBigMessage(context)); 922ca7b54a002b5bc627171d1b275cb016bf1105da2Daniel Sandler 923ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (mostRecentNotification.mAttachmentBitmap != null) { 924ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // The message has a picture, show that 925ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 926ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor notification = new Notification.BigPictureStyle(noti) 927ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor .bigPicture(mostRecentNotification.mAttachmentBitmap) 928ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // This sets the text for the expanded picture form: 929ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor .setSummaryText(mostRecentNotification.formatPictureMessage(context)) 930ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor .build(); 931ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } else { 932ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // Show a single notification -- big style with the text of the whole message 933ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor notification = new Notification.BigTextStyle(noti) 934ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor .bigText(mostRecentNotification.formatBigMessage(context)) 935ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor .build(); 936ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 9376d2ba55a4bd1937bbec101ab2a4c005b566b43f8Tom Taylor if (DEBUG) { 9386d2ba55a4bd1937bbec101ab2a4c005b566b43f8Tom Taylor Log.d(TAG, "updateNotification: single message notification"); 9396d2ba55a4bd1937bbec101ab2a4c005b566b43f8Tom Taylor } 940ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } else { 941ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // We've got multiple messages 942ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (uniqueThreadCount == 1) { 943ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // We've got multiple messages for the same thread. 944ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // Starting with the oldest new message, display the full text of each message. 945ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // Begin a line for each subsequent message. 946429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor SpannableStringBuilder buf = new SpannableStringBuilder(); 947ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor NotificationInfo infos[] = 9484c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor notificationSet.toArray(new NotificationInfo[messageCount]); 949ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor int len = infos.length; 950ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor for (int i = len - 1; i >= 0; i--) { 951ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor NotificationInfo info = infos[i]; 952ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 953ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor buf.append(info.formatBigMessage(context)); 954429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor 955ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (i != 0) { 956ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor buf.append('\n'); 957ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 958ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 959ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 960ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor noti.setContentText(context.getString(R.string.message_count_notification, 961ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor messageCount)); 962ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 963ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // Show a single notification -- big style with the text of all the messages 964ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor notification = new Notification.BigTextStyle(noti) 965ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor .bigText(buf) 9664c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor // Forcibly show the last line, with the app's smallIcon in it, if we 96764fefc1c9b26bd6778c318e83cec696abb389c22Daniel Sandler // kicked the smallIcon out with an avatar bitmap 96864fefc1c9b26bd6778c318e83cec696abb389c22Daniel Sandler .setSummaryText((avatar == null) ? null : " ") 969ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor .build(); 9706d2ba55a4bd1937bbec101ab2a4c005b566b43f8Tom Taylor if (DEBUG) { 9716d2ba55a4bd1937bbec101ab2a4c005b566b43f8Tom Taylor Log.d(TAG, "updateNotification: multi messages for single thread"); 9726d2ba55a4bd1937bbec101ab2a4c005b566b43f8Tom Taylor } 973ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } else { 974ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // Build a set of the most recent notification per threadId. 9754c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor HashSet<Long> uniqueThreads = new HashSet<Long>(messageCount); 976ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor ArrayList<NotificationInfo> mostRecentNotifPerThread = 977ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor new ArrayList<NotificationInfo>(); 9784c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor Iterator<NotificationInfo> notifications = notificationSet.iterator(); 979ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor while (notifications.hasNext()) { 980ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor NotificationInfo notificationInfo = notifications.next(); 981ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (!uniqueThreads.contains(notificationInfo.mThreadId)) { 982ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor uniqueThreads.add(notificationInfo.mThreadId); 983ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor mostRecentNotifPerThread.add(notificationInfo); 984ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 985ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 986ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // When collapsed, show all the senders like this: 987ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // Fred Flinstone, Barry Manilow, Pete... 988ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor noti.setContentText(formatSenders(context, mostRecentNotifPerThread)); 989ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor Notification.InboxStyle inboxStyle = new Notification.InboxStyle(noti); 990ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 991ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // We have to set the summary text to non-empty so the content text doesn't show 992ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // up when expanded. 993ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor inboxStyle.setSummaryText(" "); 994ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 995ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // At this point we've got multiple messages in multiple threads. We only 996ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // want to show the most recent message per thread, which are in 997ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor // mostRecentNotifPerThread. 998ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor int uniqueThreadMessageCount = mostRecentNotifPerThread.size(); 999ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor int maxMessages = Math.min(MAX_MESSAGES_TO_SHOW, uniqueThreadMessageCount); 1000ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor 1001ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor for (int i = 0; i < maxMessages; i++) { 1002ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor NotificationInfo info = mostRecentNotifPerThread.get(i); 1003ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor inboxStyle.addLine(info.formatInboxMessage(context)); 1004ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor } 1005ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor notification = inboxStyle.build(); 1006ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor if (DEBUG) { 1007ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor Log.d(TAG, "updateNotification: multi messages," + 1008ee0f8ea8d8739358387443b4fe7d1d9edf44f601Tom Taylor " showing inboxStyle notification"); 1009429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor } 10109ab4d755b862392724b7dbb12e636235a05cb3bdTom Taylor } 1011674b5045f39aedf85e6a7e38237860d000f46de0Daniel Sandler } 1012674b5045f39aedf85e6a7e38237860d000f46de0Daniel Sandler 101372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project nm.notify(NOTIFICATION_ID, notification); 101472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 101572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 101672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected static CharSequence buildTickerMessage( 101772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Context context, String address, String subject, String body) { 101833a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick String displayAddress = Contact.get(address, true).getName(); 10195a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 102072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project StringBuilder buf = new StringBuilder( 102172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project displayAddress == null 102272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ? "" 102372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project : displayAddress.replace('\n', ' ').replace('\r', ' ')); 102472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project buf.append(':').append(' '); 102572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 102672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int offset = buf.length(); 102772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!TextUtils.isEmpty(subject)) { 102872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project subject = subject.replace('\n', ' ').replace('\r', ' '); 102972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project buf.append(subject); 103072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project buf.append(' '); 103172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 103272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 103372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!TextUtils.isEmpty(body)) { 103472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project body = body.replace('\n', ' ').replace('\r', ' '); 103572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project buf.append(body); 103672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 103772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 103872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SpannableString spanText = new SpannableString(buf.toString()); 103972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project spanText.setSpan(new StyleSpan(Typeface.BOLD), 0, offset, 104072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 104172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 104272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return spanText; 104372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 104472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 104572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static String getMmsSubject(String sub, int charset) { 104672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return TextUtils.isEmpty(sub) ? "" 104772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project : new EncodedStringValue(charset, PduPersister.getBytes(sub)).getString(); 104872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 104972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 105072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static void notifyDownloadFailed(Context context, long threadId) { 1051b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick notifyFailed(context, true, threadId, false); 105272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 105372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 10545d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project public static void notifySendFailed(Context context) { 1055b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick notifyFailed(context, false, 0, false); 105672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 105772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 1058b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick public static void notifySendFailed(Context context, boolean noisy) { 1059b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick notifyFailed(context, false, 0, noisy); 1060b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick } 10615a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 1062b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick private static void notifyFailed(Context context, boolean isDownload, long threadId, 1063b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick boolean noisy) { 106472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO factor out common code for creating notifications 1065d83675687b1ef742c33bffe8195d7b1852c2c01dTom Taylor boolean enabled = MessagingPreferenceActivity.getNotificationEnabled(context); 106672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!enabled) { 106772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 106872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 106972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 107072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Strategy: 107172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // a. If there is a single failure notification, tapping on the notification goes 107272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // to the compose view. 10735a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor // b. If there are two failure it stays in the thread view. Selecting one undelivered 107472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // thread will dismiss one undelivered notification but will still display the 107572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // notification.If you select the 2nd undelivered one it will dismiss the notification. 10765a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 10777015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev long[] msgThreadId = {0, 1}; // Dummy initial values, just to initialize the memory 107872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int totalFailedCount = getUndeliveredMessageCount(context, msgThreadId); 10797015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev if (totalFailedCount == 0 && !isDownload) { 10807015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev return; 10817015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev } 10827015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev // The getUndeliveredMessageCount method puts a non-zero value in msgThreadId[1] if all 10837015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev // failures are from the same thread. 10847015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev // If isDownload is true, we're dealing with 1 specific failure; therefore "all failed" are 10857015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev // indeed in the same thread since there's only 1. 10867015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev boolean allFailedInSameThread = (msgThreadId[1] != 0) || isDownload; 10875a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 108872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent failedIntent; 108972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Notification notification = new Notification(); 109072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String title; 109172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String description; 109272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (totalFailedCount > 1) { 109372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project description = context.getString(R.string.notification_failed_multiple, 109472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Integer.toString(totalFailedCount)); 109572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project title = context.getString(R.string.notification_failed_multiple_title); 109672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 109772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project title = isDownload ? 109872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context.getString(R.string.message_download_failed_title) : 109972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context.getString(R.string.message_send_failed_title); 11005a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 110172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project description = context.getString(R.string.message_failed_body); 11027015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev } 11037015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev 1104fb7068020e74e431acc9511212d2a6d17258ab9eAdam Powell TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(context); 11057015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev if (allFailedInSameThread) { 1106836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project failedIntent = new Intent(context, ComposeMessageActivity.class); 110795817b166d415114bac89ca0946c3717ae229526Tom Taylor if (isDownload) { 110895817b166d415114bac89ca0946c3717ae229526Tom Taylor // When isDownload is true, the valid threadId is passed into this function. 110995817b166d415114bac89ca0946c3717ae229526Tom Taylor failedIntent.putExtra("failed_download_flag", true); 111095817b166d415114bac89ca0946c3717ae229526Tom Taylor } else { 11117015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev threadId = msgThreadId[0]; 111295817b166d415114bac89ca0946c3717ae229526Tom Taylor failedIntent.putExtra("undelivered_flag", true); 11135a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor } 11145a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor failedIntent.putExtra("thread_id", threadId); 11156cc254afc74dee97c7ef356612ae9ec7bc8b77ceTom Taylor taskStackBuilder.addParentStack(ComposeMessageActivity.class); 11167015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev } else { 11177015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev failedIntent = new Intent(context, ConversationList.class); 111872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 11196cc254afc74dee97c7ef356612ae9ec7bc8b77ceTom Taylor taskStackBuilder.addNextIntent(failedIntent); 112072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 112172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.icon = R.drawable.stat_notify_sms_failed; 112272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 112372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.tickerText = title; 112472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 11256cc254afc74dee97c7ef356612ae9ec7bc8b77ceTom Taylor notification.setLatestEventInfo(context, title, description, 11266cc254afc74dee97c7ef356612ae9ec7bc8b77ceTom Taylor taskStackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)); 112772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 1128b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick if (noisy) { 1129d83675687b1ef742c33bffe8195d7b1852c2c01dTom Taylor SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); 1130e3baaa51cd25b52c7a24e381319926b9da00abdfWei Huang boolean vibrate = sp.getBoolean(MessagingPreferenceActivity.NOTIFICATION_VIBRATE, 1131e3baaa51cd25b52c7a24e381319926b9da00abdfWei Huang false /* don't vibrate by default */); 1132b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick if (vibrate) { 1133b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick notification.defaults |= Notification.DEFAULT_VIBRATE; 1134b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick } 113572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 1136e3baaa51cd25b52c7a24e381319926b9da00abdfWei Huang String ringtoneStr = sp.getString(MessagingPreferenceActivity.NOTIFICATION_RINGTONE, 1137e3baaa51cd25b52c7a24e381319926b9da00abdfWei Huang null); 1138b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick notification.sound = TextUtils.isEmpty(ringtoneStr) ? null : Uri.parse(ringtoneStr); 1139b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick } 11405a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 1141429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor NotificationManager notificationMgr = (NotificationManager) 1142429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor context.getSystemService(Context.NOTIFICATION_SERVICE); 1143429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor 114472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isDownload) { 1145429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor notificationMgr.notify(DOWNLOAD_FAILED_NOTIFICATION_ID, notification); 114672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 1147429f4c0b2a6ada384e30af31644f1edba0284b4dTom Taylor notificationMgr.notify(MESSAGE_FAILED_NOTIFICATION_ID, notification); 114872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 114972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 11505a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 11517015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev /** 11527015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev * Query the DB and return the number of undelivered messages (total for both SMS and MMS) 11537015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev * @param context The context 11547015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev * @param threadIdResult A container to put the result in, according to the following rules: 11557015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev * threadIdResult[0] contains the thread id of the first message. 11567015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev * threadIdResult[1] is nonzero if the thread ids of all the messages are the same. 11577015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev * You can pass in null for threadIdResult. 11587015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev * You can pass in a threadIdResult of size 1 to avoid the comparison of each thread id. 11597015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev */ 116072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static int getUndeliveredMessageCount(Context context, long[] threadIdResult) { 116172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor undeliveredCursor = SqliteWrapper.query(context, context.getContentResolver(), 1162c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev UNDELIVERED_URI, MMS_THREAD_ID_PROJECTION, "read=0", null, null); 116372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (undeliveredCursor == null) { 116472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return 0; 116572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 116672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int count = undeliveredCursor.getCount(); 116772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 116872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (threadIdResult != null && undeliveredCursor.moveToFirst()) { 116972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project threadIdResult[0] = undeliveredCursor.getLong(0); 11705a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 11712f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project if (threadIdResult.length >= 2) { 11722f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project // Test to see if all the undelivered messages belong to the same thread. 11732f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project long firstId = threadIdResult[0]; 11742f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project while (undeliveredCursor.moveToNext()) { 11752f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project if (undeliveredCursor.getLong(0) != firstId) { 11762f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project firstId = 0; 11772f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project break; 11782f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project } 11792f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project } 11802f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project threadIdResult[1] = firstId; // non-zero if all ids are the same 11812f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project } 118272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 118372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 118472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project undeliveredCursor.close(); 118572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 118672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return count; 118772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 118872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 1189b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor public static void nonBlockingUpdateSendFailedNotification(final Context context) { 1190b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor new AsyncTask<Void, Void, Integer>() { 1191b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor protected Integer doInBackground(Void... none) { 1192b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor return getUndeliveredMessageCount(context, null); 1193b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor } 1194b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor 1195b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor protected void onPostExecute(Integer result) { 1196b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor if (result < 1) { 1197b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor cancelNotification(context, MESSAGE_FAILED_NOTIFICATION_ID); 1198b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor } else { 1199b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor // rebuild and adjust the message count if necessary. 1200b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor notifySendFailed(context); 1201b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor } 1202b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor } 1203b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor }.execute(); 120472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 12055a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 12065a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor /** 12072f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project * If all the undelivered messages belong to "threadId", cancel the notification. 12082f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project */ 12092f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project public static void updateSendFailedNotificationForThread(Context context, long threadId) { 12102f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project long[] msgThreadId = {0, 0}; 12115a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor if (getUndeliveredMessageCount(context, msgThreadId) > 0 12122f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project && msgThreadId[0] == threadId 12132f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project && msgThreadId[1] != 0) { 12142f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project cancelNotification(context, MESSAGE_FAILED_NOTIFICATION_ID); 12152f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project } 12162f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project } 12175a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 121872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static int getDownloadFailedMessageCount(Context context) { 121972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Look for any messages in the MMS Inbox that are of the type 122072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // NOTIFICATION_IND (i.e. not already downloaded) and in the 122172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // permanent failure state. If there are none, cancel any 122272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // failed download notification. 122372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor c = SqliteWrapper.query(context, context.getContentResolver(), 122472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Mms.Inbox.CONTENT_URI, null, 122572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Mms.MESSAGE_TYPE + "=" + 122672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String.valueOf(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) + 122772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project " AND " + Mms.STATUS + "=" + 122872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String.valueOf(DownloadManager.STATE_PERMANENT_FAILURE), 122972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project null, null); 123072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (c == null) { 123172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return 0; 123272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 123372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int count = c.getCount(); 123472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project c.close(); 123572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return count; 123672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 123772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 123872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static void updateDownloadFailedNotification(Context context) { 123972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (getDownloadFailedMessageCount(context) < 1) { 124072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cancelNotification(context, DOWNLOAD_FAILED_NOTIFICATION_ID); 124172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 124272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 12435a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 124495817b166d415114bac89ca0946c3717ae229526Tom Taylor public static boolean isFailedToDeliver(Intent intent) { 124595817b166d415114bac89ca0946c3717ae229526Tom Taylor return (intent != null) && intent.getBooleanExtra("undelivered_flag", false); 124695817b166d415114bac89ca0946c3717ae229526Tom Taylor } 124795817b166d415114bac89ca0946c3717ae229526Tom Taylor 124895817b166d415114bac89ca0946c3717ae229526Tom Taylor public static boolean isFailedToDownload(Intent intent) { 124995817b166d415114bac89ca0946c3717ae229526Tom Taylor return (intent != null) && intent.getBooleanExtra("failed_download_flag", false); 125095817b166d415114bac89ca0946c3717ae229526Tom Taylor } 1251c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 1252c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev /** 1253c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * Get the thread ID of the SMS message with the given URI 1254c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * @param context The context 1255c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * @param uri The URI of the SMS message 1256c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * @return The thread ID, or THREAD_NONE if the URI contains no entries 1257c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev */ 1258c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public static long getSmsThreadId(Context context, Uri uri) { 1259c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev Cursor cursor = SqliteWrapper.query( 1260c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev context, 1261c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev context.getContentResolver(), 1262c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev uri, 1263c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev SMS_THREAD_ID_PROJECTION, 1264c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev null, 1265c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev null, 1266c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev null); 1267c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 1268c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev if (cursor == null) { 1269c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev return THREAD_NONE; 1270c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 1271c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 1272c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev try { 1273c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev if (cursor.moveToFirst()) { 1274c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev return cursor.getLong(cursor.getColumnIndex(Sms.THREAD_ID)); 1275c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } else { 1276c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev return THREAD_NONE; 1277c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 1278c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } finally { 1279c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev cursor.close(); 1280c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 1281c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 1282c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 1283c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev /** 1284c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * Get the thread ID of the MMS message with the given URI 1285c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * @param context The context 1286c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * @param uri The URI of the SMS message 1287c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * @return The thread ID, or THREAD_NONE if the URI contains no entries 1288c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev */ 1289c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public static long getThreadId(Context context, Uri uri) { 1290c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev Cursor cursor = SqliteWrapper.query( 1291c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev context, 1292c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev context.getContentResolver(), 1293c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev uri, 1294c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev MMS_THREAD_ID_PROJECTION, 1295c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev null, 1296c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev null, 1297c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev null); 1298c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 1299c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev if (cursor == null) { 1300c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev return THREAD_NONE; 1301c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 1302c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 1303c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev try { 1304c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev if (cursor.moveToFirst()) { 1305c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev return cursor.getLong(cursor.getColumnIndex(Mms.THREAD_ID)); 1306c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } else { 1307c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev return THREAD_NONE; 1308c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 1309c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } finally { 1310c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev cursor.close(); 1311c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 1312c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 131372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project} 1314