Android - receiving long SMS (multipart)
Asked Answered
B

5

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?

Bluebonnet answered 29/11, 2010 at 16:58 Comment(1)
This may seem like a silly question, but is there a way to shorten the listened for message to below 160 characters?Hind
E
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) {

}
Earlearla answered 16/2, 2011 at 14:45 Comment(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?Hillock
And how about multiple senders: would it be possible for a single call to the onReceive()-method to contain messages from multiple sources?Hillock
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.Chromatolysis
C
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());
                        }
                    }
                }
Coker answered 21/11, 2015 at 13:41 Comment(0)
C
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.

Combustible answered 27/1, 2011 at 13:24 Comment(0)
G
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.

Gongorism answered 29/1, 2011 at 15:51 Comment(0)
S
1

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
            }
        }
    }
Stingo answered 1/9, 2023 at 12:22 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.