Receiving SMS on Android App
Asked Answered
B

3

13

i followed a tutorial to receive SMS on my application and read it to pass the SMSbody to Toast. that is the Receiver class.

public class SmsReciever extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent){
        Bundle bundle= intent.getExtras();
        SmsMessage[] msgs= null;
        String str="";
        if(bundle != null ){
            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]);
                str+= msgs[i].getMessageBody();

            }
             Toast.makeText(context, str, Toast.LENGTH_LONG).show();
        }
        }

    }

the manifest file

    <receiver android:name="com.msoft.masrooq.SmsReciever">
    <intent-filter>
    <action android:name="android.provider.telephony.SMS_RECIEVED"></action>
    </intent-filter>
    </receiver>
        <uses-permission android:name="android.permission.RECEIVE_SMS"/>
            <uses-permission android:name="android.permission.READ_SMS" />

the app starts fine but it doesn't response to receiving sms it doesn't do anything.

Bautram answered 11/7, 2012 at 14:50 Comment(1)
I had similar problem. I did not receive any messages, although i thought i have implemented everything required for it to work. I have no idea if this is the fix for some problems, but i declared receiver above main activity tags in manifest and from then on it worked. Hope that this will fix someones problemsVulcanology
B
33

Here is my implementation of receiving sms messages. Sms message may be broken into many, notice how it is treated. Also check the android:priority attribute.

public class SmsReceiver extends BroadcastReceiver {

    private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(SMS_RECEIVED)) {
            Bundle bundle = intent.getExtras();
            if (bundle != null) {
                // get sms objects
                Object[] pdus = (Object[]) bundle.get("pdus");
                if (pdus.length == 0) {
                    return;
                }
                // large message might be broken into many
                SmsMessage[] messages = new SmsMessage[pdus.length];
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < pdus.length; i++) {
                    messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                    sb.append(messages[i].getMessageBody());
                }
                String sender = messages[0].getOriginatingAddress();
                String message = sb.toString();
                Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
                // prevent any other broadcast receivers from receiving broadcast
                // abortBroadcast();
            }
        }
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.smsreceiver"
    android:versionCode="1"
    android:versionName="1.0">
    <uses-sdk android:minSdkVersion="4" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity
            android:name=".SmsLoggerActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name="com.example.smsreceiver.SmsReceiver" android:enabled="true">
            <intent-filter android:priority="2147483647">
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

Few notes: If you declare your receiver in xml than system can use your receiver regardless of your application was ever launched. Since Android 1.6 notifications about received sms messages are delivered as ordered broadcasts, you can use android:priority attribute of <intent-filter> to tell the system send the sms first to your application (you can also call abortBroadcast() so other applications won't receive the sms, e.g. the native sms app). Don't forget broadcast receiver has about 10 seconds for executing its operation, otherwise it can be prematurely terminated before finishing its job.

Bigler answered 11/7, 2012 at 15:48 Comment(3)
+1 Just a heads up, android.permission.SEND_SMS and android.permission.RECEIVE_SMS are different. And in your Main activity just create an object SmsReceiver().Scathing
How would one implement this for MMS?Pippo
@Bigler The Google administrators for the Google Play Store consider the RECEIVE_SMS permission (in the tutorial you mention) to be dangerous. As a result, an app that contains the permission will be rejected. Then the developer has to submit a form to Google Play administrators for approval. Other developers have mentioned the process is awful with feedback taking weeks and receiving outright rejections with either no explanations or generic feedback. Any ideas on how to avoid?Collectivism
B
2

Broadcasts are case-sensitive. Use android.provider.Telephony.SMS_RECEIVED not android.provider.telephony.SMS_RECEIVED.

Also, I also have a category set, but I'm not sure it's mandatory:

<intent-filter>
   <action android:name="android.provider.Telephony.SMS_RECEIVED" />
   <category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Baguio answered 11/7, 2012 at 15:39 Comment(1)
The Google administrators for the Google Play Store consider the RECEIVE_SMS permission (in the tutorial you mention) to be dangerous. As a result, an app that contains the permission will be rejected. Then the developer has to submit a form to Google Play administrators for approval. Other developers have mentioned the process is awful with feedback taking weeks and receiving outright rejections with either no explanations or generic feedback. Any ideas on how to avoid?Collectivism
P
2

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

 <application
 <uses-permission android:name="android.permission.RECEIVE_SMS" />
 <uses-permission android:name="android.permission.READ_SMS" />
 ...
  <receiver
        android:name=".SMSReceiver">
        <intent-filter android:priority="100">
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
        </intent-filter>
  </receiver>
 ...
</application>

And here Java code :

public class SMSReceiver extends BroadcastReceiver {
public static final String ACTION ="android.provider.Telephony.SMS_RECEIVED";
private static final String SMS_SENDER="123456789";

@Override
public void onReceive(Context context, Intent intent) {
        if (intent != null && intent.getAction() != null &&
                ACTION.compareToIgnoreCase(intent.getAction()) == 0) {
            Object[] pduArray = (Object[]) intent.getExtras().get("pdus");
            SmsMessage[] messages = new SmsMessage[pduArray.length];
            for (int i = 0; i < pduArray.length; i++) {
                messages[i] = SmsMessage.createFromPdu((byte[]) pduArray[i]);
            }
            // SMS Sender, example: 123456789
            String sms_from = messages[0].getDisplayOriginatingAddress(); 

            //Lets check if SMS sender is 123456789
            if (sms_from.equalsIgnoreCase(SMS_SENDER)) {
                StringBuilder bodyText = new StringBuilder();

                // If SMS has several parts, lets combine it :)
                for (int i = 0; i < messages.length; i++) {
                    bodyText.append(messages[i].getMessageBody());
                }
                //SMS Body
                String body = bodyText.toString();
                // Lets get SMS Code
                String code  = body.replaceAll("[^0-9]", ""); 
            }
      }
 }
Prosperity answered 30/7, 2018 at 4:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.