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?
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;
}