BluetoothMapContentObserver.java revision 0e7e149687b0b5e340991b20c9d8e5232e8d3e39
1fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie/* 2fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* Copyright (C) 2013 Samsung System LSI 3fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* Licensed under the Apache License, Version 2.0 (the "License"); 4fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* you may not use this file except in compliance with the License. 5fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* You may obtain a copy of the License at 6fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* 7fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* http://www.apache.org/licenses/LICENSE-2.0 8fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* 9fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* Unless required by applicable law or agreed to in writing, software 10fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* distributed under the License is distributed on an "AS IS" BASIS, 11fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* See the License for the specific language governing permissions and 13fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* limitations under the License. 14fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie*/ 15fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xiepackage com.android.bluetooth.map; 16fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 17fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.io.ByteArrayInputStream; 18fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.io.FileNotFoundException; 19fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.io.IOException; 20fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.io.OutputStream; 21fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.io.StringWriter; 22fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.io.UnsupportedEncodingException; 23fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.util.ArrayList; 24fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.util.Arrays; 25fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.util.Collections; 26fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.util.HashMap; 27fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.util.HashSet; 28fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.util.Map; 29fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.util.Set; 30fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 31fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport org.xmlpull.v1.XmlSerializer; 32fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 33fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.app.Activity; 34fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.app.PendingIntent; 35fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.BroadcastReceiver; 36fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.ContentResolver; 37fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.ContentUris; 38fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.ContentValues; 39fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.Context; 40fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.Intent; 41fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.IntentFilter; 42fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.database.ContentObserver; 43fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.database.Cursor; 44fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.net.Uri; 45fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.os.Handler; 46fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.provider.BaseColumns; 47fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.provider.Telephony; 48fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.provider.Telephony.Mms; 49fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.provider.Telephony.MmsSms; 50fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.provider.Telephony.Sms; 51fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.provider.Telephony.Sms.Inbox; 52fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.telephony.PhoneStateListener; 53fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.telephony.ServiceState; 54fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.telephony.SmsManager; 55fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.telephony.SmsMessage; 56fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.telephony.TelephonyManager; 57fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.util.Log; 58fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.util.Xml; 59400eaf8761223196a18b84247b066f0201226c3bHemant Guptaimport android.os.Looper; 60fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 61fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport com.android.bluetooth.map.BluetoothMapUtils.TYPE; 62fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport com.android.bluetooth.map.BluetoothMapbMessageMmsEmail.MimePart; 63fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport com.google.android.mms.pdu.PduHeaders; 64fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 65fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xiepublic class BluetoothMapContentObserver { 66fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private static final String TAG = "BluetoothMapContentObserver"; 67fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 6870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz private static final boolean D = false; 6970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz private static final boolean V = false; 70fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 71fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private Context mContext; 72fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private ContentResolver mResolver; 73fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private BluetoothMnsObexClient mMnsClient; 74fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private int mMasId; 75fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 76fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public static final int DELETED_THREAD_ID = -1; 77fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 78fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* X-Mms-Message-Type field types. These are from PduHeaders.java */ 79fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public static final int MESSAGE_TYPE_RETRIEVE_CONF = 0x84; 80fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 81fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private TYPE mSmsType; 82fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 83fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie static final String[] SMS_PROJECTION = new String[] { 84fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie BaseColumns._ID, 85fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.THREAD_ID, 86fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.ADDRESS, 87fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.BODY, 88fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.DATE, 89fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.READ, 90fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.TYPE, 91fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.STATUS, 92fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.LOCKED, 93fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.ERROR_CODE, 94fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie }; 95fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 96fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie static final String[] MMS_PROJECTION = new String[] { 97fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie BaseColumns._ID, 98fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Mms.THREAD_ID, 99fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Mms.MESSAGE_ID, 100fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Mms.MESSAGE_SIZE, 101fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Mms.SUBJECT, 102fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Mms.CONTENT_TYPE, 103fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Mms.TEXT_ONLY, 104fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Mms.DATE, 105fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Mms.DATE_SENT, 106fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Mms.READ, 107fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Mms.MESSAGE_BOX, 108fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Mms.MESSAGE_TYPE, 109fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Mms.STATUS, 110fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie }; 111fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 112fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public BluetoothMapContentObserver(final Context context) { 113fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mContext = context; 114fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mResolver = mContext.getContentResolver(); 115fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 116fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mSmsType = getSmsType(); 117fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 118fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 119fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private TYPE getSmsType() { 120fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie TYPE smsType = null; 121fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie TelephonyManager tm = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE); 122fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 123fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) { 124fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie smsType = TYPE.SMS_GSM; 125fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) { 126fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie smsType = TYPE.SMS_CDMA; 127fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 128fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 129fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return smsType; 130fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 131fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 132400eaf8761223196a18b84247b066f0201226c3bHemant Gupta private final ContentObserver mObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { 133fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie @Override 134fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void onChange(boolean selfChange) { 135fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie onChange(selfChange, null); 136fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 137fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 138fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie @Override 139fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void onChange(boolean selfChange, Uri uri) { 140fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (V) Log.d(TAG, "onChange on thread: " + Thread.currentThread().getId() 141fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie + " Uri: " + uri.toString() + " selfchange: " + selfChange); 142fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 143fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie handleMsgListChanges(); 144fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 145fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie }; 146fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 147fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private static final String folderSms[] = { 148fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "", 149fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "inbox", 150fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "sent", 151fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "draft", 152fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "outbox", 153fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "outbox", 154fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "outbox", 155fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "inbox", 156fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "inbox", 157fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie }; 158fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 159fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private static final String folderMms[] = { 160fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "", 161fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "inbox", 162fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "sent", 163fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "draft", 164fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "outbox", 165fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie }; 166fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 167fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private class Event { 168fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String eventType; 169fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie long handle; 170fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String folder; 171fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String oldFolder; 172fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie TYPE msgType; 173fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 174fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public Event(String eventType, long handle, String folder, 175fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String oldFolder, TYPE msgType) { 176fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String PATH = "telecom/msg/"; 177fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.eventType = eventType; 178fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.handle = handle; 179fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (folder != null) { 180fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.folder = PATH + folder; 181fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 182fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.folder = null; 183fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 184fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (oldFolder != null) { 185fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.oldFolder = PATH + oldFolder; 186fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 187fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.oldFolder = null; 188fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 189fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.msgType = msgType; 190fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 191fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 192fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public byte[] encode() throws UnsupportedEncodingException { 193fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie StringWriter sw = new StringWriter(); 194fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie XmlSerializer xmlEvtReport = Xml.newSerializer(); 195fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie try { 196fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlEvtReport.setOutput(sw); 197fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlEvtReport.startDocument(null, null); 198fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlEvtReport.text("\n"); 19970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz xmlEvtReport.startTag("", "MAP-event-report"); 200fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlEvtReport.attribute("", "version", "1.0"); 201fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 202fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlEvtReport.startTag("", "event"); 203fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlEvtReport.attribute("", "type", eventType); 204fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlEvtReport.attribute("", "handle", BluetoothMapUtils.getMapHandle(handle, msgType)); 205fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (folder != null) { 206fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlEvtReport.attribute("", "folder", folder); 207fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 208fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (oldFolder != null) { 209fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlEvtReport.attribute("", "old_folder", oldFolder); 210fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 211fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlEvtReport.attribute("", "msg_type", msgType.name()); 212fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlEvtReport.endTag("", "event"); 213fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 21470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz xmlEvtReport.endTag("", "MAP-event-report"); 215fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlEvtReport.endDocument(); 216fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (IllegalArgumentException e) { 217fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie e.printStackTrace(); 218fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (IllegalStateException e) { 219fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie e.printStackTrace(); 220fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (IOException e) { 221fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie e.printStackTrace(); 222fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 223fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 224fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (V) System.out.println(sw.toString()); 225fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 226fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return sw.toString().getBytes("UTF-8"); 227fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 228fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 229fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 230fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private class Msg { 231fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie long id; 232fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int type; 233fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 234fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public Msg(long id, int type) { 235fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.id = id; 236fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.type = type; 237fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 238fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 239fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 240fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private Map<Long, Msg> mMsgListSms = 241fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Collections.synchronizedMap(new HashMap<Long, Msg>()); 242fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 243fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private Map<Long, Msg> mMsgListMms = 244fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Collections.synchronizedMap(new HashMap<Long, Msg>()); 245fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 246fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void registerObserver(BluetoothMnsObexClient mns, int masId) { 247fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (V) Log.d(TAG, "registerObserver"); 248fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Use MmsSms Uri since the Sms Uri is not notified on deletes */ 249fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mMasId = masId; 250fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mMnsClient = mns; 251fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mResolver.registerContentObserver(MmsSms.CONTENT_URI, false, mObserver); 252fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie initMsgList(); 253fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 254fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 255fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void unregisterObserver() { 256fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (V) Log.d(TAG, "unregisterObserver"); 257fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mResolver.unregisterContentObserver(mObserver); 25870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz mMnsClient = null; 259fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 260fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 261fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void sendEvent(Event evt) { 262fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "sendEvent: " + evt.eventType + " " + evt.handle + " " 263fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie + evt.folder + " " + evt.oldFolder + " " + evt.msgType.name()); 264fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2650e7e149687b0b5e340991b20c9d8e5232e8d3e39Hemant Gupta if (mMnsClient == null || mMnsClient.isConnected() == false) { 2660e7e149687b0b5e340991b20c9d8e5232e8d3e39Hemant Gupta Log.d(TAG, "sendEvent: No MNS client registered or connected- don't send event"); 267fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return; 268fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 269fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 270fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie try { 271fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mMnsClient.sendEvent(evt.encode(), mMasId); 272fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (UnsupportedEncodingException ex) { 273fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* do nothing */ 274fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 275fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 276fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 277fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void initMsgList() { 278fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (V) Log.d(TAG, "initMsgList"); 279fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 280fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mMsgListSms.clear(); 281fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mMsgListMms.clear(); 282fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 283fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie HashMap<Long, Msg> msgListSms = new HashMap<Long, Msg>(); 284fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 285fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Cursor c = mResolver.query(Sms.CONTENT_URI, 286fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie SMS_PROJECTION, null, null, null); 287fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 288fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (c != null && c.moveToFirst()) { 289fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie do { 290fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie long id = c.getLong(c.getColumnIndex(BaseColumns._ID)); 291fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int type = c.getInt(c.getColumnIndex(Sms.TYPE)); 292fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 293fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Msg msg = new Msg(id, type); 294fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie msgListSms.put(id, msg); 295fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } while (c.moveToNext()); 296fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie c.close(); 297fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 298fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 299fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mMsgListSms = msgListSms; 300fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 301fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie HashMap<Long, Msg> msgListMms = new HashMap<Long, Msg>(); 302fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 303fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie c = mResolver.query(Mms.CONTENT_URI, 304fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie MMS_PROJECTION, null, null, null); 305fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 306fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (c != null && c.moveToFirst()) { 307fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie do { 308fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie long id = c.getLong(c.getColumnIndex(BaseColumns._ID)); 309fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX)); 310fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 311fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Msg msg = new Msg(id, type); 312fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie msgListMms.put(id, msg); 313fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } while (c.moveToNext()); 314fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie c.close(); 315fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 316fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 317fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mMsgListMms = msgListMms; 318fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 319fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 320fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void handleMsgListChangesSms() { 321fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (V) Log.d(TAG, "handleMsgListChangesSms"); 322fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 323fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie HashMap<Long, Msg> msgListSms = new HashMap<Long, Msg>(); 324fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 325fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Cursor c = mResolver.query(Sms.CONTENT_URI, 326fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie SMS_PROJECTION, null, null, null); 327fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 328fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie synchronized(mMsgListSms) { 329fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (c != null && c.moveToFirst()) { 330fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie do { 331fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie long id = c.getLong(c.getColumnIndex(BaseColumns._ID)); 332fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int type = c.getInt(c.getColumnIndex(Sms.TYPE)); 333fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 334fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Msg msg = mMsgListSms.remove(id); 335fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 336fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (msg == null) { 337fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* New message */ 338fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie msg = new Msg(id, type); 339fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie msgListSms.put(id, msg); 340fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 341fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (folderSms[type].equals("inbox")) { 342fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Event evt = new Event("NewMessage", id, folderSms[type], 343fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie null, mSmsType); 344fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendEvent(evt); 345fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 346fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 347fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Existing message */ 348fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (type != msg.type) { 349fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "new type: " + type + " old type: " + msg.type); 350fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Event evt = new Event("MessageShift", id, folderSms[type], 351fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie folderSms[msg.type], mSmsType); 352fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendEvent(evt); 353fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie msg.type = type; 354fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 355fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie msgListSms.put(id, msg); 356fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 357fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } while (c.moveToNext()); 358fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie c.close(); 359fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 360fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 361fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie for (Msg msg : mMsgListSms.values()) { 362fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Event evt = new Event("MessageDeleted", msg.id, "deleted", 363fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie folderSms[msg.type], mSmsType); 364fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendEvent(evt); 365fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 366fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 367fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mMsgListSms = msgListSms; 368fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 369fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 370fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 371fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void handleMsgListChangesMms() { 372fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (V) Log.d(TAG, "handleMsgListChangesMms"); 373fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 374fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie HashMap<Long, Msg> msgListMms = new HashMap<Long, Msg>(); 375fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 376fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Cursor c = mResolver.query(Mms.CONTENT_URI, 377fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie MMS_PROJECTION, null, null, null); 378fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 379fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie synchronized(mMsgListMms) { 380fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (c != null && c.moveToFirst()) { 381fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie do { 382fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie long id = c.getLong(c.getColumnIndex(BaseColumns._ID)); 383fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX)); 384fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int mtype = c.getInt(c.getColumnIndex(Mms.MESSAGE_TYPE)); 385fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 386fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Msg msg = mMsgListMms.remove(id); 387fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 388fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (msg == null) { 389fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* New message - only notify on retrieve conf */ 390fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (folderMms[type].equals("inbox") && 391fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mtype != MESSAGE_TYPE_RETRIEVE_CONF) { 392fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie continue; 393fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 394fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 395fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie msg = new Msg(id, type); 396fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie msgListMms.put(id, msg); 397fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 398fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (folderMms[type].equals("inbox")) { 399fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Event evt = new Event("NewMessage", id, folderMms[type], 400fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie null, TYPE.MMS); 401fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendEvent(evt); 402fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 403fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 404fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Existing message */ 405fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (type != msg.type) { 406fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "new type: " + type + " old type: " + msg.type); 407fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Event evt = new Event("MessageShift", id, folderMms[type], 408fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie folderMms[msg.type], TYPE.MMS); 409fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendEvent(evt); 410fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie msg.type = type; 411fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 412fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (folderMms[type].equals("sent")) { 413fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie evt = new Event("SendingSuccess", id, 414fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie folderSms[type], null, TYPE.MMS); 415fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendEvent(evt); 416fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 417fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 418fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie msgListMms.put(id, msg); 419fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 420fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } while (c.moveToNext()); 421fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie c.close(); 422fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 423fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 424fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie for (Msg msg : mMsgListMms.values()) { 425fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Event evt = new Event("MessageDeleted", msg.id, "deleted", 426fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie folderMms[msg.type], TYPE.MMS); 427fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendEvent(evt); 428fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 429fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 430fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mMsgListMms = msgListMms; 431fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 432fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 433fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 434fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void handleMsgListChanges() { 435fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie handleMsgListChangesSms(); 436fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie handleMsgListChangesMms(); 437fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 438fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 439fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private boolean deleteMessageMms(long handle) { 440fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie boolean res = false; 441fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle); 442fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Cursor c = mResolver.query(uri, null, null, null, null); 443fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (c != null && c.moveToFirst()) { 444fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Move to deleted folder, or delete if already in deleted folder */ 445fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID)); 446fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (threadId != DELETED_THREAD_ID) { 447fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Set deleted thread id */ 448fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ContentValues contentValues = new ContentValues(); 449fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie contentValues.put(Mms.THREAD_ID, DELETED_THREAD_ID); 450fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mResolver.update(uri, contentValues, null, null); 451fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 452fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Delete from observer message list to avoid delete notifications */ 453fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mMsgListMms.remove(handle); 454fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Delete message */ 455fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mResolver.delete(uri, null, null); 456fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 457fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie res = true; 458fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 459fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (c != null) { 460fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie c.close(); 461fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 462fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return res; 463fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 464fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 465fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void updateThreadIdMms(Uri uri, long threadId) { 466fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ContentValues contentValues = new ContentValues(); 467fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie contentValues.put(Mms.THREAD_ID, threadId); 468fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mResolver.update(uri, contentValues, null, null); 469fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 470fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 471fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private boolean unDeleteMessageMms(long handle) { 472fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie boolean res = false; 473fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle); 474fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Cursor c = mResolver.query(uri, null, null, null, null); 475fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 476fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (c != null && c.moveToFirst()) { 477fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID)); 478fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (threadId == DELETED_THREAD_ID) { 479fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Restore thread id from address, or if no thread for address 480fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * create new thread by insert and remove of fake message */ 481fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String address; 482fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie long id = c.getLong(c.getColumnIndex(BaseColumns._ID)); 483fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int msgBox = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX)); 484fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (msgBox == Mms.MESSAGE_BOX_INBOX) { 485fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie address = BluetoothMapContent.getAddressMms(mResolver, id, 486fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie BluetoothMapContent.MMS_FROM); 487fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 488fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie address = BluetoothMapContent.getAddressMms(mResolver, id, 489fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie BluetoothMapContent.MMS_TO); 490fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 491fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Set<String> recipients = new HashSet<String>(); 492fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie recipients.addAll(Arrays.asList(address)); 493fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie updateThreadIdMms(uri, Telephony.Threads.getOrCreateThreadId(mContext, recipients)); 494fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 495fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "Message not in deleted folder: handle " + handle 496fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie + " threadId " + threadId); 497fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 498fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie res = true; 499fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 500fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (c != null) { 501fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie c.close(); 502fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 503fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return res; 504fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 505fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 506fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private boolean deleteMessageSms(long handle) { 507fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie boolean res = false; 508fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle); 509fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Cursor c = mResolver.query(uri, null, null, null, null); 510fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 511fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (c != null && c.moveToFirst()) { 512fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Move to deleted folder, or delete if already in deleted folder */ 513fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID)); 514fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (threadId != DELETED_THREAD_ID) { 515fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Set deleted thread id */ 516fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ContentValues contentValues = new ContentValues(); 517fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie contentValues.put(Sms.THREAD_ID, DELETED_THREAD_ID); 518fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mResolver.update(uri, contentValues, null, null); 519fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 520fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Delete from observer message list to avoid delete notifications */ 521fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mMsgListSms.remove(handle); 522fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Delete message */ 523fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mResolver.delete(uri, null, null); 524fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 525fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie res = true; 526fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 527fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (c != null) { 528fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie c.close(); 529fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 530fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return res; 531fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 532fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 533fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void updateThreadIdSms(Uri uri, long threadId) { 534fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ContentValues contentValues = new ContentValues(); 535fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie contentValues.put(Sms.THREAD_ID, threadId); 536fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mResolver.update(uri, contentValues, null, null); 537fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 538fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 539fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private boolean unDeleteMessageSms(long handle) { 540fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie boolean res = false; 541fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle); 542fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Cursor c = mResolver.query(uri, null, null, null, null); 543fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 544fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (c != null && c.moveToFirst()) { 545fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID)); 546fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (threadId == DELETED_THREAD_ID) { 547fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String address = c.getString(c.getColumnIndex(Sms.ADDRESS)); 548fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Set<String> recipients = new HashSet<String>(); 549fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie recipients.addAll(Arrays.asList(address)); 550fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie updateThreadIdSms(uri, Telephony.Threads.getOrCreateThreadId(mContext, recipients)); 551fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 552fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "Message not in deleted folder: handle " + handle 553fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie + " threadId " + threadId); 554fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 555fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie res = true; 556fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 557fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (c != null) { 558fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie c.close(); 559fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 560fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return res; 561fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 562fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 563fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public boolean setMessageStatusDeleted(long handle, TYPE type, int statusValue) { 564fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie boolean res = false; 565fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (D) Log.d(TAG, "setMessageStatusDeleted: handle " + handle 566fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie + " type " + type + " value " + statusValue); 567fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 568fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (statusValue == BluetoothMapAppParams.STATUS_VALUE_YES) { 569fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (type == TYPE.SMS_GSM || type == TYPE.SMS_CDMA) { 570fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie res = deleteMessageSms(handle); 571fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else if (type == TYPE.MMS) { 572fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie res = deleteMessageMms(handle); 573fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 574fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else if (statusValue == BluetoothMapAppParams.STATUS_VALUE_NO) { 575fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (type == TYPE.SMS_GSM || type == TYPE.SMS_CDMA) { 576fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie res = unDeleteMessageSms(handle); 577fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else if (type == TYPE.MMS) { 578fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie res = unDeleteMessageMms(handle); 579fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 580fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 581fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return res; 582fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 583fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 584fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public boolean setMessageStatusRead(long handle, TYPE type, int statusValue) { 585fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie boolean res = true; 586fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 587fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (D) Log.d(TAG, "setMessageStatusRead: handle " + handle 588fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie + " type " + type + " value " + statusValue); 589fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 590fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Approved MAP spec errata 3445 states that read status initiated */ 591fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* by the MCE shall change the MSE read status. */ 592fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 593fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (type == TYPE.SMS_GSM || type == TYPE.SMS_CDMA) { 594fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle); 595fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Cursor c = mResolver.query(uri, null, null, null, null); 596fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 597fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ContentValues contentValues = new ContentValues(); 598fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie contentValues.put(Sms.READ, statusValue); 599fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mResolver.update(uri, contentValues, null, null); 600fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else if (type == TYPE.MMS) { 601fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle); 602fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Cursor c = mResolver.query(uri, null, null, null, null); 603fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 604fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ContentValues contentValues = new ContentValues(); 605fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie contentValues.put(Mms.READ, statusValue); 606fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mResolver.update(uri, contentValues, null, null); 607fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 608fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 609fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return res; 610fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 611fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 612fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private class PushMsgInfo { 613fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie long id; 614fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int transparent; 615fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int retry; 616fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String phone; 617fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri uri; 618fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int parts; 619fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int partsSent; 620fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int partsDelivered; 621fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie boolean resend; 622fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 623fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public PushMsgInfo(long id, int transparent, 624fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int retry, String phone, Uri uri) { 625fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.id = id; 626fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.transparent = transparent; 627fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.retry = retry; 628fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.phone = phone; 629fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.uri = uri; 630fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.resend = false; 631fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie }; 632fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 633fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 634fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private Map<Long, PushMsgInfo> mPushMsgList = 635fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Collections.synchronizedMap(new HashMap<Long, PushMsgInfo>()); 636fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 637fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public long pushMessage(BluetoothMapbMessage msg, String folder, 638fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie BluetoothMapAppParams ap) throws IllegalArgumentException { 639fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (D) Log.d(TAG, "pushMessage"); 640fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ArrayList<BluetoothMapbMessage.vCard> recipientList = msg.getRecipients(); 641fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int transparent = (ap.getTransparent() == BluetoothMapAppParams.INVALID_VALUE_PARAMETER) ? 642fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 0 : ap.getTransparent(); 643fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int retry = ap.getRetry(); 644fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int charset = ap.getCharset(); 645fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie long handle = -1; 646fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 647fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (recipientList == null) { 648fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "empty recipient list"); 649fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return -1; 650fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 651fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 652fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie for (BluetoothMapbMessage.vCard recipient : recipientList) { 653fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if(recipient.getEnvLevel() == 0) // Only send the message to the top level recipient 654fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie { 655fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Only send to first address */ 656fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String phone = recipient.getFirstPhoneNumber(); 657fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie boolean read = false; 658fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie boolean deliveryReport = true; 659fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 660fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie switch(msg.getType()){ 661fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie case MMS: 662fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie { 663fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Send message if folder is outbox */ 664c3ec58fcc54cb33635f4dee746ee22cb8b0e3210Zhihai Xu /* to do, support MMS in the future */ 665c3ec58fcc54cb33635f4dee746ee22cb8b0e3210Zhihai Xu /* 666fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie handle = sendMmsMessage(folder, phone, (BluetoothMapbMessageMmsEmail)msg); 667c3ec58fcc54cb33635f4dee746ee22cb8b0e3210Zhihai Xu */ 668fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie break; 669fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 670fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie case SMS_GSM: //fall-through 671fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie case SMS_CDMA: 672fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie { 673fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Add the message to the database */ 674fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String msgBody = ((BluetoothMapbMessageSms) msg).getSmsBody(); 675fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri contentUri = Uri.parse("content://sms/" + folder); 676fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri uri = Sms.addMessageToUri(mResolver, contentUri, phone, msgBody, 677fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "", System.currentTimeMillis(), read, deliveryReport); 678fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 679fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (uri == null) { 680fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "pushMessage - failure on add to uri " + contentUri); 681fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return -1; 682fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 683fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 684fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie handle = Long.parseLong(uri.getLastPathSegment()); 685fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 686fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Send message if folder is outbox */ 687fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (folder.equals("outbox")) { 688fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie PushMsgInfo msgInfo = new PushMsgInfo(handle, transparent, 689fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie retry, phone, uri); 690fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mPushMsgList.put(handle, msgInfo); 691fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendMessage(msgInfo, msgBody); 692fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 693fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie break; 694fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 695fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie case EMAIL: 696fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie { 697fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie break; 698fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 699fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 700fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 701fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 702fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 703fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 704fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* If multiple recipients return handle of last */ 705fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return handle; 706fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 707fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 708fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 709fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 710fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public long sendMmsMessage(String folder,String to_address, BluetoothMapbMessageMmsEmail msg) { 711fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* 712fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie *strategy: 713fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie *1) parse message into parts 714fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie *if folder is outbox/drafts: 715fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie *2) push message to draft 716fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie *if folder is outbox: 717fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie *3) move message to outbox (to trigger the mms app to add msg to pending_messages list) 718fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie *4) send intent to mms app in order to wake it up. 719fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie *else if folder !outbox: 720fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie *1) push message to folder 721fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * */ 7222e7c4d9904b097efe6f07d31af3793b96b4d4e77Kim Schulz long handle = pushMmsToFolder(Mms.MESSAGE_BOX_DRAFTS, to_address, msg); 7232e7c4d9904b097efe6f07d31af3793b96b4d4e77Kim Schulz /* if invalid handle (-1) then just return the handle - else continue sending (if folder is outbox) */ 7242e7c4d9904b097efe6f07d31af3793b96b4d4e77Kim Schulz if (BluetoothMapAppParams.INVALID_VALUE_PARAMETER != handle && folder.equalsIgnoreCase("outbox")) { 7252e7c4d9904b097efe6f07d31af3793b96b4d4e77Kim Schulz moveDraftToOutbox(handle); 7262e7c4d9904b097efe6f07d31af3793b96b4d4e77Kim Schulz 7272e7c4d9904b097efe6f07d31af3793b96b4d4e77Kim Schulz Intent sendIntent = new Intent("android.intent.action.MMS_SEND_OUTBOX_MSG"); 7282e7c4d9904b097efe6f07d31af3793b96b4d4e77Kim Schulz Log.d(TAG, "broadcasting intent: "+sendIntent.toString()); 7292e7c4d9904b097efe6f07d31af3793b96b4d4e77Kim Schulz mContext.sendBroadcast(sendIntent); 730fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 7312e7c4d9904b097efe6f07d31af3793b96b4d4e77Kim Schulz return handle; 732fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 733fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 734fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 735fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void moveDraftToOutbox(long handle) { 736fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ContentResolver contentResolver = mContext.getContentResolver(); 737fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /*Move message by changing the msg_box value in the content provider database */ 738fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (handle != -1) { 739fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String whereClause = " _id= " + handle; 740fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri uri = Uri.parse("content://mms"); 741fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Cursor queryResult = contentResolver.query(uri, null, whereClause, null, null); 742fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (queryResult != null) { 743fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (queryResult.getCount() > 0) { 744fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie queryResult.moveToFirst(); 745fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ContentValues data = new ContentValues(); 746fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* set folder to be outbox */ 747fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie data.put("msg_box", Mms.MESSAGE_BOX_OUTBOX); 748fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie contentResolver.update(uri, data, whereClause, null); 749fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "moved draft MMS to outbox"); 750fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 751fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie queryResult.close(); 752fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie }else { 753fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "Could not move draft to outbox "); 754fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 755fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 756fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 757fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private long pushMmsToFolder(int folder, String to_address, BluetoothMapbMessageMmsEmail msg) { 758fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /** 759fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * strategy: 760fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * 1) parse msg into parts + header 761fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * 2) create thread id (abuse the ease of adding an SMS to get id for thread) 762fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * 3) push parts into content://mms/parts/ table 763fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * 3) 764fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie */ 765fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 766fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ContentValues values = new ContentValues(); 767fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("msg_box", folder); 768fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 769fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("read", 0); 770fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("seen", 0); 77170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("sub", msg.getSubject()); 772fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("sub_cs", 106); 773fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("ct_t", "application/vnd.wap.multipart.related"); 774fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("exp", 604800); 775fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("m_cls", PduHeaders.MESSAGE_CLASS_PERSONAL_STR); 776fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("m_type", PduHeaders.MESSAGE_TYPE_SEND_REQ); 777fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("v", PduHeaders.CURRENT_MMS_VERSION); 778fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("pri", PduHeaders.PRIORITY_NORMAL); 779fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("rr", PduHeaders.VALUE_NO); 780fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("tr_id", "T"+ Long.toHexString(System.currentTimeMillis())); 781fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("d_rpt", PduHeaders.VALUE_NO); 782fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("locked", 0); 78370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if(msg.getTextOnly() == true) 78470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("text_only", true); 78570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 78670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("m_size", msg.getSize()); 78770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 788fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie // Get thread id 789fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Set<String> recipients = new HashSet<String>(); 790fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie recipients.addAll(Arrays.asList(to_address)); 791fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("thread_id", Telephony.Threads.getOrCreateThreadId(mContext, recipients)); 792fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri uri = Uri.parse("content://mms"); 793fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 794fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ContentResolver cr = mContext.getContentResolver(); 795fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie uri = cr.insert(uri, values); 796fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 797fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (uri == null) { 798fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie // unable to insert MMS 799fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.e(TAG, "Unabled to insert MMS " + values + "Uri: " + uri); 800fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return -1; 801fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 802fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 803fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie long handle = Long.parseLong(uri.getLastPathSegment()); 804fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (V){ 805fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.v(TAG, " NEW URI " + uri.toString()); 806fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 807fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie try { 80870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if(V) Log.v(TAG, "Adding " + msg.getMimeParts().size() + " parts to the data base."); 809fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie for(MimePart part : msg.getMimeParts()) { 81070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz int count = 0; 81170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz count++; 812fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.clear(); 813fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if(part.contentType != null && part.contentType.toUpperCase().contains("TEXT")) { 814fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("ct", "text/plain"); 815fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("chset", 106); 81670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if(part.partName != null) { 81770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("fn", part.partName); 81870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("name", part.partName); 81970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } else if(part.contentId == null && part.contentLocation == null) { 82070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz /* We must set at least one part identifier */ 82170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("fn", "text_" + count +".txt"); 82270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("name", "text_" + count +".txt"); 82370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 82470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if(part.contentId != null) { 82570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("cid", part.contentId); 82670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 82770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if(part.contentLocation != null) 82870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("cl", part.contentLocation); 82970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if(part.contentDisposition != null) 83070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("cd", part.contentDisposition); 831fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("text", new String(part.data, "UTF-8")); 832fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie uri = Uri.parse("content://mms/" + handle + "/part"); 833fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie uri = cr.insert(uri, values); 83470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if(V) Log.v(TAG, "Added TEXT part"); 835fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 836fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else if (part.contentType != null && part.contentType.toUpperCase().contains("SMIL")){ 837fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 838fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("seq", -1); 839fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("ct", "application/smil"); 84070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if(part.contentId != null) 84170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("cid", part.contentId); 84270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if(part.contentLocation != null) 84370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("cl", part.contentLocation); 84470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if(part.contentDisposition != null) 84570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("cd", part.contentDisposition); 846fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("fn", "smil.xml"); 847fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("name", "smil.xml"); 848fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("text", new String(part.data, "UTF-8")); 849fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 850fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie uri = Uri.parse("content://mms/" + handle + "/part"); 851fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie uri = cr.insert(uri, values); 85270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if(V) Log.v(TAG, "Added SMIL part"); 853fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 854fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie }else /*VIDEO/AUDIO/IMAGE*/ { 85570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz writeMmsDataPart(handle, part, count); 85670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if(V) Log.v(TAG, "Added OTHER part"); 857fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 858fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (uri != null && V){ 859fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.v(TAG, "Added part with content-type: "+ part.contentType + " to Uri: " + uri.toString()); 860fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 861fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 862fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (UnsupportedEncodingException e) { 86370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz Log.w(TAG, e); 864fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (IOException e) { 86570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz Log.w(TAG, e); 866fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 867fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 868fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.clear(); 869fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("contact_id", "null"); 870fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("address", "insert-address-token"); 871fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("type", BluetoothMapContent.MMS_FROM); 872fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("charset", 106); 873fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 874fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie uri = Uri.parse("content://mms/" + handle + "/addr"); 875fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie uri = cr.insert(uri, values); 876fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (uri != null && V){ 877fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.v(TAG, " NEW URI " + uri.toString()); 878fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 879fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 880fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.clear(); 881fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("contact_id", "null"); 882fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("address", to_address); 883fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("type", BluetoothMapContent.MMS_TO); 884fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("charset", 106); 885fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 886fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie uri = Uri.parse("content://mms/" + handle + "/addr"); 887fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie uri = cr.insert(uri, values); 888fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (uri != null && V){ 889fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.v(TAG, " NEW URI " + uri.toString()); 890fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 891fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return handle; 892fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 893fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 894fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 89570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz private void writeMmsDataPart(long handle, MimePart part, int count) throws IOException{ 896fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ContentValues values = new ContentValues(); 897fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.put("mid", handle); 89870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if(part.contentType != null) 89970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("ct", part.contentType); 90070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if(part.contentId != null) 90170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("cid", part.contentId); 90270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if(part.contentLocation != null) 90370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("cl", part.contentLocation); 90470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if(part.contentDisposition != null) 90570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("cd", part.contentDisposition); 90670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if(part.partName != null) { 90770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("fn", part.partName); 90870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("name", part.partName); 90970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } else if(part.contentId == null && part.contentLocation == null) { 91070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz /* We must set at least one part identifier */ 91170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("fn", "part_" + count + ".dat"); 91270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz values.put("name", "part_" + count + ".dat"); 91370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 914fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri partUri = Uri.parse("content://mms/" + handle + "/part"); 915fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri res = mResolver.insert(partUri, values); 916fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 917fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie // Add data to part 918fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie OutputStream os = mResolver.openOutputStream(res); 91970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz os.write(part.data); 920fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie os.close(); 921fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 922fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 923fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 924fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void sendMessage(PushMsgInfo msgInfo, String msgBody) { 925fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 926fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie SmsManager smsMng = SmsManager.getDefault(); 927fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ArrayList<String> parts = smsMng.divideMessage(msgBody); 928fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie msgInfo.parts = parts.size(); 929fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 930fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ArrayList<PendingIntent> deliveryIntents = new ArrayList<PendingIntent>(msgInfo.parts); 931fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>(msgInfo.parts); 932fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 933fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie for (int i = 0; i < msgInfo.parts; i++) { 934fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Intent intent; 935fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie intent = new Intent(ACTION_MESSAGE_DELIVERY, null); 936fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie intent.putExtra("HANDLE", msgInfo.id); 937fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie deliveryIntents.add(PendingIntent.getBroadcast(mContext, 0, intent, 938fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie PendingIntent.FLAG_UPDATE_CURRENT)); 939fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 940fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie intent = new Intent(ACTION_MESSAGE_SENT, null); 941fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie intent.putExtra("HANDLE", msgInfo.id); 942fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sentIntents.add(PendingIntent.getBroadcast(mContext, 0, intent, 943fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie PendingIntent.FLAG_UPDATE_CURRENT)); 944fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 945fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 946fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "sendMessage to " + msgInfo.phone); 947fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 948fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie smsMng.sendMultipartTextMessage(msgInfo.phone, null, parts, sentIntents, 949fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie deliveryIntents); 950fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 951fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 952fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private static final String ACTION_MESSAGE_DELIVERY = 953fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_DELIVERY"; 954fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private static final String ACTION_MESSAGE_SENT = 955fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_SENT"; 956fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 957fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private SmsBroadcastReceiver mSmsBroadcastReceiver = new SmsBroadcastReceiver(); 958fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 959fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private class SmsBroadcastReceiver extends BroadcastReceiver { 960fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private final String[] ID_PROJECTION = new String[] { Sms._ID }; 961fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private final Uri UPDATE_STATUS_URI = Uri.parse("content://sms/status"); 962fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 963fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void register() { 964400eaf8761223196a18b84247b066f0201226c3bHemant Gupta Handler handler = new Handler(Looper.getMainLooper()); 965fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 966fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie IntentFilter intentFilter = new IntentFilter(); 967fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie intentFilter.addAction(ACTION_MESSAGE_DELIVERY); 968fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie intentFilter.addAction(ACTION_MESSAGE_SENT); 969fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mContext.registerReceiver(this, intentFilter, null, handler); 970fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 971fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 972fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void unregister() { 973fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie try { 974fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mContext.unregisterReceiver(this); 975fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (IllegalArgumentException e) { 976fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* do nothing */ 977fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 978fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 979fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 980fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie @Override 981fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void onReceive(Context context, Intent intent) { 982fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String action = intent.getAction(); 983fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie long handle = intent.getLongExtra("HANDLE", -1); 984fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie PushMsgInfo msgInfo = mPushMsgList.get(handle); 985fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 986fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "onReceive: action" + action); 987fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 988fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (msgInfo == null) { 989fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "onReceive: no msgInfo found for handle " + handle); 990fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return; 991fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 992fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 993fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (action.equals(ACTION_MESSAGE_SENT)) { 994fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie msgInfo.partsSent++; 995fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (msgInfo.partsSent == msgInfo.parts) { 996fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie actionMessageSent(context, intent, msgInfo); 997fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 998fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else if (action.equals(ACTION_MESSAGE_DELIVERY)) { 999fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie msgInfo.partsDelivered++; 1000fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (msgInfo.partsDelivered == msgInfo.parts) { 1001fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie actionMessageDelivery(context, intent, msgInfo); 1002fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1003fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 1004fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "onReceive: Unknown action " + action); 1005fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1006fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1007fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1008fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void actionMessageSent(Context context, Intent intent, 1009fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie PushMsgInfo msgInfo) { 1010fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int result = getResultCode(); 1011fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie boolean delete = false; 1012fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1013fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (result == Activity.RESULT_OK) { 1014fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "actionMessageSent: result OK"); 1015fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (msgInfo.transparent == 0) { 1016fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (!Sms.moveMessageToFolder(context, msgInfo.uri, 1017fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.MESSAGE_TYPE_SENT, 0)) { 1018fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "Failed to move " + msgInfo.uri + " to SENT"); 1019fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1020fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 1021fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie delete = true; 1022fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1023fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1024fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Event evt = new Event("SendingSuccess", msgInfo.id, 1025fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie folderSms[Sms.MESSAGE_TYPE_SENT], null, mSmsType); 1026fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendEvent(evt); 1027fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1028fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 1029fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (msgInfo.retry == 1) { 1030fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Notify failure, but keep message in outbox for resending */ 1031fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie msgInfo.resend = true; 1032fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Event evt = new Event("SendingFailure", msgInfo.id, 1033fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie folderSms[Sms.MESSAGE_TYPE_OUTBOX], null, mSmsType); 1034fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendEvent(evt); 1035fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 1036fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (msgInfo.transparent == 0) { 1037fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (!Sms.moveMessageToFolder(context, msgInfo.uri, 1038fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.MESSAGE_TYPE_FAILED, 0)) { 1039fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "Failed to move " + msgInfo.uri + " to FAILED"); 1040fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1041fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 1042fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie delete = true; 1043fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1044fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1045fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Event evt = new Event("SendingFailure", msgInfo.id, 1046fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie folderSms[Sms.MESSAGE_TYPE_FAILED], null, mSmsType); 1047fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendEvent(evt); 1048fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1049fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1050fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1051fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (delete == true) { 1052fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Delete from Observer message list to avoid delete notifications */ 1053fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mMsgListSms.remove(msgInfo.id); 1054fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1055fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Delete from DB */ 1056fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mResolver.delete(msgInfo.uri, null, null); 1057fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1058fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1059fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1060fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void actionMessageDelivery(Context context, Intent intent, 1061fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie PushMsgInfo msgInfo) { 1062fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri messageUri = intent.getData(); 1063fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie byte[] pdu = intent.getByteArrayExtra("pdu"); 1064fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String format = intent.getStringExtra("format"); 1065fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1066fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie SmsMessage message = SmsMessage.createFromPdu(pdu, format); 1067fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (message == null) { 1068fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "actionMessageDelivery: Can't get message from pdu"); 1069fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return; 1070fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1071fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int status = message.getStatus(); 1072fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1073fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Cursor cursor = mResolver.query(msgInfo.uri, ID_PROJECTION, null, null, null); 1074fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1075fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie try { 1076fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (cursor.moveToFirst()) { 1077fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int messageId = cursor.getInt(0); 1078fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1079fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri updateUri = ContentUris.withAppendedId(UPDATE_STATUS_URI, messageId); 1080fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie boolean isStatusReport = message.isStatusReportMessage(); 1081fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1082fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "actionMessageDelivery: uri=" + messageUri + ", status=" + status + 1083fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ", isStatusReport=" + isStatusReport); 1084fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1085fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ContentValues contentValues = new ContentValues(2); 1086fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1087fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie contentValues.put(Sms.STATUS, status); 1088fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie contentValues.put(Inbox.DATE_SENT, System.currentTimeMillis()); 1089fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mResolver.update(updateUri, contentValues, null, null); 1090fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 1091fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "Can't find message for status update: " + messageUri); 1092fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1093fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } finally { 1094fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie cursor.close(); 1095fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1096fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1097fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (status == 0) { 1098fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Event evt = new Event("DeliverySuccess", msgInfo.id, 1099fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie folderSms[Sms.MESSAGE_TYPE_SENT], null, mSmsType); 1100fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendEvent(evt); 1101fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 1102fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Event evt = new Event("DeliveryFailure", msgInfo.id, 1103fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie folderSms[Sms.MESSAGE_TYPE_SENT], null, mSmsType); 1104fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendEvent(evt); 1105fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1106fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1107fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mPushMsgList.remove(msgInfo.id); 1108fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1109fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1110fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1111fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void registerPhoneServiceStateListener() { 1112fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie TelephonyManager tm = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE); 1113fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie tm.listen(mPhoneListener, PhoneStateListener.LISTEN_SERVICE_STATE); 1114fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1115fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1116fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void unRegisterPhoneServiceStateListener() { 1117fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie TelephonyManager tm = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE); 1118fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie tm.listen(mPhoneListener, PhoneStateListener.LISTEN_NONE); 1119fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1120fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1121fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void resendPendingMessages() { 1122fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Send pending messages in outbox */ 1123fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String where = "type = " + Sms.MESSAGE_TYPE_OUTBOX; 1124fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Cursor c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION, where, null, 1125fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie null); 1126fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1127fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (c != null && c.moveToFirst()) { 1128fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie do { 1129fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie long id = c.getLong(c.getColumnIndex(BaseColumns._ID)); 1130fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String msgBody = c.getString(c.getColumnIndex(Sms.BODY)); 1131fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie PushMsgInfo msgInfo = mPushMsgList.get(id); 1132fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (msgInfo == null || msgInfo.resend == false) { 1133fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie continue; 1134fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1135fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendMessage(msgInfo, msgBody); 1136fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } while (c.moveToNext()); 1137fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie c.close(); 1138fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1139fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1140fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1141fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void failPendingMessages() { 1142fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Move pending messages from outbox to failed */ 1143fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String where = "type = " + Sms.MESSAGE_TYPE_OUTBOX; 1144fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Cursor c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION, where, null, 1145fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie null); 1146fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1147fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (c != null && c.moveToFirst()) { 1148fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie do { 1149fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie long id = c.getLong(c.getColumnIndex(BaseColumns._ID)); 1150fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String msgBody = c.getString(c.getColumnIndex(Sms.BODY)); 1151fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie PushMsgInfo msgInfo = mPushMsgList.get(id); 1152fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (msgInfo == null || msgInfo.resend == false) { 1153fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie continue; 1154fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1155fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.moveMessageToFolder(mContext, msgInfo.uri, 1156fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.MESSAGE_TYPE_FAILED, 0); 1157fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } while (c.moveToNext()); 1158fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1159fac695e2dc25510b12684217d066b86dbbbba176Zhihai Xu if (c != null) c.close(); 1160fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1161fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1162fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void removeDeletedMessages() { 1163fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Remove messages from virtual "deleted" folder (thread_id -1) */ 1164fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mResolver.delete(Uri.parse("content://sms/"), 1165fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "thread_id = " + DELETED_THREAD_ID, null); 1166fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1167fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1168fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private PhoneStateListener mPhoneListener = new PhoneStateListener() { 1169fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie @Override 1170fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void onServiceStateChanged(ServiceState serviceState) { 1171fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "Phone service state change: " + serviceState.getState()); 1172fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) { 1173fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie resendPendingMessages(); 1174fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1175fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1176fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie }; 1177fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1178fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void init() { 1179fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mSmsBroadcastReceiver.register(); 1180fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie registerPhoneServiceStateListener(); 1181fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1182fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1183fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void deinit() { 1184fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mSmsBroadcastReceiver.unregister(); 1185fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie unRegisterPhoneServiceStateListener(); 1186fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie failPendingMessages(); 1187fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie removeDeletedMessages(); 1188fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1189fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie} 1190