mirror of
https://github.com/oxen-io/session-android.git
synced 2023-12-14 02:53:01 +01:00
Add support for "delivery notifications." Currently SMS-only.
This commit is contained in:
parent
118560cf0d
commit
5cb02445e8
19 changed files with 174 additions and 61 deletions
BIN
res/drawable-hdpi/ic_sms_mms_delivered.png
Normal file
BIN
res/drawable-hdpi/ic_sms_mms_delivered.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 927 B |
BIN
res/drawable-mdpi/ic_sms_mms_delivered.png
Normal file
BIN
res/drawable-mdpi/ic_sms_mms_delivered.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 692 B |
BIN
res/drawable-xhdpi/ic_sms_mms_delivered.png
Normal file
BIN
res/drawable-xhdpi/ic_sms_mms_delivered.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
|
@ -96,6 +96,13 @@
|
|||
android:orientation="horizontal"
|
||||
android:gravity="left">
|
||||
|
||||
<ImageView android:id="@+id/delivered_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="3dip"
|
||||
android:src="@drawable/ic_sms_mms_delivered"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView android:id="@+id/group_message_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -105,8 +112,7 @@
|
|||
android:textColor="#ffcccccc"
|
||||
android:visibility="gone"
|
||||
android:layout_marginRight="8dip"
|
||||
android:paddingTop="1dip"/>
|
||||
|
||||
android:paddingTop="1dip"/>
|
||||
|
||||
<TextView android:id="@+id/conversation_item_date"
|
||||
android:autoLink="all"
|
||||
|
|
|
@ -118,6 +118,13 @@
|
|||
android:orientation="horizontal"
|
||||
android:gravity="right">
|
||||
|
||||
<ImageView android:id="@+id/delivered_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="3dip"
|
||||
android:src="@drawable/ic_sms_mms_delivered"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView android:id="@+id/group_message_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -1,22 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
* Copyright (C) 2007-2008 Esmertec AG.
|
||||
* Copyright (C) 2007-2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceCategory android:title="@string/preferences__use_settings">
|
||||
<CheckBoxPreference android:defaultValue="true"
|
||||
|
@ -31,6 +14,19 @@
|
|||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="Delivery Reports">
|
||||
<CheckBoxPreference android:defaultValue="false"
|
||||
android:key="pref_delivery_report_sms"
|
||||
android:summary="Request a delivery report for each SMS message you send"
|
||||
android:title="SMS delivery reports" />
|
||||
|
||||
<CheckBoxPreference android:defaultValue="false"
|
||||
android:key="pref_delivery_report_mms"
|
||||
android:summary="Request a delivery report for each MMS message you send"
|
||||
android:enabled="false"
|
||||
android:title="MMS delivery reports" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/preferences__input_settings">
|
||||
<CheckBoxPreference android:defaultValue="false"
|
||||
android:key="pref_enter_sends"
|
||||
|
|
|
@ -80,6 +80,9 @@ public class ApplicationPreferencesActivity extends SherlockPreferenceActivity {
|
|||
public static final String MMSC_PROXY_HOST_PREF = "pref_apn_mms_proxy";
|
||||
public static final String MMSC_PROXY_PORT_PREF = "pref_apn_mms_proxy_port";
|
||||
|
||||
public static final String SMS_DELIVERY_REPORT_PREF = "pref_delivery_report_sms";
|
||||
public static final String MMS_DELIVERY_REPORT_PREF = "pref_delivery_report_mms";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
|
|
@ -208,6 +208,7 @@ public class ConversationAdapter extends CursorAdapter {
|
|||
long dateReceived = cursor.getLong(cursor.getColumnIndexOrThrow(MmsSmsDatabase.DATE_RECEIVED));
|
||||
long dateSent = cursor.getLong(cursor.getColumnIndexOrThrow(MmsSmsDatabase.DATE_SENT));
|
||||
long type = cursor.getLong(cursor.getColumnIndexOrThrow(SmsDatabase.TYPE));
|
||||
int status = cursor.getInt(cursor.getColumnIndexOrThrow(SmsDatabase.STATUS));
|
||||
String body = cursor.getString(cursor.getColumnIndexOrThrow(SmsDatabase.BODY));
|
||||
String address = cursor.getString(cursor.getColumnIndexOrThrow(SmsDatabase.ADDRESS));
|
||||
Recipient recipient = getIndividualRecipientFor(address);
|
||||
|
@ -226,7 +227,7 @@ public class ConversationAdapter extends CursorAdapter {
|
|||
|
||||
SmsMessageRecord messageRecord = new SmsMessageRecord(context, messageId, recipients,
|
||||
recipient, dateSent, dateReceived,
|
||||
type, threadId, groupData);
|
||||
type, threadId, status, groupData);
|
||||
|
||||
if (body == null) {
|
||||
body = "";
|
||||
|
|
|
@ -84,6 +84,7 @@ public class ConversationItem extends LinearLayout {
|
|||
private ImageView failedImage;
|
||||
private ImageView keyImage;
|
||||
private ImageView contactPhoto;
|
||||
private ImageView deliveredImage;
|
||||
|
||||
private ImageView mmsThumbnail;
|
||||
private Button mmsDownloadButton;
|
||||
|
@ -118,6 +119,7 @@ public class ConversationItem extends LinearLayout {
|
|||
this.mmsDownloadButton = (Button) findViewById(R.id.mms_download_button);
|
||||
this.mmsDownloadingLabel = (TextView) findViewById(R.id.mms_label_downloading);
|
||||
this.contactPhoto = (ImageView)findViewById(R.id.contact_photo);
|
||||
this.deliveredImage = (ImageView)findViewById(R.id.delivered_indicator);
|
||||
|
||||
setOnClickListener(clickListener);
|
||||
this.failedImage.setOnClickListener(failedIconClickListener);
|
||||
|
@ -182,6 +184,7 @@ public class ConversationItem extends LinearLayout {
|
|||
failedImage.setVisibility(messageRecord.isFailed() ? View.VISIBLE : View.GONE);
|
||||
secureImage.setVisibility(messageRecord.isSecure() ? View.VISIBLE : View.GONE);
|
||||
keyImage.setVisibility(messageRecord.isKeyExchange() ? View.VISIBLE : View.GONE);
|
||||
deliveredImage.setVisibility(!messageRecord.isKeyExchange() && messageRecord.isDelivered() ? View.VISIBLE : View.GONE);
|
||||
|
||||
mmsThumbnail.setVisibility(View.GONE);
|
||||
mmsDownloadButton.setVisibility(View.GONE);
|
||||
|
|
|
@ -93,7 +93,7 @@ public class MmsSmsDatabase extends Database {
|
|||
String[] projection = {"_id", "body", "type", "address", "subject",
|
||||
"normalized_date_sent AS date_sent",
|
||||
"normalized_date_received AS date_received",
|
||||
"m_type", "msg_box", "transport_type"};
|
||||
"m_type", "msg_box", "status", "transport_type"};
|
||||
String order = "normalized_date_received ASC";
|
||||
String selection = "thread_id = " + threadId;
|
||||
|
||||
|
@ -135,8 +135,8 @@ public class MmsSmsDatabase extends Database {
|
|||
}
|
||||
|
||||
private Cursor queryTables(String[] projection, String selection, String order, String groupBy, String limit) {
|
||||
String[] mmsProjection = {"date * 1000 AS normalized_date_sent", "date_received * 1000 AS normalized_date_received", "_id", "body", "read", "thread_id", "type", "address", "subject", "date", "m_type", "msg_box", "transport_type"};
|
||||
String[] smsProjection = {"date_sent * 1 AS normalized_date_sent", "date * 1 AS normalized_date_received", "_id", "body", "read", "thread_id", "type", "address", "subject", "date", "m_type", "msg_box", "transport_type"};
|
||||
String[] mmsProjection = {"date * 1000 AS normalized_date_sent", "date_received * 1000 AS normalized_date_received", "_id", "body", "read", "thread_id", "type", "address", "subject", "date", "m_type", "msg_box", "status", "transport_type"};
|
||||
String[] smsProjection = {"date_sent * 1 AS normalized_date_sent", "date * 1 AS normalized_date_received", "_id", "body", "read", "thread_id", "type", "address", "subject", "date", "m_type", "msg_box", "status", "transport_type"};
|
||||
|
||||
SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
|
||||
SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
|
||||
|
@ -166,6 +166,7 @@ public class MmsSmsDatabase extends Database {
|
|||
smsColumnsPresent.add("date");
|
||||
smsColumnsPresent.add("read");
|
||||
smsColumnsPresent.add("thread_id");
|
||||
smsColumnsPresent.add("status");
|
||||
|
||||
String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery("transport_type", mmsProjection, mmsColumnsPresent, 2, "mms", selection, null, null, null);
|
||||
String smsSubQuery = smsQueryBuilder.buildUnionSubQuery("transport_type", smsProjection, smsColumnsPresent, 2, "sms", selection, null, null, null);
|
||||
|
|
|
@ -170,6 +170,16 @@ public class SmsDatabase extends Database {
|
|||
updateType(id, Types.SENT_TYPE);
|
||||
}
|
||||
|
||||
public void markStatus(long id, int status) {
|
||||
Log.w("MessageDatabase", "Updating ID: " + id + " to status: " + status);
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(STATUS, status);
|
||||
|
||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||
db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {id+""});
|
||||
notifyConversationListeners(getThreadIdForMessage(id));
|
||||
}
|
||||
|
||||
public void markAsSentFailed(long id) {
|
||||
updateType(id, Types.FAILED_TYPE);
|
||||
}
|
||||
|
@ -317,6 +327,13 @@ public class SmsDatabase extends Database {
|
|||
" VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
}
|
||||
|
||||
public static class Status {
|
||||
public static final int STATUS_NONE = -1;
|
||||
public static final int STATUS_COMPLETE = 0;
|
||||
public static final int STATUS_PENDING = 32;
|
||||
public static final int STATUS_FAILED = 64;
|
||||
}
|
||||
|
||||
public static class Types {
|
||||
public static final int INBOX_TYPE = 1;
|
||||
public static final int SENT_TYPE = 2;
|
||||
|
|
|
@ -46,7 +46,8 @@ public class MediaMmsMessageRecord extends MessageRecord {
|
|||
long threadId, SlideDeck slideDeck, long mailbox,
|
||||
GroupData groupData)
|
||||
{
|
||||
super(id, recipients, individualRecipient, dateSent, dateReceived, threadId, groupData);
|
||||
super(id, recipients, individualRecipient, dateSent, dateReceived,
|
||||
threadId, DELIVERY_STATUS_NONE, groupData);
|
||||
this.slideDeck = slideDeck;
|
||||
this.mailbox = mailbox;
|
||||
|
||||
|
|
|
@ -29,18 +29,26 @@ import org.thoughtcrime.securesms.recipients.Recipients;
|
|||
*/
|
||||
public abstract class MessageRecord extends DisplayRecord {
|
||||
|
||||
public static final int DELIVERY_STATUS_NONE = 0;
|
||||
public static final int DELIVERY_STATUS_RECEIVED = 1;
|
||||
public static final int DELIVERY_STATUS_PENDING = 2;
|
||||
public static final int DELIVERY_STATUS_FAILED = 3;
|
||||
|
||||
private final Recipient individualRecipient;
|
||||
private final long id;
|
||||
private final int deliveryStatus;
|
||||
private final GroupData groupData;
|
||||
|
||||
public MessageRecord(long id, Recipients recipients,
|
||||
Recipient individualRecipient,
|
||||
long dateSent, long dateReceived,
|
||||
long threadId, GroupData groupData)
|
||||
long threadId, int deliveryStatus,
|
||||
GroupData groupData)
|
||||
{
|
||||
super(recipients, dateSent, dateReceived, threadId);
|
||||
this.id = id;
|
||||
this.individualRecipient = individualRecipient;
|
||||
this.deliveryStatus = deliveryStatus;
|
||||
this.groupData = groupData;
|
||||
}
|
||||
|
||||
|
@ -58,6 +66,14 @@ public abstract class MessageRecord extends DisplayRecord {
|
|||
return id;
|
||||
}
|
||||
|
||||
public int getDeliveryStatus() {
|
||||
return deliveryStatus;
|
||||
}
|
||||
|
||||
public boolean isDelivered() {
|
||||
return getDeliveryStatus() == DELIVERY_STATUS_RECEIVED;
|
||||
}
|
||||
|
||||
public boolean isStaleKeyExchange() {
|
||||
return this.staleKeyExchange;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,9 @@ public class NotificationMmsMessageRecord extends MessageRecord {
|
|||
byte[] contentLocation, long messageSize, long expiry,
|
||||
int status, byte[] transactionId)
|
||||
{
|
||||
super(id, recipients, individualRecipient, dateSent, dateReceived, threadId, null);
|
||||
super(id, recipients, individualRecipient, dateSent, dateReceived,
|
||||
threadId, DELIVERY_STATUS_NONE, null);
|
||||
|
||||
this.contentLocation = contentLocation;
|
||||
this.messageSize = messageSize;
|
||||
this.expiry = expiry;
|
||||
|
|
|
@ -36,19 +36,18 @@ public class SmsMessageRecord extends MessageRecord {
|
|||
|
||||
private final Context context;
|
||||
private final long type;
|
||||
private final long dateSent;
|
||||
|
||||
public SmsMessageRecord(Context context, long id,
|
||||
Recipients recipients,
|
||||
Recipient individualRecipient,
|
||||
long dateSent, long dateReceived,
|
||||
long type, long threadId,
|
||||
GroupData groupData)
|
||||
int status, GroupData groupData)
|
||||
{
|
||||
super(id, recipients, individualRecipient, dateSent, dateReceived, threadId, groupData);
|
||||
super(id, recipients, individualRecipient, dateSent, dateReceived,
|
||||
threadId, getGenericDeliveryStatus(status), groupData);
|
||||
this.context = context.getApplicationContext();
|
||||
this.type = type;
|
||||
this.dateSent = dateSent;
|
||||
}
|
||||
|
||||
public long getType() {
|
||||
|
@ -76,7 +75,8 @@ public class SmsMessageRecord extends MessageRecord {
|
|||
|
||||
@Override
|
||||
public boolean isFailed() {
|
||||
return SmsDatabase.Types.isFailedMessageType(getType());
|
||||
return SmsDatabase.Types.isFailedMessageType(getType()) ||
|
||||
getDeliveryStatus() == DELIVERY_STATUS_FAILED;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -99,4 +99,15 @@ public class SmsMessageRecord extends MessageRecord {
|
|||
return false;
|
||||
}
|
||||
|
||||
private static int getGenericDeliveryStatus(int status) {
|
||||
if (status == SmsDatabase.Status.STATUS_NONE) {
|
||||
return MessageRecord.DELIVERY_STATUS_NONE;
|
||||
} else if (status >= SmsDatabase.Status.STATUS_FAILED) {
|
||||
return MessageRecord.DELIVERY_STATUS_FAILED;
|
||||
} else if (status >= SmsDatabase.Status.STATUS_PENDING) {
|
||||
return MessageRecord.DELIVERY_STATUS_PENDING;
|
||||
} else {
|
||||
return MessageRecord.DELIVERY_STATUS_RECEIVED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ public class SendReceiveService extends Service {
|
|||
|
||||
public static final String SEND_SMS_ACTION = "org.thoughtcrime.securesms.SendReceiveService.SEND_SMS_ACTION";
|
||||
public static final String SENT_SMS_ACTION = "org.thoughtcrime.securesms.SendReceiveService.SENT_SMS_ACTION";
|
||||
public static final String DELIVERED_SMS_ACTION = "org.thoughtcrime.securesms.SendReceiveService.DELIVERED_SMS_ACTION";
|
||||
public static final String RECEIVE_SMS_ACTION = "org.thoughtcrime.securesms.SendReceiveService.RECEIVE_SMS_ACTION";
|
||||
public static final String SEND_MMS_ACTION = "org.thoughtcrime.securesms.SendReceiveService.SEND_MMS_ACTION";
|
||||
public static final String SEND_MMS_CONNECTIVITY_ACTION = "org.thoughtcrime.securesms.SendReceiveService.SEND_MMS_CONNECTIVITY_ACTION";
|
||||
|
@ -93,6 +94,8 @@ public class SendReceiveService extends Service {
|
|||
scheduleIntent(RECEIVE_SMS, intent);
|
||||
else if (intent.getAction().equals(SENT_SMS_ACTION))
|
||||
scheduleIntent(RECEIVE_SMS, intent);
|
||||
else if (intent.getAction().equals(DELIVERED_SMS_ACTION))
|
||||
scheduleIntent(RECEIVE_SMS, intent);
|
||||
else if (intent.getAction().equals(SEND_MMS_ACTION) || intent.getAction().equals(SEND_MMS_CONNECTIVITY_ACTION))
|
||||
scheduleSecretRequiredIntent(SEND_MMS, intent);
|
||||
else if (intent.getAction().equals(RECEIVE_MMS_ACTION))
|
||||
|
@ -191,8 +194,8 @@ public class SendReceiveService extends Service {
|
|||
|
||||
public void run() {
|
||||
switch (what) {
|
||||
case RECEIVE_SMS: smsReceiver.process(masterSecret, intent); return;
|
||||
case SEND_SMS: smsSender.process(masterSecret, intent); return;
|
||||
case RECEIVE_SMS: smsReceiver.process(masterSecret, intent); return;
|
||||
case SEND_SMS: smsSender.process(masterSecret, intent); return;
|
||||
case RECEIVE_MMS: mmsReceiver.process(masterSecret, intent); return;
|
||||
case SEND_MMS: mmsSender.process(masterSecret, intent); return;
|
||||
case DOWNLOAD_MMS: mmsDownloader.process(masterSecret, intent); return;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
/**
|
||||
* Copyright (C) 2011 Whisper Systems
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
|
@ -10,14 +10,12 @@
|
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.thoughtcrime.securesms.service;
|
||||
|
||||
import org.thoughtcrime.securesms.protocol.WirePrefix;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
@ -26,6 +24,8 @@ import android.preference.PreferenceManager;
|
|||
import android.telephony.SmsMessage;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.protocol.WirePrefix;
|
||||
|
||||
public class SmsListener extends BroadcastReceiver {
|
||||
|
||||
private static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
|
||||
|
@ -40,58 +40,58 @@ public class SmsListener extends BroadcastReceiver {
|
|||
if (messageBody.startsWith("Sparebank1://otp?")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Sprint Visual Voicemail
|
||||
return
|
||||
message.getOriginatingAddress().length() < 7 &&
|
||||
(messageBody.startsWith("//ANDROID:") || messageBody.startsWith("//Android:") ||
|
||||
return
|
||||
message.getOriginatingAddress().length() < 7 &&
|
||||
(messageBody.startsWith("//ANDROID:") || messageBody.startsWith("//Android:") ||
|
||||
messageBody.startsWith("//android:") || messageBody.startsWith("//BREW:"));
|
||||
}
|
||||
|
||||
|
||||
private SmsMessage getSmsMessageFromIntent(Intent intent) {
|
||||
Bundle bundle = intent.getExtras();
|
||||
Object[] pdus = (Object[])bundle.get("pdus");
|
||||
|
||||
if (pdus == null || pdus.length == 0)
|
||||
return null;
|
||||
|
||||
|
||||
return SmsMessage.createFromPdu((byte[])pdus[0]);
|
||||
}
|
||||
|
||||
|
||||
private String getSmsMessageBodyFromIntent(Intent intent) {
|
||||
Bundle bundle = intent.getExtras();
|
||||
Object[] pdus = (Object[])bundle.get("pdus");
|
||||
StringBuilder bodyBuilder = new StringBuilder();
|
||||
|
||||
|
||||
if (pdus == null)
|
||||
return null;
|
||||
|
||||
|
||||
for (int i=0;i<pdus.length;i++)
|
||||
bodyBuilder.append(SmsMessage.createFromPdu((byte[])pdus[i]).getDisplayMessageBody());
|
||||
|
||||
return bodyBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
private boolean isRelevent(Context context, Intent intent) {
|
||||
SmsMessage message = getSmsMessageFromIntent(intent);
|
||||
String messageBody = getSmsMessageBodyFromIntent(intent);
|
||||
|
||||
if (message == null && messageBody == null)
|
||||
return false;
|
||||
|
||||
|
||||
if (isExemption(message, messageBody))
|
||||
return false;
|
||||
|
||||
|
||||
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("pref_all_sms", true))
|
||||
return true;
|
||||
return true;
|
||||
|
||||
return WirePrefix.isEncryptedMessage(messageBody) || WirePrefix.isKeyExchange(messageBody);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Log.w("SMSListener", "Got SMS broadcast...");
|
||||
|
||||
|
||||
if (intent.getAction().equals(SMS_RECEIVED_ACTION) && isRelevent(context, intent)) {
|
||||
intent.setAction(SendReceiveService.RECEIVE_SMS_ACTION);
|
||||
intent.putExtra("ResultCode", this.getResultCode());
|
||||
|
@ -103,6 +103,10 @@ public class SmsListener extends BroadcastReceiver {
|
|||
intent.putExtra("ResultCode", this.getResultCode());
|
||||
intent.setClass(context, SendReceiveService.class);
|
||||
context.startService(intent);
|
||||
} else if (intent.getAction().equals(SendReceiveService.DELIVERED_SMS_ACTION)) {
|
||||
intent.putExtra("ResultCode", this.getResultCode());
|
||||
intent.setClass(context, SendReceiveService.class);
|
||||
context.startService(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -176,10 +176,26 @@ public class SmsReceiver {
|
|||
DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageId);
|
||||
}
|
||||
|
||||
private void handleDeliveredMessage(Intent intent) {
|
||||
long messageId = intent.getLongExtra("message_id", -1);
|
||||
long type = intent.getLongExtra("type", -1);
|
||||
byte[] pdu = intent.getByteArrayExtra("pdu");
|
||||
String format = intent.getStringExtra("format");
|
||||
SmsMessage message = SmsMessage.createFromPdu(pdu);
|
||||
|
||||
if (message == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
DatabaseFactory.getSmsDatabase(context).markStatus(messageId, message.getStatus());
|
||||
}
|
||||
|
||||
public void process(MasterSecret masterSecret, Intent intent) {
|
||||
if (intent.getAction().equals(SendReceiveService.RECEIVE_SMS_ACTION))
|
||||
handleReceiveMessage(masterSecret, intent);
|
||||
else if (intent.getAction().equals(SendReceiveService.SENT_SMS_ACTION))
|
||||
handleSentMessage(intent);
|
||||
else if (intent.getAction().equals(SendReceiveService.DELIVERED_SMS_ACTION))
|
||||
handleDeliveredMessage(intent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,11 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.telephony.SmsManager;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.ApplicationPreferencesActivity;
|
||||
import org.thoughtcrime.securesms.crypto.MasterCipher;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.crypto.SessionCipher;
|
||||
|
@ -111,15 +113,36 @@ public class SmsSender {
|
|||
return sentIntents;
|
||||
}
|
||||
|
||||
private ArrayList<PendingIntent> constructDeliveredIntents(long messageId, long type, ArrayList<String> messages) {
|
||||
if (!PreferenceManager.getDefaultSharedPreferences(context)
|
||||
.getBoolean(ApplicationPreferencesActivity.SMS_DELIVERY_REPORT_PREF, false))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ArrayList<PendingIntent> deliveredIntents = new ArrayList<PendingIntent>(messages.size());
|
||||
|
||||
for (int i=0;i<messages.size();i++) {
|
||||
Intent pending = new Intent(SendReceiveService.DELIVERED_SMS_ACTION, Uri.parse("custom://" + messageId + System.currentTimeMillis()), context, SmsListener.class);
|
||||
pending.putExtra("type", type);
|
||||
pending.putExtra("message_id", messageId);
|
||||
deliveredIntents.add(PendingIntent.getBroadcast(context, 0, pending, 0));
|
||||
}
|
||||
|
||||
return deliveredIntents;
|
||||
}
|
||||
|
||||
private void deliverGSMTransportTextMessage(String recipient, String text, long messageId, long type) {
|
||||
ArrayList<String> messages = SmsManager.getDefault().divideMessage(text);
|
||||
ArrayList<PendingIntent> sentIntents = constructSentIntents(messageId, type, messages);
|
||||
ArrayList<String> messages = SmsManager.getDefault().divideMessage(text);
|
||||
ArrayList<PendingIntent> sentIntents = constructSentIntents(messageId, type, messages);
|
||||
ArrayList<PendingIntent> deliveredIntents = constructDeliveredIntents(messageId, type, messages);
|
||||
|
||||
// XXX moxie@thoughtcrime.org 1/7/11 -- There's apparently a bug where for some unknown recipients
|
||||
// and messages, this will throw an NPE. I have no idea why, so I'm just catching it and marking
|
||||
// the message as a failure. That way at least it doesn't repeatedly crash every time you start
|
||||
// the app.
|
||||
try {
|
||||
SmsManager.getDefault().sendMultipartTextMessage(recipient, null, messages, sentIntents, null);
|
||||
SmsManager.getDefault().sendMultipartTextMessage(recipient, null, messages, sentIntents, deliveredIntents);
|
||||
} catch (NullPointerException npe) {
|
||||
Log.w("SmsSender", npe);
|
||||
DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageId);
|
||||
|
@ -142,15 +165,18 @@ public class SmsSender {
|
|||
return;
|
||||
}
|
||||
|
||||
ArrayList<String> messages = multipartMessageHandler.divideMessage(recipient, text, prefix);
|
||||
ArrayList<PendingIntent> sentIntents = constructSentIntents(messageId, type, messages);
|
||||
ArrayList<String> messages = multipartMessageHandler.divideMessage(recipient, text, prefix);
|
||||
ArrayList<PendingIntent> sentIntents = constructSentIntents(messageId, type, messages);
|
||||
ArrayList<PendingIntent> deliveredIntents = constructDeliveredIntents(messageId, type, messages);
|
||||
|
||||
for (int i=0;i<messages.size();i++) {
|
||||
// XXX moxie@thoughtcrime.org 1/7/11 -- There's apparently a bug where for some unknown recipients
|
||||
// and messages, this will throw an NPE. I have no idea why, so I'm just catching it and marking
|
||||
// the message as a failure. That way at least it doesn't repeatedly crash every time you start
|
||||
// the app.
|
||||
try {
|
||||
SmsManager.getDefault().sendTextMessage(recipient, null, messages.get(i), sentIntents.get(i), null);
|
||||
SmsManager.getDefault().sendTextMessage(recipient, null, messages.get(i), sentIntents.get(i),
|
||||
deliveredIntents == null ? null : deliveredIntents.get(i));
|
||||
} catch (NullPointerException npe) {
|
||||
Log.w("SmsSender", npe);
|
||||
DatabaseFactory.getSmsDatabase(context).markAsSentFailed(messageId);
|
||||
|
|
Loading…
Reference in a new issue