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,443
  • 12
  • 54
  • 76
  • 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

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,395
  • 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
  • 3,689
  • 1
  • 59
  • 69
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,595
  • 9
  • 77
  • 86
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
  • 23,572
  • 15
  • 99
  • 156
0

I faced with this problem 12 years later. You can handle this in the SMS BroadcastReceiver's onReceive method. The fullMessage string will be contain the original text message.

override fun onReceive(context: Context?, intent: Intent?) {
        if (intent?.action == Telephony.Sms.Intents.SMS_RECEIVED_ACTION) {
            var fullMessage = ""
            var originatingAddress = ""

            val smsMessages = Telephony.Sms.Intents.getMessagesFromIntent(intent)

            for (message in smsMessages) {
                originatingAddress = message.originatingAddress ?: ""
                fullMessage += message.messageBody
            }
        }
    }
Daniel
  • 1