I have read lots of posts on sending SMS and multipart SMS messages such as:
Sending SMS in Android, Sending and Receiving SMS and MMS in Android (pre Kit Kat Android 4.4), Android PendingIntent extras, not received by BroadcastReceiver
... and others, but they don't seem to go into checking that all parts of the message were sent successfully.
From what I understand, with a multi part message, you add a PendingIntent for each message part, but the examples I have seen don't seem to check that all parts are sent successfully... if one is (I guess the first one) they seem to assume it was successful...
So I thought I would send a multipart message and keep track of the parts. I would not say the message is successfully sent until all parts are successfully sent.
I have attempted to do this in the following code... SmsMessageInfo is just a simple class containing the phone number, a message and a list of booleans for parts processed and a list of parts successfully sent, it also has a unique message Id.
I have tried the following:
private void sendLongSmsMessage(Context context, final SmsMessageInfo messageInfo) {
// Receive when each part of the SMS has been sent (or does it????)
context.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String messageIdAsString = intent.getExtras().getString(INTENT_EXTRA_MESSAGE_ID_KEY);
Log.i("SMSMessageSender", "Broadcast Intent Recieved, IntentMessageID: " + messageIdAsString + " messageInfoId: " + messageInfo.messageId);
if (messageIdAsString != null) {
if (Long.parseLong(messageIdAsString) == messageInfo.messageId) {
String messagePartNrAsString = (String) intent.getExtras().get(INTENT_EXTRA_PART_NR_KEY);
int messagePartNr = Integer.parseInt(messagePartNrAsString);
Log.i("SMSMessageSender", "Broadcast Intent Recieved Multi Part Message Part No: " + messagePartNrAsString);
// We need to make all the parts succeed before we say we have succeeded.
switch (getResultCode()) {
case Activity.RESULT_OK:
messageInfo.partsSent.add(messagePartNr, true);
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
messageInfo.failMessage = "Error - Generic failure";
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
messageInfo.failMessage = "Error - No Service";
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
messageInfo.failMessage = "Error - Null PDU";
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
messageInfo.failMessage = "Error - Radio off";
break;
}
messageInfo.partsProcessed.add(messagePartNr, true);
boolean allSent = true;
for (Boolean partSent : messageInfo.partsSent) {
allSent = allSent && partSent;
}
messageInfo.sent = allSent;
boolean allProcessed = true;
for (Boolean partProcessed : messageInfo.partsProcessed) {
allProcessed = allProcessed && partProcessed;
}
if (allProcessed) {
// We have our response for all of our message parts, so we can unregister our receiver.
Log.i("SMSMessageSender", "All message part resoponses received, unregistering message Id: " + messageIdAsString);
context.unregisterReceiver(this);
}
} else {
Log.w("SMSMessageSender", "Received a broadcast message with Id for a different message");
}
} else {
Log.w("SMSMessageSender", "Received a broadcast message but not for message Id");
}
}
}, new IntentFilter(SENT));
ArrayList<String> messageList = SmsManager.getDefault().divideMessage(messageInfo.message);
ArrayList<PendingIntent> pendingIntents = new ArrayList<PendingIntent>(messageList.size());
messageInfo.partsSent.clear();
for (int i = 0; i < messageList.size(); i++) {
messageInfo.partsSent.add(i, false);
messageInfo.partsProcessed.add(i, false);
Intent sentIntent = new Intent(SENT);
sentIntent.putExtra(INTENT_EXTRA_MESSAGE_ID_KEY, Long.toString(messageInfo.messageId));
sentIntent.putExtra(INTENT_EXTRA_PART_NR_KEY, Integer.toString(i));
Log.i("SMSMessageSender", "Adding part " + i + " tp multi-part message Id: " + messageInfo.messageId);
pendingIntents.add(PendingIntent.getBroadcast(context, 0, sentIntent, PendingIntent.FLAG_ONE_SHOT));
}
Log.i("SMSMessageSender", "About to send multi-part message Id: " + messageInfo.messageId);
SmsManager.getDefault().sendMultipartTextMessage(messageInfo.phoneNumber, null, messageList, pendingIntents, null);
}
The problem with this is that the second message part never gets received.
It seems strange to have to go into all the hassle of creating multiple PendingIntents only to not go and check that they all worked.
In the log message where I show the Message Part No, it is always 0, I never get the second part, therefore this code never thinks it gets completed.
Am I just making it too complicated, should I just take any old PendingIntent that comes back and assume the same applies to the rest (in which case why did Google make you supply a list of them in the first place).
I apologise for the long question, but didn't really know how to ask more clearly in a shorter fashion :-)
Regards Colin