Android – Listen For Incoming SMS Messages Android – Listen For Incoming SMS Messages android android

Android – Listen For Incoming SMS Messages


public class SmsListener extends BroadcastReceiver{    private SharedPreferences preferences;    @Override    public void onReceive(Context context, Intent intent) {        // TODO Auto-generated method stub        if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){            Bundle bundle = intent.getExtras();           //---get the SMS message passed in---            SmsMessage[] msgs = null;            String msg_from;            if (bundle != null){                //---retrieve the SMS message received---                try{                    Object[] pdus = (Object[]) bundle.get("pdus");                    msgs = new SmsMessage[pdus.length];                    for(int i=0; i<msgs.length; i++){                        msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);                        msg_from = msgs[i].getOriginatingAddress();                        String msgBody = msgs[i].getMessageBody();                    }                }catch(Exception e){//                            Log.d("Exception caught",e.getMessage());                }            }        }    }}

Note: In your manifest file add the BroadcastReceiver-

<receiver android:name=".listener.SmsListener">    <intent-filter>        <action android:name="android.provider.Telephony.SMS_RECEIVED" />    </intent-filter></receiver>

Add this permission:

<uses-permission android:name="android.permission.RECEIVE_SMS" />


Note that on some devices your code wont work without android:priority="1000" in intent filter:

<receiver android:name=".listener.SmsListener">    <intent-filter android:priority="1000">        <action android:name="android.provider.Telephony.SMS_RECEIVED" />    </intent-filter></receiver>

And here is some optimizations:

public class SmsListener extends BroadcastReceiver{    @Override    public void onReceive(Context context, Intent intent) {        if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(intent.getAction())) {            for (SmsMessage smsMessage : Telephony.Sms.Intents.getMessagesFromIntent(intent)) {                String messageBody = smsMessage.getMessageBody();            }        }    }}

Note:
The value must be an integer, such as "100". Higher numbers have a higher priority. The default value is 0. The value must be greater than -1000 and less than 1000.

Here's a link.


@Mike M. and I found an issue with the accepted answer (see our comments):

Basically, there is no point in going through the for loop if we are not concatenating the multipart message each time:

for (int i = 0; i < msgs.length; i++) {    msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);    msg_from = msgs[i].getOriginatingAddress();    String msgBody = msgs[i].getMessageBody();}

Notice that we just set msgBody to the string value of the respective part of the message no matter what index we are on, which makes the entire point of looping through the different parts of the SMS message useless, since it will just be set to the very last index value. Instead we should use +=, or as Mike noted, StringBuilder:

All in all, here is what my SMS receiving code looks like:

if (myBundle != null) {    Object[] pdus = (Object[]) myBundle.get("pdus"); // pdus is key for SMS in bundle    //Object [] pdus now contains array of bytes    messages = new SmsMessage[pdus.length];    for (int i = 0; i < messages.length; i++) {         messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]); //Returns one message, in array because multipart message due to sms max char         Message += messages[i].getMessageBody(); // Using +=, because need to add multipart from before also    }    contactNumber = messages[0].getOriginatingAddress(); //This could also be inside the loop, but there is no need}

Just putting this answer out there in case anyone else has the same confusion.