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