24

I have an application, which has to listen for specific SMS. So far easy.

But when I receive the message, it's multipart. Is there a proper way to receive the SMS as one message?

Now my activity starts two times, for each part of the sms. Should I concatenate the SMS by hand?

Danail
  • 10,303
  • 12
  • 52
  • 74
  • This may seem like a silly question, but is there a way to shorten the listened for message to below 160 characters? – Phobos Nov 30 '10 at 03:14

5 Answers5

22

It may be useful to look at how gTalkSMS handles incoming SMS'es, as it appears to handle multipart messages correctly.

Sebastian Paaske Tørholm
  • 47,464
  • 10
  • 95
  • 116
  • 2
    Thanks a lot for the link, it was really helpful. RetrieveMessages method in the link is what helped me to collect all the multipart messages in one. – class Android May 01 '15 at 12:46
  • Shame that the link is now dead – Armand May 17 '16 at 14:51
  • I read this line there `// There can be multiple SMS from multiple senders` how it could be possible? that multiple SMS from multiple Sender in one broadcast? – Asif Mushtaq Dec 28 '17 at 20:29
11
Bundle bundle  = intent.getExtras();
Object[] pdus = (Object[]) bundle.get("pdus");
            messages = new SmsMessage[pdus.length];
            for (int i = 0; i < pdus.length; i++)
            {
                messages[i] =
                    SmsMessage.createFromPdu((byte[]) pdus[i]);
            }

SmsMessage sms = messages[0];
try {
  if (messages.length == 1 || sms.isReplace()) {
    body = sms.getDisplayMessageBody();
  } else {
    StringBuilder bodyText = new StringBuilder();
    for (int i = 0; i < messages.length; i++) {
      bodyText.append(messages[i].getMessageBody());
    }
    body = bodyText.toString();
  }
} catch (Exception e) {

}
om252345
  • 2,365
  • 4
  • 29
  • 31
  • 3
    Thanks, works for me. Any idea how well this works in practice? Could the PDUs for example come in wrong order in real networks? Or could the receiver be triggered once with part1, and then another time with part2? – Asmo Soinio Feb 17 '11 at 11:27
  • 3
    And how about multiple senders: would it be possible for a single call to the onReceive()-method to contain messages from multiple sources? – Asmo Soinio Feb 17 '11 at 11:29
  • The above code is full of holes.The GSM spec says you should not assume PDU's are delivered in sequence. Also the throughput for GSM messages is about 6 - 10 / minute, you you have a multipart that contains more (or you are receiving several messages at once) the operator will standoff and retry later. – Lieuwe Feb 28 '14 at 15:04
3

Shorter solution:

if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
                    Bundle bundle = intent.getExtras();           //---get the SMS message passed in---
                    SmsMessage[] msgs = null;

                    if (bundle != null) {
                        //---retrieve the SMS message received---
                        try {
                            Object[] pdus = (Object[]) bundle.get("pdus");
                            msgs = new SmsMessage[pdus.length];
                            String msgBody = "";
                            String msg_from = "";
                            for (int i = 0; i < msgs.length; i++) {
                                msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                                msg_from = msgs[i].getOriginatingAddress();
                                msgBody += msgs[i].getMessageBody();
                            }

                        } catch (Exception e) {
    //                            Log.d("Exception caught",e.getMessage());
                        }
                    }
                }
M. Usman Khan
  • 4,214
  • 1
  • 52
  • 66
1

Yes you should concatenate the SMS by hand, but obviously you don't want to be starting up a new activity for each message segment.

I suggest setting your Activity's launchMode attribute to singleTask or singleInstance so that that doesn't happen.

Alternatively have your SMS's received by a Service, which will fire up a new Activity only once it has a complete message.

Reuben Scratton
  • 38,312
  • 9
  • 75
  • 85
1

I am not aware of a way to recive a multipart message as once. But if you have the right intent-filter setup you get only one Intent for more than one SMS. In fact, the Intent can contain SMS from different senders and/or zero or more multipart SMS .

You could try this approach:

Add an SmsReceiver Class with intent-filter android.provider.Telephony.SMS_RECEIVED in the Manifest.

The classes onReceive Method will get an intent with a bundle of pdus. These pdu's can origin from different senders each and/or there can be more pdus from the same sender in case of a multipart text message, which you have to concatenate.

Flow
  • 22,860
  • 14
  • 95
  • 151