In Android, if I want to read an incoming SMS, I would use SmsMessage.createFromPdu
, but this returns an array of SmsMessage
s. Why is that? Why not just a single SmsMessage
? Is it because long messages could be divided into several? If so, does that mean I can count on all these SmsMessage
s to have the same originating address?

- 6,190
- 3
- 41
- 61
2 Answers
After doing tons of research, here's the deal:
Yes, these messages that you get are the broken down pieces of a larger message.
The array of SmsMessage
s contains messages that may or may not be related to each other (different senders). Why Android mixes them up like that? I don't know. You should always loop through them and group them by SmsMessage.getDisplayOriginatingAddress()
. Then, for each group of messages, append their bodies from SmsMessage.getDisplayMessageBody()
to reconstruct the larger message.
Here's an example from the GTalk app source (thanks @hungryghost):
private static Map<String, String> RetrieveMessages(Intent intent) {
Map<String, String> msg = null;
SmsMessage[] msgs;
Bundle bundle = intent.getExtras();
if (bundle != null && bundle.containsKey("pdus")) {
Object[] pdus = (Object[]) bundle.get("pdus");
if (pdus != null) {
int nbrOfpdus = pdus.length;
msg = new HashMap<String, String>(nbrOfpdus);
msgs = new SmsMessage[nbrOfpdus];
// There can be multiple SMS from multiple senders, there can be a maximum of nbrOfpdus different senders
// However, send long SMS of same sender in one message
for (int i = 0; i < nbrOfpdus; i++) {
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
String originatinAddress = msgs[i].getDisplayOriginatingAddress();
// Check if index with number exists
if (!msg.containsKey(originatinAddress)) {
// Index with number doesn't exist
// Save string into associative array with sender number as index
msg.put(msgs[i].getOriginatingAddress(), msgs[i].getDisplayMessageBody());
} else {
// Number has been there, add content but consider that
// msg.get(originatinAddress) already contains sms:sndrNbr:previousparts of SMS,
// so just add the part of the current PDU
String previousparts = msg.get(originatinAddress);
String msgString = previousparts + msgs[i].getMessageBody();
msg.put(originatinAddress, msgString);
}
}
}
}
return msg;
}

- 6,190
- 3
- 41
- 61
It returns an array in order to support concatenated multi-part SMS (for messages longer than the normal ~160 char limit). Each message may or may not have the same originating address depending on whether or not they share the same header info.
http://en.wikipedia.org/wiki/Concatenated_SMS
http://en.wikipedia.org/wiki/Protocol_data_unit
Message may be out of sequence and may be from different senders. Take a look at these links for discussion on how to concatenate multi-part SMS, including a good code example.

- 1
- 1

- 9,463
- 3
- 23
- 36
-
Thank you. Also, are the messages in the array in the proper order? On the first article, it says that messages are very unlikely to arrive in the proper order. Does Android take care of that by the time I get a hold of the array? – AxiomaticNexus Jun 12 '14 at 18:38
-
Sorry, I may have been wrong. You should check originating address when reconstructing your multi-part sms. I've edited the answer and added links describing the process. – hungryghost Jun 12 '14 at 22:08