172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/* 272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2007-2008 Esmertec AG. 372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2007-2008 The Android Open Source Project 472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * you may not use this file except in compliance with the License. 772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * You may obtain a copy of the License at 872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 1072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 1172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * See the License for the specific language governing permissions and 1572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * limitations under the License. 1672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 1772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 1872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpackage com.android.mms.transaction; 1972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 2072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport static android.content.Intent.ACTION_BOOT_COMPLETED; 21f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport static android.provider.Telephony.Sms.Intents.SMS_RECEIVED_ACTION; 2237321876549776417f035118f157d9531f73de6bWink Saville 2304db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylorimport java.util.Calendar; 2404db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylorimport java.util.GregorianCalendar; 2504db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor 2672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.Activity; 2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.Service; 2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentResolver; 2972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentUris; 3072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentValues; 3172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context; 3272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Intent; 33cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylorimport android.content.IntentFilter; 3472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.Cursor; 35d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.database.sqlite.SqliteWrapper; 3672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri; 3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Handler; 3872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.HandlerThread; 3972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.IBinder; 4072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Looper; 4172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Message; 4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Process; 43f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Sms; 44f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Sms.Inbox; 45f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Sms.Intents; 46f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Sms.Outbox; 4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.telephony.ServiceState; 4837321876549776417f035118f157d9531f73de6bWink Savilleimport android.telephony.SmsManager; 4937321876549776417f035118f157d9531f73de6bWink Savilleimport android.telephony.SmsMessage; 506a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kallaimport android.text.TextUtils; 5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log; 5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.Toast; 5372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 54f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.internal.telephony.TelephonyIntents; 55812391ad832f3fdac054ad3a50af563da16e99b5Wei Huangimport com.android.mms.LogTag; 56d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.R; 57d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.data.Contact; 58d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.data.Conversation; 59d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.ui.ClassZeroActivity; 60d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.util.Recycler; 61d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.util.SendingProgressTokenManager; 62d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.widget.MmsWidgetProvider; 63d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.MmsException; 6437321876549776417f035118f157d9531f73de6bWink Saville 6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/** 6672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * This service essentially plays the role of a "worker thread", allowing us to store 6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * incoming messages to the database, update notifications, etc. without blocking the 6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * main thread that SmsReceiver runs on. 6972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 7072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class SmsReceiverService extends Service { 7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String TAG = "SmsReceiverService"; 7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private ServiceHandler mServiceHandler; 7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private Looper mServiceLooper; 7552b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao private boolean mSending; 7672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final String MESSAGE_SENT_ACTION = 7872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project "com.android.mms.transaction.MESSAGE_SENT"; 7972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 8052b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao // Indicates next message can be picked up and sent out. 8152b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao public static final String EXTRA_MESSAGE_SENT_SEND_NEXT ="SendNextMsg"; 8252b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao 8352b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao public static final String ACTION_SEND_MESSAGE = 8452b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao "com.android.mms.transaction.SEND_MESSAGE"; 8552b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao 8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // This must match the column IDs below. 8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String[] SEND_PROJECTION = new String[] { 8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms._ID, //0 8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.THREAD_ID, //1 9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.ADDRESS, //2 9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.BODY, //3 9252b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao Sms.STATUS, //4 9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }; 9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 96f31df323b2dc4b668d91b24dd3a5d34f5ccbb14cTom Taylor public Handler mToastHandler = new Handler(); 9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // This must match SEND_PROJECTION. 9972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int SEND_COLUMN_ID = 0; 10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int SEND_COLUMN_THREAD_ID = 1; 10172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int SEND_COLUMN_ADDRESS = 2; 10272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int SEND_COLUMN_BODY = 3; 10352b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao private static final int SEND_COLUMN_STATUS = 4; 10472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 10572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private int mResultCode; 106f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor 10772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 10872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void onCreate() { 109f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor // Temporarily removed for this duplicate message track down. 110c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor// if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) { 111f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor// Log.v(TAG, "onCreate"); 112f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor// } 11372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 11472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Start up the thread running the service. Note that we create a 11572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // separate thread because the service normally runs in the process's 11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // main thread, which we don't want to block. 11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project HandlerThread thread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND); 11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project thread.start(); 11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceLooper = thread.getLooper(); 12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceHandler = new ServiceHandler(mServiceLooper); 12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 12535de139283bfeca8b2360c8b13b9cd8dee8e039bTom Taylor public int onStartCommand(Intent intent, int flags, int startId) { 126f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor // Temporarily removed for this duplicate message track down. 12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 1282c77f17bc77af92e57c82cc1bfa44de2979e505aTom Taylor mResultCode = intent != null ? intent.getIntExtra("result", 0) : 0; 12972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 13068be4f572123274aa67e13544482ca4d99e7b235Tom Taylor if (mResultCode != 0) { 1310856dec418d9838e09b1609439279e248355e0c4Tom Taylor Log.v(TAG, "onStart: #" + startId + " mResultCode: " + mResultCode + 1320856dec418d9838e09b1609439279e248355e0c4Tom Taylor " = " + translateResultCode(mResultCode)); 1330856dec418d9838e09b1609439279e248355e0c4Tom Taylor } 1340856dec418d9838e09b1609439279e248355e0c4Tom Taylor 13572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Message msg = mServiceHandler.obtainMessage(); 13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project msg.arg1 = startId; 13772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project msg.obj = intent; 13872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceHandler.sendMessage(msg); 13935de139283bfeca8b2360c8b13b9cd8dee8e039bTom Taylor return Service.START_NOT_STICKY; 14072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 14172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 1420856dec418d9838e09b1609439279e248355e0c4Tom Taylor private static String translateResultCode(int resultCode) { 1430856dec418d9838e09b1609439279e248355e0c4Tom Taylor switch (resultCode) { 1440856dec418d9838e09b1609439279e248355e0c4Tom Taylor case Activity.RESULT_OK: 1450856dec418d9838e09b1609439279e248355e0c4Tom Taylor return "Activity.RESULT_OK"; 1460856dec418d9838e09b1609439279e248355e0c4Tom Taylor case SmsManager.RESULT_ERROR_GENERIC_FAILURE: 1470856dec418d9838e09b1609439279e248355e0c4Tom Taylor return "SmsManager.RESULT_ERROR_GENERIC_FAILURE"; 1480856dec418d9838e09b1609439279e248355e0c4Tom Taylor case SmsManager.RESULT_ERROR_RADIO_OFF: 1490856dec418d9838e09b1609439279e248355e0c4Tom Taylor return "SmsManager.RESULT_ERROR_RADIO_OFF"; 1500856dec418d9838e09b1609439279e248355e0c4Tom Taylor case SmsManager.RESULT_ERROR_NULL_PDU: 1510856dec418d9838e09b1609439279e248355e0c4Tom Taylor return "SmsManager.RESULT_ERROR_NULL_PDU"; 1520856dec418d9838e09b1609439279e248355e0c4Tom Taylor case SmsManager.RESULT_ERROR_NO_SERVICE: 1530856dec418d9838e09b1609439279e248355e0c4Tom Taylor return "SmsManager.RESULT_ERROR_NO_SERVICE"; 1540856dec418d9838e09b1609439279e248355e0c4Tom Taylor case SmsManager.RESULT_ERROR_LIMIT_EXCEEDED: 1550856dec418d9838e09b1609439279e248355e0c4Tom Taylor return "SmsManager.RESULT_ERROR_LIMIT_EXCEEDED"; 1560856dec418d9838e09b1609439279e248355e0c4Tom Taylor case SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE: 1570856dec418d9838e09b1609439279e248355e0c4Tom Taylor return "SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE"; 1580856dec418d9838e09b1609439279e248355e0c4Tom Taylor default: 1590856dec418d9838e09b1609439279e248355e0c4Tom Taylor return "Unknown error code"; 1600856dec418d9838e09b1609439279e248355e0c4Tom Taylor } 1610856dec418d9838e09b1609439279e248355e0c4Tom Taylor } 1620856dec418d9838e09b1609439279e248355e0c4Tom Taylor 16372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 16472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void onDestroy() { 165f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor // Temporarily removed for this duplicate message track down. 166c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor// if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) { 167f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor// Log.v(TAG, "onDestroy"); 168f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor// } 16972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceLooper.quit(); 17072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 17172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 17272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 17372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public IBinder onBind(Intent intent) { 17472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return null; 17572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 17672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 17772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final class ServiceHandler extends Handler { 17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public ServiceHandler(Looper looper) { 17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project super(looper); 18072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 18172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 18272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 18372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Handle incoming transaction requests. 1840d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang * The incoming requests are initiated by the MMSC Server or by the MMS Client itself. 18572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 18672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 18772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void handleMessage(Message msg) { 18872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int serviceId = msg.arg1; 18972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent intent = (Intent)msg.obj; 1900856dec418d9838e09b1609439279e248355e0c4Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 1910d2c0042be90f42635e3bc301f2a2e37460e6344Tom Taylor Log.v(TAG, "handleMessage serviceId: " + serviceId + " intent: " + intent); 1920d2c0042be90f42635e3bc301f2a2e37460e6344Tom Taylor } 1932c77f17bc77af92e57c82cc1bfa44de2979e505aTom Taylor if (intent != null) { 1942c77f17bc77af92e57c82cc1bfa44de2979e505aTom Taylor String action = intent.getAction(); 1952c77f17bc77af92e57c82cc1bfa44de2979e505aTom Taylor 196161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor int error = intent.getIntExtra("errorCode", 0); 197161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor 1980856dec418d9838e09b1609439279e248355e0c4Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 1990d2c0042be90f42635e3bc301f2a2e37460e6344Tom Taylor Log.v(TAG, "handleMessage action: " + action + " error: " + error); 2000d2c0042be90f42635e3bc301f2a2e37460e6344Tom Taylor } 2010d2c0042be90f42635e3bc301f2a2e37460e6344Tom Taylor 2022c77f17bc77af92e57c82cc1bfa44de2979e505aTom Taylor if (MESSAGE_SENT_ACTION.equals(intent.getAction())) { 203161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor handleSmsSent(intent, error); 2042c77f17bc77af92e57c82cc1bfa44de2979e505aTom Taylor } else if (SMS_RECEIVED_ACTION.equals(action)) { 205161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor handleSmsReceived(intent, error); 2062c77f17bc77af92e57c82cc1bfa44de2979e505aTom Taylor } else if (ACTION_BOOT_COMPLETED.equals(action)) { 2072c77f17bc77af92e57c82cc1bfa44de2979e505aTom Taylor handleBootCompleted(); 208f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylor } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) { 2092c77f17bc77af92e57c82cc1bfa44de2979e505aTom Taylor handleServiceStateChanged(intent); 21052b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao } else if (ACTION_SEND_MESSAGE.endsWith(action)) { 21152b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao handleSendMessage(); 2122c77f17bc77af92e57c82cc1bfa44de2979e505aTom Taylor } 21372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 21472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // NOTE: We MUST not call stopSelf() directly, since we need to 21572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // make sure the wake lock acquired by AlertReceiver is released. 21672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SmsReceiver.finishStartingService(SmsReceiverService.this, serviceId); 21772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 22072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void handleServiceStateChanged(Intent intent) { 22172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // If service just returned, start sending out the queued messages 22272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras()); 22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) { 22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project sendFirstQueuedMessage(); 22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 22772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 22852b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao private void handleSendMessage() { 22952b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao if (!mSending) { 23052b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao sendFirstQueuedMessage(); 23152b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao } 23252b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao } 23352b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao 23472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public synchronized void sendFirstQueuedMessage() { 235cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor boolean success = true; 23672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // get all the queued messages from the database 23772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project final Uri uri = Uri.parse("content://sms/queued"); 23872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContentResolver resolver = getContentResolver(); 23972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor c = SqliteWrapper.query(this, resolver, uri, 24023142979f43786098655229416cf1d07c5f78e09Tom Taylor SEND_PROJECTION, null, null, "date ASC"); // date ASC so we send out in 24123142979f43786098655229416cf1d07c5f78e09Tom Taylor // same order the user tried 24223142979f43786098655229416cf1d07c5f78e09Tom Taylor // to send messages. 24372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (c != null) { 24472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 24572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (c.moveToFirst()) { 24672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String msgText = c.getString(SEND_COLUMN_BODY); 24752b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao String address = c.getString(SEND_COLUMN_ADDRESS); 24872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int threadId = c.getInt(SEND_COLUMN_THREAD_ID); 24952b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao int status = c.getInt(SEND_COLUMN_STATUS); 25072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 2510d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang int msgId = c.getInt(SEND_COLUMN_ID); 2520d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang Uri msgUri = ContentUris.withAppendedId(Sms.CONTENT_URI, msgId); 2530d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang 2544020be563f457ed2251b43928f14770246c886a2Tom Taylor SmsMessageSender sender = new SmsSingleRecipientSender(this, 2554020be563f457ed2251b43928f14770246c886a2Tom Taylor address, msgText, threadId, status == Sms.STATUS_PENDING, 2564020be563f457ed2251b43928f14770246c886a2Tom Taylor msgUri); 2574020be563f457ed2251b43928f14770246c886a2Tom Taylor 258a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor if (LogTag.DEBUG_SEND || 259a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor LogTag.VERBOSE || 260a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 2614020be563f457ed2251b43928f14770246c886a2Tom Taylor Log.v(TAG, "sendFirstQueuedMessage " + msgUri + 2620d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang ", address: " + address + 263858d59e9f4b0839ee014e52e0744ea910d9830ffWei Huang ", threadId: " + threadId); 2640d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang } 265858d59e9f4b0839ee014e52e0744ea910d9830ffWei Huang 26672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 26752b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao sender.sendMessage(SendingProgressTokenManager.NO_TOKEN);; 26852b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao mSending = true; 26967ec6c54e11c19caf894b4ffce7250fb3fd96d30Wei Huang } catch (MmsException e) { 27067ec6c54e11c19caf894b4ffce7250fb3fd96d30Wei Huang Log.e(TAG, "sendFirstQueuedMessage: failed to send message " + msgUri 27167ec6c54e11c19caf894b4ffce7250fb3fd96d30Wei Huang + ", caught ", e); 27213848bd88f29a358d13c2ce49f5c90c5858296f2Tom Taylor mSending = false; 27313848bd88f29a358d13c2ce49f5c90c5858296f2Tom Taylor messageFailedToSend(msgUri, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 274cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor success = false; 27572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 27672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 27772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 27872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project c.close(); 27972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 28072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 281cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor if (success) { 282cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor // We successfully sent all the messages in the queue. We don't need to 283cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor // be notified of any service changes any longer. 284cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor unRegisterForServiceStateChanges(); 285cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor } 28672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 28772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 288161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor private void handleSmsSent(Intent intent, int error) { 28972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Uri uri = intent.getData(); 29052b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao mSending = false; 29152b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao boolean sendNextMsg = intent.getBooleanExtra(EXTRA_MESSAGE_SENT_SEND_NEXT, false); 29272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 293c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor if (LogTag.DEBUG_SEND) { 294a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor Log.v(TAG, "handleSmsSent uri: " + uri + " sendNextMsg: " + sendNextMsg + 295a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor " mResultCode: " + mResultCode + 296a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor " = " + translateResultCode(mResultCode) + " error: " + error); 297c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor } 298c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor 29972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mResultCode == Activity.RESULT_OK) { 300a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor if (LogTag.DEBUG_SEND || Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 301a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor Log.v(TAG, "handleSmsSent move message to sent folder uri: " + uri); 302f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor } 303161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor if (!Sms.moveMessageToFolder(this, uri, Sms.MESSAGE_TYPE_SENT, error)) { 3040d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang Log.e(TAG, "handleSmsSent: failed to move message " + uri + " to sent folder"); 3050d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang } 30652b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao if (sendNextMsg) { 30752b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao sendFirstQueuedMessage(); 30852b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao } 30972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 3100d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang // Update the notification for failed messages since they may be deleted. 311b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor MessagingNotification.nonBlockingUpdateSendFailedNotification(this); 31272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else if ((mResultCode == SmsManager.RESULT_ERROR_RADIO_OFF) || 31372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project (mResultCode == SmsManager.RESULT_ERROR_NO_SERVICE)) { 314f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 315f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor Log.v(TAG, "handleSmsSent: no service, queuing message w/ uri: " + uri); 316f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor } 317cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor // We got an error with no service or no radio. Register for state changes so 318cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor // when the status of the connection/radio changes, we can try to send the 319cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor // queued up messages. 320cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor registerForServiceStateChanges(); 321cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor // We couldn't send the message, put in the queue to retry later. 322161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor Sms.moveMessageToFolder(this, uri, Sms.MESSAGE_TYPE_QUEUED, error); 323f31df323b2dc4b668d91b24dd3a5d34f5ccbb14cTom Taylor mToastHandler.post(new Runnable() { 324f31df323b2dc4b668d91b24dd3a5d34f5ccbb14cTom Taylor public void run() { 325f31df323b2dc4b668d91b24dd3a5d34f5ccbb14cTom Taylor Toast.makeText(SmsReceiverService.this, getString(R.string.message_queued), 326f31df323b2dc4b668d91b24dd3a5d34f5ccbb14cTom Taylor Toast.LENGTH_SHORT).show(); 327f31df323b2dc4b668d91b24dd3a5d34f5ccbb14cTom Taylor } 328f31df323b2dc4b668d91b24dd3a5d34f5ccbb14cTom Taylor }); 329f97cdd928bbc1953d422466d62807f07ae66119eNaveen Kalla } else if (mResultCode == SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE) { 3303c6eacd7f75aef4109f6ba8f1fbf2c957bd58ae2The Android Open Source Project mToastHandler.post(new Runnable() { 3313c6eacd7f75aef4109f6ba8f1fbf2c957bd58ae2The Android Open Source Project public void run() { 3323c6eacd7f75aef4109f6ba8f1fbf2c957bd58ae2The Android Open Source Project Toast.makeText(SmsReceiverService.this, getString(R.string.fdn_check_failure), 3333c6eacd7f75aef4109f6ba8f1fbf2c957bd58ae2The Android Open Source Project Toast.LENGTH_SHORT).show(); 3343c6eacd7f75aef4109f6ba8f1fbf2c957bd58ae2The Android Open Source Project } 3353c6eacd7f75aef4109f6ba8f1fbf2c957bd58ae2The Android Open Source Project }); 33672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 33713848bd88f29a358d13c2ce49f5c90c5858296f2Tom Taylor messageFailedToSend(uri, error); 33852b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao if (sendNextMsg) { 33952b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao sendFirstQueuedMessage(); 34052b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao } 34172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 34272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 34372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 34413848bd88f29a358d13c2ce49f5c90c5858296f2Tom Taylor private void messageFailedToSend(Uri uri, int error) { 345c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) { 346c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor Log.v(TAG, "messageFailedToSend msg failed uri: " + uri + " error: " + error); 34713848bd88f29a358d13c2ce49f5c90c5858296f2Tom Taylor } 34813848bd88f29a358d13c2ce49f5c90c5858296f2Tom Taylor Sms.moveMessageToFolder(this, uri, Sms.MESSAGE_TYPE_FAILED, error); 34913848bd88f29a358d13c2ce49f5c90c5858296f2Tom Taylor MessagingNotification.notifySendFailed(getApplicationContext(), true); 35013848bd88f29a358d13c2ce49f5c90c5858296f2Tom Taylor } 35113848bd88f29a358d13c2ce49f5c90c5858296f2Tom Taylor 352161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor private void handleSmsReceived(Intent intent, int error) { 35372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SmsMessage[] msgs = Intents.getMessagesFromIntent(intent); 354104d391ddcc251c4c26975c093d2df5dea9b15c1Tom Taylor String format = intent.getStringExtra("format"); 355104d391ddcc251c4c26975c093d2df5dea9b15c1Tom Taylor Uri messageUri = insertMessage(this, msgs, error, format); 35672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 357c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) { 3580d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang SmsMessage sms = msgs[0]; 3590d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang Log.v(TAG, "handleSmsReceived" + (sms.isReplace() ? "(replace)" : "") + 36023142979f43786098655229416cf1d07c5f78e09Tom Taylor " messageUri: " + messageUri + 3610d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang ", address: " + sms.getOriginatingAddress() + 3620d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang ", body: " + sms.getMessageBody()); 363f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor } 364f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor 36572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (messageUri != null) { 366c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev long threadId = MessagingNotification.getSmsThreadId(this, messageUri); 3673b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor // Called off of the UI thread so ok to block. 368d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor Log.d(TAG, "handleSmsReceived messageUri: " + messageUri + " threadId: " + threadId); 369c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev MessagingNotification.blockingUpdateNewMessageIndicator(this, threadId, false); 37072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 37172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 37272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 37372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void handleBootCompleted() { 3747015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev // Some messages may get stuck in the outbox. At this point, they're probably irrelevant 3757015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev // to the user, so mark them as failed and notify the user, who can then decide whether to 3767015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev // resend them manually. 3777015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev int numMoved = moveOutboxMessagesToFailedBox(); 3787015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev if (numMoved > 0) { 3797015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev MessagingNotification.notifySendFailed(getApplicationContext(), true); 3807015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev } 3817015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev 3827015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev // Send any queued messages that were waiting from before the reboot. 38372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project sendFirstQueuedMessage(); 3843b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor 3853b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor // Called off of the UI thread so ok to block. 386c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev MessagingNotification.blockingUpdateNewMessageIndicator( 387c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev this, MessagingNotification.THREAD_ALL, false); 38872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 38972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 3907015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev /** 3917015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev * Move all messages that are in the outbox to the failed state and set them to unread. 3927015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev * @return The number of messages that were actually moved 3937015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev */ 3947015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev private int moveOutboxMessagesToFailedBox() { 3957015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev ContentValues values = new ContentValues(3); 39672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 3977015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev values.put(Sms.TYPE, Sms.MESSAGE_TYPE_FAILED); 3987015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev values.put(Sms.ERROR_CODE, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 3997015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev values.put(Sms.READ, Integer.valueOf(0)); 40072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 401a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor int messageCount = SqliteWrapper.update( 40272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project getApplicationContext(), getContentResolver(), Outbox.CONTENT_URI, 40372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project values, "type = " + Sms.MESSAGE_TYPE_OUTBOX, null); 404a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) { 4057015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev Log.v(TAG, "moveOutboxMessagesToFailedBox messageCount: " + messageCount); 406a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor } 4077015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev return messageCount; 40872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 40972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 41072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final String CLASS_ZERO_BODY_KEY = "CLASS_ZERO_BODY"; 41172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 41272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // This must match the column IDs below. 41372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final static String[] REPLACE_PROJECTION = new String[] { 41472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms._ID, 41572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.ADDRESS, 41672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.PROTOCOL 41772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }; 41872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 41972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // This must match REPLACE_PROJECTION. 42072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int REPLACE_COLUMN_ID = 0; 42172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 42272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 42372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * If the message is a class-zero message, display it immediately 42472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * and return null. Otherwise, store it using the 42572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <code>ContentResolver</code> and return the 42672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <code>Uri</code> of the thread containing this message 42772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * so that we can use it for notification. 42872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 429104d391ddcc251c4c26975c093d2df5dea9b15c1Tom Taylor private Uri insertMessage(Context context, SmsMessage[] msgs, int error, String format) { 43072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Build the helper classes to parse the messages. 43172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SmsMessage sms = msgs[0]; 43272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 43372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (sms.getMessageClass() == SmsMessage.MessageClass.CLASS_0) { 434104d391ddcc251c4c26975c093d2df5dea9b15c1Tom Taylor displayClassZeroMessage(context, sms, format); 43572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return null; 43672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else if (sms.isReplace()) { 437161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor return replaceMessage(context, msgs, error); 43872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 439161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor return storeMessage(context, msgs, error); 44072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 44172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 44272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 44372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 44472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * This method is used if this is a "replace short message" SMS. 44572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * We find any existing message that matches the incoming 44672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * message's originating address and protocol identifier. If 44772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * there is one, we replace its fields with those of the new 44872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * message. Otherwise, we store the new message as usual. 44972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 45072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * See TS 23.040 9.2.3.9. 45172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 452161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor private Uri replaceMessage(Context context, SmsMessage[] msgs, int error) { 45372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SmsMessage sms = msgs[0]; 45472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContentValues values = extractContentValues(sms); 455161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor values.put(Sms.ERROR_CODE, error); 456dc0014f123be2c475bdeed2aef09566b5127e2a2bi int pduCount = msgs.length; 457dc0014f123be2c475bdeed2aef09566b5127e2a2bi 458dc0014f123be2c475bdeed2aef09566b5127e2a2bi if (pduCount == 1) { 459dc0014f123be2c475bdeed2aef09566b5127e2a2bi // There is only one part, so grab the body directly. 460dc0014f123be2c475bdeed2aef09566b5127e2a2bi values.put(Inbox.BODY, replaceFormFeeds(sms.getDisplayMessageBody())); 461dc0014f123be2c475bdeed2aef09566b5127e2a2bi } else { 462dc0014f123be2c475bdeed2aef09566b5127e2a2bi // Build up the body from the parts. 463dc0014f123be2c475bdeed2aef09566b5127e2a2bi StringBuilder body = new StringBuilder(); 464dc0014f123be2c475bdeed2aef09566b5127e2a2bi for (int i = 0; i < pduCount; i++) { 465dc0014f123be2c475bdeed2aef09566b5127e2a2bi sms = msgs[i]; 466dc0014f123be2c475bdeed2aef09566b5127e2a2bi if (sms.mWrappedSmsMessage != null) { 467dc0014f123be2c475bdeed2aef09566b5127e2a2bi body.append(sms.getDisplayMessageBody()); 468dc0014f123be2c475bdeed2aef09566b5127e2a2bi } 469dc0014f123be2c475bdeed2aef09566b5127e2a2bi } 470dc0014f123be2c475bdeed2aef09566b5127e2a2bi values.put(Inbox.BODY, replaceFormFeeds(body.toString())); 471dc0014f123be2c475bdeed2aef09566b5127e2a2bi } 47272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 47372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContentResolver resolver = context.getContentResolver(); 47472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String originatingAddress = sms.getOriginatingAddress(); 47572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int protocolIdentifier = sms.getProtocolIdentifier(); 47672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String selection = 47772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.ADDRESS + " = ? AND " + 47872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.PROTOCOL + " = ?"; 47972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String[] selectionArgs = new String[] { 48072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project originatingAddress, Integer.toString(protocolIdentifier) 48172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }; 48272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 48372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor cursor = SqliteWrapper.query(context, resolver, Inbox.CONTENT_URI, 48472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project REPLACE_PROJECTION, selection, selectionArgs, null); 48572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 48672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (cursor != null) { 48772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 48872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (cursor.moveToFirst()) { 48972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long messageId = cursor.getLong(REPLACE_COLUMN_ID); 49072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Uri messageUri = ContentUris.withAppendedId( 49172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.CONTENT_URI, messageId); 49272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 49372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SqliteWrapper.update(context, resolver, messageUri, 49472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project values, null, null); 49572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return messageUri; 49672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 49772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 49872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cursor.close(); 49972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 50072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 501161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor return storeMessage(context, msgs, error); 50272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 50372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 504beb7834e73f6bc94938cb448522df19edb60d8c8Tom Taylor public static String replaceFormFeeds(String s) { 505beb7834e73f6bc94938cb448522df19edb60d8c8Tom Taylor // Some providers send formfeeds in their messages. Convert those formfeeds to newlines. 5064c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor return s == null ? "" : s.replace('\f', '\n'); 507beb7834e73f6bc94938cb448522df19edb60d8c8Tom Taylor } 508beb7834e73f6bc94938cb448522df19edb60d8c8Tom Taylor 5096ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// private static int count = 0; 5106ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor 511161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor private Uri storeMessage(Context context, SmsMessage[] msgs, int error) { 51272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SmsMessage sms = msgs[0]; 51372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 51472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Store the message in the content provider. 51572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContentValues values = extractContentValues(sms); 516161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor values.put(Sms.ERROR_CODE, error); 51772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int pduCount = msgs.length; 51872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 51972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (pduCount == 1) { 52072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // There is only one part, so grab the body directly. 521beb7834e73f6bc94938cb448522df19edb60d8c8Tom Taylor values.put(Inbox.BODY, replaceFormFeeds(sms.getDisplayMessageBody())); 52272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 52372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Build up the body from the parts. 52472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project StringBuilder body = new StringBuilder(); 52572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (int i = 0; i < pduCount; i++) { 52672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project sms = msgs[i]; 527dca923722b6eb0bb3cd8ca1d4d7b478c2fa4352bTom Taylor if (sms.mWrappedSmsMessage != null) { 528dca923722b6eb0bb3cd8ca1d4d7b478c2fa4352bTom Taylor body.append(sms.getDisplayMessageBody()); 529dca923722b6eb0bb3cd8ca1d4d7b478c2fa4352bTom Taylor } 53072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 531beb7834e73f6bc94938cb448522df19edb60d8c8Tom Taylor values.put(Inbox.BODY, replaceFormFeeds(body.toString())); 53272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 533f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor 53423da10700b189ccca64b8e729631763572a0f15fTom Taylor // Make sure we've got a thread id so after the insert we'll be able to delete 53523da10700b189ccca64b8e729631763572a0f15fTom Taylor // excess messages. 53623da10700b189ccca64b8e729631763572a0f15fTom Taylor Long threadId = values.getAsLong(Sms.THREAD_ID); 53723da10700b189ccca64b8e729631763572a0f15fTom Taylor String address = values.getAsString(Sms.ADDRESS); 5386ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor 5396ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor // Code for debugging and easy injection of short codes, non email addresses, etc. 5406ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor // See Contact.isAlphaNumber() for further comments and results. 5416ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// switch (count++ % 8) { 5426ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// case 0: address = "AB12"; break; 5436ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// case 1: address = "12"; break; 5446ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// case 2: address = "Jello123"; break; 5456ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// case 3: address = "T-Mobile"; break; 5466ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// case 4: address = "Mobile1"; break; 5476ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// case 5: address = "Dogs77"; break; 5486ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// case 6: address = "****1"; break; 5496ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// case 7: address = "#4#5#6#"; break; 5506ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// } 5516ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor 5526a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla if (!TextUtils.isEmpty(address)) { 5536a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla Contact cacheContact = Contact.get(address,true); 5546a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla if (cacheContact != null) { 5556a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla address = cacheContact.getNumber(); 5566a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla } 5576a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla } else { 5586a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla address = getString(R.string.unknown_sender); 5596a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla values.put(Sms.ADDRESS, address); 560baf7fec7d1a5b8d52ae7be04865f9e869742c261repo sync } 56123da10700b189ccca64b8e729631763572a0f15fTom Taylor 56223da10700b189ccca64b8e729631763572a0f15fTom Taylor if (((threadId == null) || (threadId == 0)) && (address != null)) { 5636bbfdd3cc9cbe6b31dc64f122f3308563d19e077Tom Taylor threadId = Conversation.getOrCreateThreadId(context, address); 564627007213deb59ef938c80353c8f3598b01478b3Wei Huang values.put(Sms.THREAD_ID, threadId); 56523da10700b189ccca64b8e729631763572a0f15fTom Taylor } 56672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 56772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContentResolver resolver = context.getContentResolver(); 56872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 56923da10700b189ccca64b8e729631763572a0f15fTom Taylor Uri insertedUri = SqliteWrapper.insert(context, resolver, Inbox.CONTENT_URI, values); 570f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor 57123da10700b189ccca64b8e729631763572a0f15fTom Taylor // Now make sure we're not over the limit in stored messages 572c7aa632be8e7d3ebe71f236f534ea2f0af71e04aTom Taylor Recycler.getSmsRecycler().deleteOldMessagesByThreadId(context, threadId); 573c7aa632be8e7d3ebe71f236f534ea2f0af71e04aTom Taylor MmsWidgetProvider.notifyDatasetChanged(context); 57423da10700b189ccca64b8e729631763572a0f15fTom Taylor 57523da10700b189ccca64b8e729631763572a0f15fTom Taylor return insertedUri; 57672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 57772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 57872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 57972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Extract all the content values except the body from an SMS 58072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * message. 58172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 58272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private ContentValues extractContentValues(SmsMessage sms) { 58372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Store the message in the content provider. 58472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContentValues values = new ContentValues(); 58572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 58672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project values.put(Inbox.ADDRESS, sms.getDisplayOriginatingAddress()); 58772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 58872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Use now for the timestamp to avoid confusion with clock 58972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // drift between the handset and the SMSC. 59004db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor // Check to make sure the system is giving us a non-bogus time. 59104db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor Calendar buildDate = new GregorianCalendar(2011, 8, 18); // 18 Sep 2011 59204db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor Calendar nowDate = new GregorianCalendar(); 59304db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor long now = System.currentTimeMillis(); 59404db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor nowDate.setTimeInMillis(now); 59504db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor 59604db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor if (nowDate.before(buildDate)) { 59704db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor // It looks like our system clock isn't set yet because the current time right now 59804db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor // is before an arbitrary time we made this build. Instead of inserting a bogus 59904db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor // receive time in this case, use the timestamp of when the message was sent. 60004db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor now = sms.getTimestampMillis(); 60104db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor } 60204db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor 60304db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor values.put(Inbox.DATE, new Long(now)); 60454711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert values.put(Inbox.DATE_SENT, Long.valueOf(sms.getTimestampMillis())); 60572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project values.put(Inbox.PROTOCOL, sms.getProtocolIdentifier()); 606627007213deb59ef938c80353c8f3598b01478b3Wei Huang values.put(Inbox.READ, 0); 607627007213deb59ef938c80353c8f3598b01478b3Wei Huang values.put(Inbox.SEEN, 0); 60872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (sms.getPseudoSubject().length() > 0) { 60972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project values.put(Inbox.SUBJECT, sms.getPseudoSubject()); 61072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 61172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project values.put(Inbox.REPLY_PATH_PRESENT, sms.isReplyPathPresent() ? 1 : 0); 61272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project values.put(Inbox.SERVICE_CENTER, sms.getServiceCenterAddress()); 61372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return values; 61472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 61572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 61672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 61772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Displays a class-zero message immediately in a pop-up window 61872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * with the number from where it received the Notification with 61972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * the body of the message 62072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 62172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 622104d391ddcc251c4c26975c093d2df5dea9b15c1Tom Taylor private void displayClassZeroMessage(Context context, SmsMessage sms, String format) { 62372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Using NEW_TASK here is necessary because we're calling 62472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // startActivity from outside an activity. 62572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent smsDialogIntent = new Intent(context, ClassZeroActivity.class) 6264da6513065fbcfbf7fee9a18176ce62d2f62c825Yong Liu .putExtra("pdu", sms.getPdu()) 627104d391ddcc251c4c26975c093d2df5dea9b15c1Tom Taylor .putExtra("format", format) 62872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 62972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); 63072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 63172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context.startActivity(smsDialogIntent); 63272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 63372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 634cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor private void registerForServiceStateChanges() { 635cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor Context context = getApplicationContext(); 636cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor unRegisterForServiceStateChanges(); 637cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor 638cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor IntentFilter intentFilter = new IntentFilter(); 639f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylor intentFilter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED); 640c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) { 641cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor Log.v(TAG, "registerForServiceStateChanges"); 642cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor } 643cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor 644cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor context.registerReceiver(SmsReceiver.getInstance(), intentFilter); 645cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor } 646cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor 647cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor private void unRegisterForServiceStateChanges() { 648c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) { 649cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor Log.v(TAG, "unRegisterForServiceStateChanges"); 650cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor } 651cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor try { 652cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor Context context = getApplicationContext(); 653cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor context.unregisterReceiver(SmsReceiver.getInstance()); 654cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor } catch (IllegalArgumentException e) { 655cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor // Allow un-matched register-unregister calls 656cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor } 657cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor } 65872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project} 65937321876549776417f035118f157d9531f73de6bWink Saville 66037321876549776417f035118f157d9531f73de6bWink Saville 661