MessagingNotification.java revision b0ef8fc2738b210a2bb0490e75eedc1e7b7b491f
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 2372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.R; 24812391ad832f3fdac054ad3a50af563da16e99b5Wei Huangimport com.android.mms.LogTag; 2533a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrickimport com.android.mms.data.Contact; 2670c73e05a792832aa28da751cdaf3fa83a7b8113Ficus Kirkpatrickimport com.android.mms.data.Conversation; 2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.ui.ComposeMessageActivity; 2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.ui.ConversationList; 2972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.ui.MessagingPreferenceActivity; 3072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.util.AddressUtils; 3172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.util.DownloadManager; 32c7aa632be8e7d3ebe71f236f534ea2f0af71e04aTom Taylorimport com.android.mms.widget.MmsWidgetProvider; 3372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 34f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.EncodedStringValue; 35f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduHeaders; 36f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduPersister; 37fd644551e8506266aad2b76463b51b44154ed62fTom Taylorimport android.database.sqlite.SqliteWrapper; 3872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 3972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.Notification; 4072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.NotificationManager; 4172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.PendingIntent; 421fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylorimport android.content.ComponentName; 4372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentResolver; 4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context; 4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Intent; 4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.SharedPreferences; 4770f5af8fd89d66ae246a805d10a50540746319aaWei Huangimport android.content.BroadcastReceiver; 4870f5af8fd89d66ae246a805d10a50540746319aaWei Huangimport android.content.IntentFilter; 4972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.Cursor; 5072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.graphics.Typeface; 51006d49271549ed639ffcd70d94c7650bb3514796Jim Shumaimport android.media.AudioManager; 5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri; 53b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylorimport android.os.AsyncTask; 545a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylorimport android.os.Handler; 5572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.preference.PreferenceManager; 56f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Mms; 57f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Sms; 5872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.Spannable; 5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.SpannableString; 6072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.TextUtils; 6172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.style.StyleSpan; 6272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log; 63800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERTimport android.widget.Toast; 6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.Comparator; 66b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrickimport java.util.HashSet; 67b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrickimport java.util.Set; 6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.SortedSet; 6972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.TreeSet; 7072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/** 7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * This class is used to update the notification indicator. It will check whether 7372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * there are unread messages. If yes, it would show the notification indicator, 7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * otherwise, hide the indicator. 7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 7672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class MessagingNotification { 77c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 78812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang private static final String TAG = LogTag.APP; 7972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int NOTIFICATION_ID = 123; 8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final int MESSAGE_FAILED_NOTIFICATION_ID = 789; 8272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final int DOWNLOAD_FAILED_NOTIFICATION_ID = 531; 83c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev /** 84c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * This is the volume at which to play the in-conversation notification sound, 85c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * expressed as a fraction of the system notification volume. 86c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev */ 87c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev private static final float IN_CONVERSATION_NOTIFICATION_VOLUME = 0.25f; 8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // This must be consistent with the column constants below. 9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String[] MMS_STATUS_PROJECTION = new String[] { 9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Mms.THREAD_ID, Mms.DATE, Mms._ID, Mms.SUBJECT, Mms.SUBJECT_CHARSET }; 9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // This must be consistent with the column constants below. 9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String[] SMS_STATUS_PROJECTION = new String[] { 9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.THREAD_ID, Sms.DATE, Sms.ADDRESS, Sms.SUBJECT, Sms.BODY }; 9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // These must be consistent with MMS_STATUS_PROJECTION and 9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // SMS_STATUS_PROJECTION. 9972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_THREAD_ID = 0; 10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_DATE = 1; 10172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_MMS_ID = 2; 10272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_SMS_ADDRESS = 2; 10372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_SUBJECT = 3; 10472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_SUBJECT_CS = 4; 10572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int COLUMN_SMS_BODY = 4; 10672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 107c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev private static final String[] SMS_THREAD_ID_PROJECTION = new String[] { Sms.THREAD_ID }; 108c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev private static final String[] MMS_THREAD_ID_PROJECTION = new String[] { Mms.THREAD_ID }; 109c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 11072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String NEW_INCOMING_SM_CONSTRAINT = 11172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project "(" + Sms.TYPE + " = " + Sms.MESSAGE_TYPE_INBOX 112627007213deb59ef938c80353c8f3598b01478b3Wei Huang + " AND " + Sms.SEEN + " = 0)"; 11372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 114800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT private static final String NEW_DELIVERY_SM_CONSTRAINT = 115c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor "(" + Sms.TYPE + " = " + Sms.MESSAGE_TYPE_SENT 116c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor + " AND " + Sms.STATUS + " = "+ Sms.STATUS_COMPLETE +")"; 117800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String NEW_INCOMING_MM_CONSTRAINT = 11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project "(" + Mms.MESSAGE_BOX + "=" + Mms.MESSAGE_BOX_INBOX 120627007213deb59ef938c80353c8f3598b01478b3Wei Huang + " AND " + Mms.SEEN + "=0" 12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + " AND (" + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_NOTIFICATION_IND 12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + " OR " + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_RETRIEVE_CONF + "))"; 12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final MmsSmsNotificationInfoComparator INFO_COMPARATOR = 12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project new MmsSmsNotificationInfoComparator(); 1265a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final Uri UNDELIVERED_URI = Uri.parse("content://mms-sms/undelivered"); 12872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 12970f5af8fd89d66ae246a805d10a50540746319aaWei Huang 13070f5af8fd89d66ae246a805d10a50540746319aaWei Huang private final static String NOTIFICATION_DELETED_ACTION = 13170f5af8fd89d66ae246a805d10a50540746319aaWei Huang "com.android.mms.NOTIFICATION_DELETED_ACTION"; 13270f5af8fd89d66ae246a805d10a50540746319aaWei Huang 13370f5af8fd89d66ae246a805d10a50540746319aaWei Huang public static class OnDeletedReceiver extends BroadcastReceiver { 134c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev @Override 13570f5af8fd89d66ae246a805d10a50540746319aaWei Huang public void onReceive(Context context, Intent intent) { 13670f5af8fd89d66ae246a805d10a50540746319aaWei Huang if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) { 13770f5af8fd89d66ae246a805d10a50540746319aaWei Huang Log.d(TAG, "[MessagingNotification] clear notification: mark all msgs seen"); 13870f5af8fd89d66ae246a805d10a50540746319aaWei Huang } 13970f5af8fd89d66ae246a805d10a50540746319aaWei Huang 14070f5af8fd89d66ae246a805d10a50540746319aaWei Huang Conversation.markAllConversationsAsSeen(context); 14170f5af8fd89d66ae246a805d10a50540746319aaWei Huang } 142c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 143c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 144c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public static final long THREAD_ALL = -1; 145c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public static final long THREAD_NONE = -2; 146c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev /** 147c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * Keeps track of the thread ID of the conversation that's currently displayed to the user 148c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev */ 149c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev private static long sCurrentlyDisplayedThreadId; 150c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev private static final Object sCurrentlyDisplayedThreadLock = new Object(); 151c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 15270f5af8fd89d66ae246a805d10a50540746319aaWei Huang private static OnDeletedReceiver sNotificationDeletedReceiver = new OnDeletedReceiver(); 15370f5af8fd89d66ae246a805d10a50540746319aaWei Huang private static Intent sNotificationOnDeleteIntent; 1545a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor private static Handler mToastHandler = new Handler(); 15570f5af8fd89d66ae246a805d10a50540746319aaWei Huang 15672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private MessagingNotification() { 15772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 15872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 15970f5af8fd89d66ae246a805d10a50540746319aaWei Huang public static void init(Context context) { 16070f5af8fd89d66ae246a805d10a50540746319aaWei Huang // set up the intent filter for notification deleted action 16170f5af8fd89d66ae246a805d10a50540746319aaWei Huang IntentFilter intentFilter = new IntentFilter(); 16270f5af8fd89d66ae246a805d10a50540746319aaWei Huang intentFilter.addAction(NOTIFICATION_DELETED_ACTION); 16370f5af8fd89d66ae246a805d10a50540746319aaWei Huang context.registerReceiver(sNotificationDeletedReceiver, intentFilter); 16470f5af8fd89d66ae246a805d10a50540746319aaWei Huang 16570f5af8fd89d66ae246a805d10a50540746319aaWei Huang // initialize the notification deleted action 16670f5af8fd89d66ae246a805d10a50540746319aaWei Huang sNotificationOnDeleteIntent = new Intent(NOTIFICATION_DELETED_ACTION); 16770f5af8fd89d66ae246a805d10a50540746319aaWei Huang } 16870f5af8fd89d66ae246a805d10a50540746319aaWei Huang 16972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 170c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * Specifies which message thread is currently being viewed by the user. New messages in that 171c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * thread will not generate a notification icon and will play the notification sound at a lower 172c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * volume. Make sure you set this to THREAD_NONE when the UI component that shows the thread is 173c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * no longer visible to the user (e.g. Activity.onPause(), etc.) 174c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * @param threadId The ID of the thread that the user is currently viewing. Pass THREAD_NONE 175c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * if the user is not viewing a thread, or THREAD_ALL if the user is viewing the conversation 176c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * list (note: that latter one has no effect as of this implementation) 177c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev */ 178c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public static void setCurrentlyDisplayedThreadId(long threadId) { 179c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev synchronized (sCurrentlyDisplayedThreadLock) { 180c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev sCurrentlyDisplayedThreadId = threadId; 181c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 182c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 183c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 184c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev /** 185627007213deb59ef938c80353c8f3598b01478b3Wei Huang * Checks to see if there are any "unseen" messages or delivery 18672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * reports. Shows the most recent notification if there is one. 1873b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor * Does its work and query in a worker thread. 18872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 18972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @param context the context to use 19072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 1913b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor public static void nonBlockingUpdateNewMessageIndicator(final Context context, 192c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev final long newMsgThreadId, 1933b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor final boolean isStatusMessage) { 1943b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor new Thread(new Runnable() { 195c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev @Override 1963b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor public void run() { 197c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev blockingUpdateNewMessageIndicator(context, newMsgThreadId, isStatusMessage); 1983b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor } 199ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev }, "MessagingNotification.nonBlockingUpdateNewMessageIndicator").start(); 20072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 20172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 20272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 203627007213deb59ef938c80353c8f3598b01478b3Wei Huang * Checks to see if there are any "unseen" messages or delivery 20472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * reports. Shows the most recent notification if there is one. 20572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 20672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @param context the context to use 207c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * @param newMsgThreadId The thread ID of a new message that we're to notify about; if there's 208c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * no new message, use THREAD_NONE. If we should notify about multiple or unknown thread IDs, 209c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * use THREAD_ALL. 210c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * @param isStatusMessage 21172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 212c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public static void blockingUpdateNewMessageIndicator(Context context, long newMsgThreadId, 213c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor boolean isStatusMessage) { 214c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev synchronized (sCurrentlyDisplayedThreadLock) { 215c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev if (newMsgThreadId > 0 && newMsgThreadId == sCurrentlyDisplayedThreadId) { 216c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev playInConversationNotificationSound(context); 217c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev return; 218c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 219c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 220c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 22172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SortedSet<MmsSmsNotificationInfo> accumulator = 22272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project new TreeSet<MmsSmsNotificationInfo>(INFO_COMPARATOR); 223c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor MmsSmsDeliveryInfo delivery = null; 224b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick Set<Long> threads = new HashSet<Long>(4); 2255a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int count = 0; 22772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project count += accumulateNotificationInfo( 228b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick accumulator, getMmsNewMessageNotificationInfo(context, threads)); 22972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project count += accumulateNotificationInfo( 230b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick accumulator, getSmsNewMessageNotificationInfo(context, threads)); 23172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 23272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cancelNotification(context, NOTIFICATION_ID); 23372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!accumulator.isEmpty()) { 234e14b79584cca1bf7ba60c53bd7e3d6386adbfc59Wei Huang if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) { 235e14b79584cca1bf7ba60c53bd7e3d6386adbfc59Wei Huang Log.d(TAG, "blockingUpdateNewMessageIndicator: count=" + count + 236c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev ", newMsgThreadId=" + newMsgThreadId); 237e14b79584cca1bf7ba60c53bd7e3d6386adbfc59Wei Huang } 238c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev accumulator.first().deliver(context, newMsgThreadId != THREAD_NONE, count, threads.size()); 23972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 2405a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 2413b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor // And deals with delivery reports (which use Toasts). It's safe to call in a worker 2423b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor // thread because the toast will eventually get posted to a handler. 243627007213deb59ef938c80353c8f3598b01478b3Wei Huang delivery = getSmsNewDeliveryInfo(context); 244627007213deb59ef938c80353c8f3598b01478b3Wei Huang if (delivery != null) { 245c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor delivery.deliver(context, isStatusMessage); 246627007213deb59ef938c80353c8f3598b01478b3Wei Huang } 24772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 24872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 24972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 250c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * Play the in-conversation notification sound (it's the regular notification sound, but 251c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * played at half-volume 252c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev */ 253c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev private static void playInConversationNotificationSound(Context context) { 254c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev final AudioManager audioManager = 255c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 256c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 257c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); 258c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev String ringtoneStr = sp.getString(MessagingPreferenceActivity.NOTIFICATION_RINGTONE, 259c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev null); 260c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev if (TextUtils.isEmpty(ringtoneStr)) { 261c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev // Nothing to play 262c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev return; 263c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 264c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev Uri ringtoneUri = Uri.parse(ringtoneStr); 265c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev NotificationPlayer player = new NotificationPlayer(LogTag.APP); 266c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev player.play(context, ringtoneUri, false, AudioManager.STREAM_NOTIFICATION, 267c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev IN_CONVERSATION_NOTIFICATION_VOLUME); 268c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 269c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 270c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev /** 27135a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick * Updates all pending notifications, clearing or updating them as 2723b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor * necessary. 27335a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick */ 274627007213deb59ef938c80353c8f3598b01478b3Wei Huang public static void blockingUpdateAllNotifications(final Context context) { 275c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev nonBlockingUpdateNewMessageIndicator(context, THREAD_NONE, false); 276b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor nonBlockingUpdateSendFailedNotification(context); 277627007213deb59ef938c80353c8f3598b01478b3Wei Huang updateDownloadFailedNotification(context); 278c7aa632be8e7d3ebe71f236f534ea2f0af71e04aTom Taylor MmsWidgetProvider.notifyDatasetChanged(context); 27935a74a9e0ee7c171c6e17f0eda4b0df0253f8364Ficus Kirkpatrick } 2805a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 28172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int accumulateNotificationInfo( 282c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev SortedSet<MmsSmsNotificationInfo> set, MmsSmsNotificationInfo info) { 28372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (info != null) { 28472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project set.add(info); 28572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 28672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return info.mCount; 28772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 28872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 28972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return 0; 29072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 29172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 292800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT private static final class MmsSmsDeliveryInfo { 293c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor public CharSequence mTicker; 294c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor public long mTimeMillis; 295c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor 296c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor public MmsSmsDeliveryInfo(CharSequence ticker, long timeMillis) { 297c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor mTicker = ticker; 298c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor mTimeMillis = timeMillis; 299c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor } 300c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor 301c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor public void deliver(Context context, boolean isStatusMessage) { 302c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor updateDeliveryNotification( 303c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor context, isStatusMessage, mTicker, mTimeMillis); 304c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor } 305800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT } 306800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 30772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final class MmsSmsNotificationInfo { 308c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public final Intent mClickIntent; 309c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public final String mDescription; 310c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public final int mIconResourceId; 311c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public final CharSequence mTicker; 312c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public final long mTimeMillis; 313c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public final String mTitle; 314c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public final int mCount; 31572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 31672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public MmsSmsNotificationInfo( 31772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent clickIntent, String description, int iconResourceId, 31872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project CharSequence ticker, long timeMillis, String title, int count) { 31972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mClickIntent = clickIntent; 32072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mDescription = description; 32172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mIconResourceId = iconResourceId; 32272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mTicker = ticker; 32372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mTimeMillis = timeMillis; 32472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mTitle = title; 32572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mCount = count; 32672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 32772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 328b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick public void deliver(Context context, boolean isNew, int count, int uniqueThreads) { 32972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project updateNotification( 3303c68b6852913222dd982dddd4e39b3e57613c37eWei Huang context, mClickIntent, mDescription, mIconResourceId, isNew, 3313c68b6852913222dd982dddd4e39b3e57613c37eWei Huang (isNew? mTicker : null), // only display the ticker if the message is new 3323c68b6852913222dd982dddd4e39b3e57613c37eWei Huang mTimeMillis, mTitle, count, uniqueThreads); 33372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 33472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 33572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public long getTime() { 33672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return mTimeMillis; 33772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 33872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 33972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 34072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final class MmsSmsNotificationInfoComparator 34172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project implements Comparator<MmsSmsNotificationInfo> { 342c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev @Override 34372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public int compare( 34472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project MmsSmsNotificationInfo info1, MmsSmsNotificationInfo info2) { 34572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return Long.signum(info2.getTime() - info1.getTime()); 34672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 34772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 34872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 3493b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor private static final MmsSmsNotificationInfo getMmsNewMessageNotificationInfo( 350b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick Context context, Set<Long> threads) { 35172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContentResolver resolver = context.getContentResolver(); 3523b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor 3533b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor // This query looks like this when logged: 3543b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor // I/Database( 147): elapsedTime4Sql|/data/data/com.android.providers.telephony/databases/ 3553b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor // mmssms.db|0.362 ms|SELECT thread_id, date, _id, sub, sub_cs FROM pdu WHERE ((msg_box=1 3563b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor // AND seen=0 AND (m_type=130 OR m_type=132))) ORDER BY date desc 3573b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor 35872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor cursor = SqliteWrapper.query(context, resolver, Mms.CONTENT_URI, 35972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project MMS_STATUS_PROJECTION, NEW_INCOMING_MM_CONSTRAINT, 36072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project null, Mms.DATE + " desc"); 36172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 362b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick if (cursor == null) { 363b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick return null; 364b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick } 3655a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 366b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick try { 367b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick if (!cursor.moveToFirst()) { 368b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick return null; 36972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 370c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 371b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick long msgId = cursor.getLong(COLUMN_MMS_ID); 372b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick Uri msgUri = Mms.CONTENT_URI.buildUpon().appendPath( 373b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick Long.toString(msgId)).build(); 374b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick String address = AddressUtils.getFrom(context, msgUri); 3751b8df494e49bf934fe160baea54ab5afc2ff3100Tom Taylor 3761b8df494e49bf934fe160baea54ab5afc2ff3100Tom Taylor Contact contact = Contact.get(address, false); 3771b8df494e49bf934fe160baea54ab5afc2ff3100Tom Taylor if (contact.getSendToVoicemail()) { 3781b8df494e49bf934fe160baea54ab5afc2ff3100Tom Taylor // don't notify 3791b8df494e49bf934fe160baea54ab5afc2ff3100Tom Taylor return null; 3801b8df494e49bf934fe160baea54ab5afc2ff3100Tom Taylor } 3811b8df494e49bf934fe160baea54ab5afc2ff3100Tom Taylor 382b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick String subject = getMmsSubject( 383b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick cursor.getString(COLUMN_SUBJECT), cursor.getInt(COLUMN_SUBJECT_CS)); 384b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick long threadId = cursor.getLong(COLUMN_THREAD_ID); 385b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick long timeMillis = cursor.getLong(COLUMN_DATE) * 1000; 386b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick 387e14b79584cca1bf7ba60c53bd7e3d6386adbfc59Wei Huang if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) { 388e14b79584cca1bf7ba60c53bd7e3d6386adbfc59Wei Huang Log.d(TAG, "getMmsNewMessageNotificationInfo: count=" + cursor.getCount() + 389e14b79584cca1bf7ba60c53bd7e3d6386adbfc59Wei Huang ", first addr = " + address + ", thread_id=" + threadId); 390e14b79584cca1bf7ba60c53bd7e3d6386adbfc59Wei Huang } 391e14b79584cca1bf7ba60c53bd7e3d6386adbfc59Wei Huang 392b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick MmsSmsNotificationInfo info = getNewMessageNotificationInfo( 393b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick address, subject, context, 394b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick R.drawable.stat_notify_mms, null, threadId, 395b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick timeMillis, cursor.getCount()); 396b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick 397b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick threads.add(threadId); 398b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick while (cursor.moveToNext()) { 399b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick threads.add(cursor.getLong(COLUMN_THREAD_ID)); 400b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick } 401b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick 402b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick return info; 403b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick } finally { 404b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick cursor.close(); 40572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 40672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 40772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 4083b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor private static final MmsSmsDeliveryInfo getSmsNewDeliveryInfo(Context context) { 409627007213deb59ef938c80353c8f3598b01478b3Wei Huang ContentResolver resolver = context.getContentResolver(); 410627007213deb59ef938c80353c8f3598b01478b3Wei Huang Cursor cursor = SqliteWrapper.query(context, resolver, Sms.CONTENT_URI, 411627007213deb59ef938c80353c8f3598b01478b3Wei Huang SMS_STATUS_PROJECTION, NEW_DELIVERY_SM_CONSTRAINT, 4126a9c779f0c0dc6cf3ae942ff70fb6c806aa166dcBanavathu, Srinivas Naik null, Sms.DATE); 413800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 414ac9a5e52dc349faae2a7d8a990ff2b674c61f027Alexander Blom if (cursor == null) { 415627007213deb59ef938c80353c8f3598b01478b3Wei Huang return null; 416ac9a5e52dc349faae2a7d8a990ff2b674c61f027Alexander Blom } 417800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 418627007213deb59ef938c80353c8f3598b01478b3Wei Huang try { 419ac9a5e52dc349faae2a7d8a990ff2b674c61f027Alexander Blom if (!cursor.moveToLast()) { 420ac9a5e52dc349faae2a7d8a990ff2b674c61f027Alexander Blom return null; 421ac9a5e52dc349faae2a7d8a990ff2b674c61f027Alexander Blom } 422800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 423627007213deb59ef938c80353c8f3598b01478b3Wei Huang String address = cursor.getString(COLUMN_SMS_ADDRESS); 424627007213deb59ef938c80353c8f3598b01478b3Wei Huang long timeMillis = 3000; 425800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 426ac9a5e52dc349faae2a7d8a990ff2b674c61f027Alexander Blom Contact contact = Contact.get(address, false); 427ac9a5e52dc349faae2a7d8a990ff2b674c61f027Alexander Blom String name = contact.getNameAndNumber(); 428ac9a5e52dc349faae2a7d8a990ff2b674c61f027Alexander Blom 429ac9a5e52dc349faae2a7d8a990ff2b674c61f027Alexander Blom return new MmsSmsDeliveryInfo(context.getString(R.string.delivery_toast_body, name), 430627007213deb59ef938c80353c8f3598b01478b3Wei Huang timeMillis); 431800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 432627007213deb59ef938c80353c8f3598b01478b3Wei Huang } finally { 433627007213deb59ef938c80353c8f3598b01478b3Wei Huang cursor.close(); 434627007213deb59ef938c80353c8f3598b01478b3Wei Huang } 435800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT } 436800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 4373b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor private static final MmsSmsNotificationInfo getSmsNewMessageNotificationInfo( 438b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick Context context, Set<Long> threads) { 43972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContentResolver resolver = context.getContentResolver(); 44072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor cursor = SqliteWrapper.query(context, resolver, Sms.CONTENT_URI, 44172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SMS_STATUS_PROJECTION, NEW_INCOMING_SM_CONSTRAINT, 44272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project null, Sms.DATE + " desc"); 44372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 444b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick if (cursor == null) { 445b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick return null; 446b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick } 4475a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 448b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick try { 449b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick if (!cursor.moveToFirst()) { 450b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick return null; 451b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick } 452b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick 453b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick String address = cursor.getString(COLUMN_SMS_ADDRESS); 4541b8df494e49bf934fe160baea54ab5afc2ff3100Tom Taylor 4551b8df494e49bf934fe160baea54ab5afc2ff3100Tom Taylor Contact contact = Contact.get(address, false); 4561b8df494e49bf934fe160baea54ab5afc2ff3100Tom Taylor if (contact.getSendToVoicemail()) { 4571b8df494e49bf934fe160baea54ab5afc2ff3100Tom Taylor // don't notify 4581b8df494e49bf934fe160baea54ab5afc2ff3100Tom Taylor return null; 4591b8df494e49bf934fe160baea54ab5afc2ff3100Tom Taylor } 4601b8df494e49bf934fe160baea54ab5afc2ff3100Tom Taylor 461b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick String body = cursor.getString(COLUMN_SMS_BODY); 462b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick long threadId = cursor.getLong(COLUMN_THREAD_ID); 463b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick long timeMillis = cursor.getLong(COLUMN_DATE); 464b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick 465d83675687b1ef742c33bffe8195d7b1852c2c01dTom Taylor if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) 466e14b79584cca1bf7ba60c53bd7e3d6386adbfc59Wei Huang { 467e14b79584cca1bf7ba60c53bd7e3d6386adbfc59Wei Huang Log.d(TAG, "getSmsNewMessageNotificationInfo: count=" + cursor.getCount() + 468e14b79584cca1bf7ba60c53bd7e3d6386adbfc59Wei Huang ", first addr=" + address + ", thread_id=" + threadId); 469e14b79584cca1bf7ba60c53bd7e3d6386adbfc59Wei Huang } 470e14b79584cca1bf7ba60c53bd7e3d6386adbfc59Wei Huang 471b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick MmsSmsNotificationInfo info = getNewMessageNotificationInfo( 472b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick address, body, context, R.drawable.stat_notify_sms, 473b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick null, threadId, timeMillis, cursor.getCount()); 474b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick 475b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick threads.add(threadId); 476b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick while (cursor.moveToNext()) { 477b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick threads.add(cursor.getLong(COLUMN_THREAD_ID)); 47872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 479b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick 480b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick return info; 481b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick } finally { 482b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick cursor.close(); 48372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 48472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 48572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 48672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final MmsSmsNotificationInfo getNewMessageNotificationInfo( 48772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String address, 48872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String body, 48972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Context context, 49072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int iconResourceId, 49172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String subject, 49272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long threadId, 49372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long timeMillis, 49472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int count) { 495812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang Intent clickIntent = ComposeMessageActivity.createIntent(context, threadId); 496812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang clickIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 497812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang | Intent.FLAG_ACTIVITY_SINGLE_TOP 498812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang | Intent.FLAG_ACTIVITY_CLEAR_TOP); 49972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 50072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String senderInfo = buildTickerMessage( 50172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context, address, null, null).toString(); 50272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String senderInfoName = senderInfo.substring( 50372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 0, senderInfo.length() - 2); 50472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project CharSequence ticker = buildTickerMessage( 50572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context, address, subject, body); 50672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 50772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return new MmsSmsNotificationInfo( 50872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project clickIntent, body, iconResourceId, ticker, timeMillis, 50972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project senderInfoName, count); 51072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 51172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 51272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static void cancelNotification(Context context, int notificationId) { 51372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project NotificationManager nm = (NotificationManager) context.getSystemService( 51472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Context.NOTIFICATION_SERVICE); 51572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 51672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project nm.cancel(notificationId); 51772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 51872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 5195a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor private static void updateDeliveryNotification(final Context context, 520c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor boolean isStatusMessage, 5215a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor final CharSequence message, 5225a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor final long timeMillis) { 523c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor if (!isStatusMessage) { 524c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor return; 525c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor } 526c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor 527800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 528d83675687b1ef742c33bffe8195d7b1852c2c01dTom Taylor if (!MessagingPreferenceActivity.getNotificationEnabled(context)) { 52970f5af8fd89d66ae246a805d10a50540746319aaWei Huang return; 53070f5af8fd89d66ae246a805d10a50540746319aaWei Huang } 531800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 532c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor mToastHandler.post(new Runnable() { 533c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev @Override 534c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor public void run() { 535c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor Toast.makeText(context, message, (int)timeMillis).show(); 536c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor } 537c36deab7d27940a07554cc424114d9c9ddd36552Tom Taylor }); 538800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT } 539800f2ac17e15b24e93158574649e821a334c491eAlexis ROBERT 54072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static void updateNotification( 54172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Context context, 54272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent clickIntent, 54372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String description, 54472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int iconRes, 54572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project boolean isNew, 54672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project CharSequence ticker, 54772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long timeMillis, 54872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String title, 549b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick int messageCount, 550b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick int uniqueThreadCount) { 551d83675687b1ef742c33bffe8195d7b1852c2c01dTom Taylor if (!MessagingPreferenceActivity.getNotificationEnabled(context)) { 55272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 55372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 55472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 555b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick Notification notification = new Notification(iconRes, ticker, timeMillis); 5561fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor Intent[] intents; 557b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick 558b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick // If we have more than one unique thread, change the title (which would 559b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick // normally be the contact who sent the message) to a generic one that 560b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick // makes sense for multiple senders, and change the Intent to take the 561b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick // user to the conversation list instead of the specific thread. 562b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick if (uniqueThreadCount > 1) { 563b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick title = context.getString(R.string.notification_multiple_title); 5641fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor Intent mainActivityIntent = new Intent(Intent.ACTION_MAIN); 565812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang 5661fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor mainActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 567812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang | Intent.FLAG_ACTIVITY_SINGLE_TOP 568812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang | Intent.FLAG_ACTIVITY_CLEAR_TOP); 569812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang 5701fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor mainActivityIntent.setType("vnd.android-dir/mms-sms"); 5711fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor intents = new Intent[1]; 5721fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor intents[0] = mainActivityIntent; 5731fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor } else { 5741fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor // Build a stack of intents so when the user hits back from the ComposeMessageActivity 5751fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor // we're sending them to, they'll up on ConversationList. 5761fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor intents = new Intent[2]; 5771fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor 5781fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor // First: root activity of the MessagingApp: ConversationList. 5791fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor // This is a convenient way to make the proper Intent to launch and 5801fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor // reset an application's task. 5811fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor intents[0] = Intent.makeRestartActivityTask(new ComponentName(context, 5821fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor ConversationList.class)); 5831fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor intents[1] = clickIntent; 584b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick } 5855a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 586b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick // If there is more than one message, change the description (which 587b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick // would normally be a snippet of the individual message text) to 588627007213deb59ef938c80353c8f3598b01478b3Wei Huang // a string indicating how many "unseen" messages there are. 589b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick if (messageCount > 1) { 590b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick description = context.getString(R.string.notification_multiple, 591b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick Integer.toString(messageCount)); 592b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick } 59372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 594b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick // Make a startActivity() PendingIntent for the notification. 5951fdc24a996e1c2d6a1add1f40260c5e0380f3112Tom Taylor PendingIntent pendingIntent = PendingIntent.getActivities(context, 0, intents, 596810fae756f4d2db00b35d7c9dfead252737abdacTom Taylor PendingIntent.FLAG_UPDATE_CURRENT); 59772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 598b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick // Update the notification. 599b11a5086727c4b67c72ca605771fb37e12dcf803Ficus Kirkpatrick notification.setLatestEventInfo(context, title, description, pendingIntent); 60072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 60172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isNew) { 602d83675687b1ef742c33bffe8195d7b1852c2c01dTom Taylor SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); 603006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma String vibrateWhen; 604006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma if (sp.contains(MessagingPreferenceActivity.NOTIFICATION_VIBRATE_WHEN)) { 605006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma vibrateWhen = 606006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma sp.getString(MessagingPreferenceActivity.NOTIFICATION_VIBRATE_WHEN, null); 607006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma } else if (sp.contains(MessagingPreferenceActivity.NOTIFICATION_VIBRATE)) { 608006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma vibrateWhen = sp.getBoolean(MessagingPreferenceActivity.NOTIFICATION_VIBRATE, false) ? 609006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma context.getString(R.string.prefDefault_vibrate_true) : 610006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma context.getString(R.string.prefDefault_vibrate_false); 611006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma } else { 612006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma vibrateWhen = context.getString(R.string.prefDefault_vibrateWhen); 613006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma } 614006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma 615006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma boolean vibrateAlways = vibrateWhen.equals("always"); 616006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma boolean vibrateSilent = vibrateWhen.equals("silent"); 617006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma AudioManager audioManager = 618006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma (AudioManager)context.getSystemService(Context.AUDIO_SERVICE); 619006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma boolean nowSilent = 620006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma audioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE; 621006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma 622006d49271549ed639ffcd70d94c7650bb3514796Jim Shuma if (vibrateAlways || vibrateSilent && nowSilent) { 62372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.defaults |= Notification.DEFAULT_VIBRATE; 62472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 62572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 626627007213deb59ef938c80353c8f3598b01478b3Wei Huang String ringtoneStr = sp.getString(MessagingPreferenceActivity.NOTIFICATION_RINGTONE, 627627007213deb59ef938c80353c8f3598b01478b3Wei Huang null); 62872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.sound = TextUtils.isEmpty(ringtoneStr) ? null : Uri.parse(ringtoneStr); 62972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 63072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 63172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.flags |= Notification.FLAG_SHOW_LIGHTS; 6325227290bbaefe2438cac9b3868a72a12a3339e83Mike Lockwood notification.defaults |= Notification.DEFAULT_LIGHTS; 63372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 63470f5af8fd89d66ae246a805d10a50540746319aaWei Huang // set up delete intent 63570f5af8fd89d66ae246a805d10a50540746319aaWei Huang notification.deleteIntent = PendingIntent.getBroadcast(context, 0, 63670f5af8fd89d66ae246a805d10a50540746319aaWei Huang sNotificationOnDeleteIntent, 0); 63770f5af8fd89d66ae246a805d10a50540746319aaWei Huang 63872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project NotificationManager nm = (NotificationManager) 63972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context.getSystemService(Context.NOTIFICATION_SERVICE); 64072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 64172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project nm.notify(NOTIFICATION_ID, notification); 64272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 64372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 64472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected static CharSequence buildTickerMessage( 64572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Context context, String address, String subject, String body) { 64633a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick String displayAddress = Contact.get(address, true).getName(); 6475a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 64872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project StringBuilder buf = new StringBuilder( 64972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project displayAddress == null 65072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ? "" 65172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project : displayAddress.replace('\n', ' ').replace('\r', ' ')); 65272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project buf.append(':').append(' '); 65372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 65472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int offset = buf.length(); 65572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!TextUtils.isEmpty(subject)) { 65672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project subject = subject.replace('\n', ' ').replace('\r', ' '); 65772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project buf.append(subject); 65872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project buf.append(' '); 65972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 66072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 66172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!TextUtils.isEmpty(body)) { 66272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project body = body.replace('\n', ' ').replace('\r', ' '); 66372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project buf.append(body); 66472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 66572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 66672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SpannableString spanText = new SpannableString(buf.toString()); 66772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project spanText.setSpan(new StyleSpan(Typeface.BOLD), 0, offset, 66872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 66972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 67072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return spanText; 67172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 67272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 67372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static String getMmsSubject(String sub, int charset) { 67472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return TextUtils.isEmpty(sub) ? "" 67572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project : new EncodedStringValue(charset, PduPersister.getBytes(sub)).getString(); 67672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 67772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 67872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static void notifyDownloadFailed(Context context, long threadId) { 679b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick notifyFailed(context, true, threadId, false); 68072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 68172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 6825d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project public static void notifySendFailed(Context context) { 683b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick notifyFailed(context, false, 0, false); 68472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 68572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 686b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick public static void notifySendFailed(Context context, boolean noisy) { 687b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick notifyFailed(context, false, 0, noisy); 688b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick } 6895a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 690b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick private static void notifyFailed(Context context, boolean isDownload, long threadId, 691b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick boolean noisy) { 69272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO factor out common code for creating notifications 693d83675687b1ef742c33bffe8195d7b1852c2c01dTom Taylor boolean enabled = MessagingPreferenceActivity.getNotificationEnabled(context); 69472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!enabled) { 69572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 69672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 69772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 69872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project NotificationManager nm = (NotificationManager) 69972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context.getSystemService(Context.NOTIFICATION_SERVICE); 7005a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 70172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Strategy: 70272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // a. If there is a single failure notification, tapping on the notification goes 70372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // to the compose view. 7045a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor // b. If there are two failure it stays in the thread view. Selecting one undelivered 70572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // thread will dismiss one undelivered notification but will still display the 70672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // notification.If you select the 2nd undelivered one it will dismiss the notification. 7075a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 7087015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev long[] msgThreadId = {0, 1}; // Dummy initial values, just to initialize the memory 70972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int totalFailedCount = getUndeliveredMessageCount(context, msgThreadId); 7107015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev if (totalFailedCount == 0 && !isDownload) { 7117015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev return; 7127015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev } 7137015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev // The getUndeliveredMessageCount method puts a non-zero value in msgThreadId[1] if all 7147015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev // failures are from the same thread. 7157015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev // If isDownload is true, we're dealing with 1 specific failure; therefore "all failed" are 7167015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev // indeed in the same thread since there's only 1. 7177015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev boolean allFailedInSameThread = (msgThreadId[1] != 0) || isDownload; 7185a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 71972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent failedIntent; 72072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Notification notification = new Notification(); 72172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String title; 72272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String description; 72372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (totalFailedCount > 1) { 72472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project description = context.getString(R.string.notification_failed_multiple, 72572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Integer.toString(totalFailedCount)); 72672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project title = context.getString(R.string.notification_failed_multiple_title); 72772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 72872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project title = isDownload ? 72972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context.getString(R.string.message_download_failed_title) : 73072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context.getString(R.string.message_send_failed_title); 7315a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 73272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project description = context.getString(R.string.message_failed_body); 7337015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev } 7347015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev 7357015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev if (allFailedInSameThread) { 736836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project failedIntent = new Intent(context, ComposeMessageActivity.class); 73795817b166d415114bac89ca0946c3717ae229526Tom Taylor if (isDownload) { 73895817b166d415114bac89ca0946c3717ae229526Tom Taylor // When isDownload is true, the valid threadId is passed into this function. 73995817b166d415114bac89ca0946c3717ae229526Tom Taylor failedIntent.putExtra("failed_download_flag", true); 74095817b166d415114bac89ca0946c3717ae229526Tom Taylor } else { 7417015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev threadId = msgThreadId[0]; 74295817b166d415114bac89ca0946c3717ae229526Tom Taylor failedIntent.putExtra("undelivered_flag", true); 7435a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor } 7445a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor failedIntent.putExtra("thread_id", threadId); 7457015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev } else { 7467015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev failedIntent = new Intent(context, ConversationList.class); 74772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 74872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 749b92b26763e49fd9cc34d382dee4d764ef163bde5Ficus Kirkpatrick failedIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); 75072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PendingIntent pendingIntent = PendingIntent.getActivity( 751810fae756f4d2db00b35d7c9dfead252737abdacTom Taylor context, 0, failedIntent, PendingIntent.FLAG_UPDATE_CURRENT); 75272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 75372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.icon = R.drawable.stat_notify_sms_failed; 75472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 75572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.tickerText = title; 75672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 75772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notification.setLatestEventInfo(context, title, description, pendingIntent); 75872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 759b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick if (noisy) { 760d83675687b1ef742c33bffe8195d7b1852c2c01dTom Taylor SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); 761e3baaa51cd25b52c7a24e381319926b9da00abdfWei Huang boolean vibrate = sp.getBoolean(MessagingPreferenceActivity.NOTIFICATION_VIBRATE, 762e3baaa51cd25b52c7a24e381319926b9da00abdfWei Huang false /* don't vibrate by default */); 763b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick if (vibrate) { 764b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick notification.defaults |= Notification.DEFAULT_VIBRATE; 765b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick } 76672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 767e3baaa51cd25b52c7a24e381319926b9da00abdfWei Huang String ringtoneStr = sp.getString(MessagingPreferenceActivity.NOTIFICATION_RINGTONE, 768e3baaa51cd25b52c7a24e381319926b9da00abdfWei Huang null); 769b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick notification.sound = TextUtils.isEmpty(ringtoneStr) ? null : Uri.parse(ringtoneStr); 770b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick } 7715a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 77272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isDownload) { 77372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project nm.notify(DOWNLOAD_FAILED_NOTIFICATION_ID, notification); 77472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 77572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project nm.notify(MESSAGE_FAILED_NOTIFICATION_ID, notification); 77672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 77772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 7785a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 7797015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev /** 7807015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev * Query the DB and return the number of undelivered messages (total for both SMS and MMS) 7817015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev * @param context The context 7827015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev * @param threadIdResult A container to put the result in, according to the following rules: 7837015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev * threadIdResult[0] contains the thread id of the first message. 7847015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev * threadIdResult[1] is nonzero if the thread ids of all the messages are the same. 7857015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev * You can pass in null for threadIdResult. 7867015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev * You can pass in a threadIdResult of size 1 to avoid the comparison of each thread id. 7877015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev */ 78872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static int getUndeliveredMessageCount(Context context, long[] threadIdResult) { 78972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor undeliveredCursor = SqliteWrapper.query(context, context.getContentResolver(), 790c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev UNDELIVERED_URI, MMS_THREAD_ID_PROJECTION, "read=0", null, null); 79172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (undeliveredCursor == null) { 79272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return 0; 79372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 79472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int count = undeliveredCursor.getCount(); 79572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 79672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (threadIdResult != null && undeliveredCursor.moveToFirst()) { 79772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project threadIdResult[0] = undeliveredCursor.getLong(0); 7985a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 7992f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project if (threadIdResult.length >= 2) { 8002f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project // Test to see if all the undelivered messages belong to the same thread. 8012f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project long firstId = threadIdResult[0]; 8022f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project while (undeliveredCursor.moveToNext()) { 8032f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project if (undeliveredCursor.getLong(0) != firstId) { 8042f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project firstId = 0; 8052f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project break; 8062f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project } 8072f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project } 8082f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project threadIdResult[1] = firstId; // non-zero if all ids are the same 8092f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project } 81072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 81172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 81272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project undeliveredCursor.close(); 81372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 81472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return count; 81572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 81672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 817b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor public static void nonBlockingUpdateSendFailedNotification(final Context context) { 818b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor new AsyncTask<Void, Void, Integer>() { 819b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor protected Integer doInBackground(Void... none) { 820b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor return getUndeliveredMessageCount(context, null); 821b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor } 822b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor 823b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor protected void onPostExecute(Integer result) { 824b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor if (result < 1) { 825b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor cancelNotification(context, MESSAGE_FAILED_NOTIFICATION_ID); 826b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor } else { 827b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor // rebuild and adjust the message count if necessary. 828b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor notifySendFailed(context); 829b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor } 830b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor } 831b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor }.execute(); 83272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 8335a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 8345a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor /** 8352f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project * If all the undelivered messages belong to "threadId", cancel the notification. 8362f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project */ 8372f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project public static void updateSendFailedNotificationForThread(Context context, long threadId) { 8382f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project long[] msgThreadId = {0, 0}; 8395a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor if (getUndeliveredMessageCount(context, msgThreadId) > 0 8402f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project && msgThreadId[0] == threadId 8412f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project && msgThreadId[1] != 0) { 8422f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project cancelNotification(context, MESSAGE_FAILED_NOTIFICATION_ID); 8432f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project } 8442f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project } 8455a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 84672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static int getDownloadFailedMessageCount(Context context) { 84772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Look for any messages in the MMS Inbox that are of the type 84872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // NOTIFICATION_IND (i.e. not already downloaded) and in the 84972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // permanent failure state. If there are none, cancel any 85072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // failed download notification. 85172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor c = SqliteWrapper.query(context, context.getContentResolver(), 85272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Mms.Inbox.CONTENT_URI, null, 85372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Mms.MESSAGE_TYPE + "=" + 85472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String.valueOf(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) + 85572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project " AND " + Mms.STATUS + "=" + 85672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String.valueOf(DownloadManager.STATE_PERMANENT_FAILURE), 85772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project null, null); 85872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (c == null) { 85972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return 0; 86072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 86172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int count = c.getCount(); 86272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project c.close(); 86372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return count; 86472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 86572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 86672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static void updateDownloadFailedNotification(Context context) { 86772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (getDownloadFailedMessageCount(context) < 1) { 86872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cancelNotification(context, DOWNLOAD_FAILED_NOTIFICATION_ID); 86972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 87072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 8715a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 87295817b166d415114bac89ca0946c3717ae229526Tom Taylor public static boolean isFailedToDeliver(Intent intent) { 87395817b166d415114bac89ca0946c3717ae229526Tom Taylor return (intent != null) && intent.getBooleanExtra("undelivered_flag", false); 87495817b166d415114bac89ca0946c3717ae229526Tom Taylor } 87595817b166d415114bac89ca0946c3717ae229526Tom Taylor 87695817b166d415114bac89ca0946c3717ae229526Tom Taylor public static boolean isFailedToDownload(Intent intent) { 87795817b166d415114bac89ca0946c3717ae229526Tom Taylor return (intent != null) && intent.getBooleanExtra("failed_download_flag", false); 87895817b166d415114bac89ca0946c3717ae229526Tom Taylor } 879c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 880c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev /** 881c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * Get the thread ID of the SMS message with the given URI 882c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * @param context The context 883c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * @param uri The URI of the SMS message 884c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * @return The thread ID, or THREAD_NONE if the URI contains no entries 885c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev */ 886c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public static long getSmsThreadId(Context context, Uri uri) { 887c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev Cursor cursor = SqliteWrapper.query( 888c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev context, 889c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev context.getContentResolver(), 890c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev uri, 891c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev SMS_THREAD_ID_PROJECTION, 892c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev null, 893c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev null, 894c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev null); 895c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 896c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev if (cursor == null) { 897c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev return THREAD_NONE; 898c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 899c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 900c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev try { 901c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev if (cursor.moveToFirst()) { 902c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev return cursor.getLong(cursor.getColumnIndex(Sms.THREAD_ID)); 903c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } else { 904c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev return THREAD_NONE; 905c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 906c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } finally { 907c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev cursor.close(); 908c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 909c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 910c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 911c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev /** 912c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * Get the thread ID of the MMS message with the given URI 913c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * @param context The context 914c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * @param uri The URI of the SMS message 915c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev * @return The thread ID, or THREAD_NONE if the URI contains no entries 916c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev */ 917c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev public static long getThreadId(Context context, Uri uri) { 918c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev Cursor cursor = SqliteWrapper.query( 919c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev context, 920c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev context.getContentResolver(), 921c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev uri, 922c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev MMS_THREAD_ID_PROJECTION, 923c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev null, 924c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev null, 925c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev null); 926c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 927c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev if (cursor == null) { 928c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev return THREAD_NONE; 929c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 930c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev 931c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev try { 932c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev if (cursor.moveToFirst()) { 933c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev return cursor.getLong(cursor.getColumnIndex(Mms.THREAD_ID)); 934c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } else { 935c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev return THREAD_NONE; 936c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 937c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } finally { 938c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev cursor.close(); 939c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 940c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev } 94172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project} 942