I am trying to create an application for monitoring incoming SMS messages, and launch a program via incoming SMS, also it should read the content from the SMS.
Workf
This is what i used!
public class SMSListener extends BroadcastReceiver {
// Get the object of SmsManager
final SmsManager sms = SmsManager.getDefault();
String mobile,body;
public void onReceive(Context context, Intent intent) {
// Retrieves a map of extended data from the intent.
final Bundle bundle = intent.getExtras();
try {
if (bundle != null) {
final Object[] pdusObj = (Object[]) bundle.get("pdus");
for (int i = 0; i < pdusObj.length; i++) {
SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
String phoneNumber = currentMessage.getDisplayOriginatingAddress();
String senderNum = phoneNumber;
String message = currentMessage.getDisplayMessageBody();
mobile=senderNum.replaceAll("\\s","");
body=message.replaceAll("\\s","+");
Log.i("SmsReceiver", "senderNum: "+ senderNum + "; message: " + body);
// Show Alert
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context,
"senderNum: "+ mobile+ ", message: " + message, duration);
toast.show();
} // end for loop
} // bundle is null
} catch (Exception e) {
Log.e("SmsReceiver", "Exception smsReceiver" +e);
}
}
}
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.