oldsport76
oldsport76

Reputation: 407

Oreo BroadcastReceiver SMS Received not working

An app I'm working on allows the user to allow the app to read the contents of a confirmation SMS to input the verification code on its own. For all devices using an OS earlier than Oreo (API 26), the implementation of the BroadcastReceiver works correctly and allows a proper reception of the SMS. By this implementation I mean placing the receiver object in the AndroidManifest.

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

However, starting with Oreo, one must explicitly register BroadcastReceivers to the appropriate context. I have implemented this as follows:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            smsReceiver = new SmsReceiver();
            IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
            intentFilter.addAction(Telephony.Sms.Intents.DATA_SMS_RECEIVED_ACTION);
            this.registerReceiver(smsReceiver, intentFilter);
        }

This block of code is executed upon receiving permission for Manifest.permission.READ_SMS. The SmsReceiver class extends BroadcastReceiver and overrides its onReceive() method.

Here, I have several questions:

  1. I have tested this implementation and have set breakpoints on my onReceive() method in my SmsReceiver. When an SMS arrives, the app never enters the onReceive() method. Why can this be?

  2. I instantiated my IntentFilter in the way it is described on the Android Developer website, i.e. with the ConnectivityManager.CONNECTIVITY_ACTION action. I know the SmsReceiver works, because the break point in onReceive() is always hit upon registration of the receiver. However, the action is merely the CONNECTIVITY_ACTION. The SMS_RECEIVED_ACTION is never caught by the receiver. Is it absolutely necessary to instantiate the IntentFilter with this action or can one leave this out?

  3. Is there something else I'm missing that could lead to my receiver not catching the arriving SMS?

Upvotes: 15

Views: 9878

Answers (6)

MGLabs
MGLabs

Reputation: 91

For Oreo and higher, specifically add Manifest.permission.RECEIVE_SMS in your requestPermission statement, no matter of other sms-related permissions you may already be asking for. List the same permissions in the manifest but not the receiver which will be registered dinamically as you did (placing a receiver both statically and programmatically defeats the purpose).

requestPermissions(new String[]{Manifest.permission.READ_SMS, Manifest.permission.RECEIVE_SMS},
                    Constants.SMS_REQUEST_PERMISSION_CODE);

The reason for this is because, quoting from the documentation, prior to Android 8.0 (API level 26), if an app requested a permission at runtime and the permission was granted, the system also incorrectly granted the app the rest of the permissions that belonged to the same permission group, and that were registered in the manifest.

For apps targeting Android 8.0, this behavior has been corrected. The app is granted only the permissions it has explicitly requested. However, once the user grants a permission to the app, all subsequent requests for permissions in that permission group are automatically granted.

The last bit is the reason why you need to make sure you have revoked SMS permissions in your emulator/device before testing again.

Upvotes: 1

Santanu Sur
Santanu Sur

Reputation: 11477

Just add

android:permission="android.permission.BROADCAST_SMS"

to the receiver tag in Manifest .

So ideal manifest registered broadcast receiver :-

<receiver android:name=".receivers.SMSBroadCastReceiver"
        android:exported="true"
        android:permission="android.permission.BROADCAST_SMS">
        <intent-filter
            android:priority="2147483647">
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
        </intent-filter>
    </receiver>

UPDATE :-

Now SMS RETRIEVER api is recommended to read SMS( else play store won't allow to release apk in some cases). So check out the link.

Upvotes: 2

Pranav Wani
Pranav Wani

Reputation: 53

Turned SMS permission off and on simultaneously. After some seconds it worked.

Upvotes: 4

shashank chandak
shashank chandak

Reputation: 544

The answer given by @rohit sharma worked for me initially, but then i also tested my app on various devices like oneplus,mi,oppo and vivo and found that

1.On vivo,oppo and mi (having miui) devices there is something called as autostart which is disabled by default so the SMS_RECIEVED_ACTION doesnt work (here by work i mean launching the app or running any service in background on sms_recieved) even being whitelisted from the list of recent implicit ban given .

2.On oneplus devices there is battery optimization feature and if your app is listed for battery optimization (which is yes by default) then the SMS_RECIEVED_ACTION will work only when your app is in foreground or background ,if your app is killed or after a phone reboot the broadcast receiver wont work. For the SMS_RECIEVD_ACTION to work you will have to remove the app from the battery optimizatons.For more information on this you can follow this thread here

Upvotes: 5

Prantik Mondal
Prantik Mondal

Reputation: 493

For me this Works:

private int MY_PERMISSIONS_REQUEST_SMS_RECEIVE = 10;
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.RECEIVE_SMS},
        MY_PERMISSIONS_REQUEST_SMS_RECEIVE);

Mention that above code in your main activity after permission granted. After that override this :

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] 
            permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            if (requestCode == MY_PERMISSIONS_REQUEST_SMS_RECEIVE) {
                Log.d("TAG", "My permission request sms received successfully");
            }
 }

thats all. So now no need to Turned SMS permission off and on after some seconds manually.

Upvotes: 5

Rohit Sharma
Rohit Sharma

Reputation: 1414

Previously I was requesting for -Manifest.permission.READ_SMS which didn't worked then I changed the permissions to - Manifest.permission.RECEIVE_SMS then it started working in oreo and I also specified the receiver in manifest I don't know whether that helped or not but this made the day for me

   public static void requestPermissionForReadSMS(Fragment fragment) {
    //        if (fragment.shouldShowRequestPermissionRationale(Manifest.permission.READ_SMS)) {
    //            Helpers.showRequestPermissionAlertDialog(fragment, fragment.getString(R.string.read_sms_permission), fragment.getString(R.string.permission_request));

    //        } else {
            fragment.requestPermissions(new String[]{Manifest.permission.RECEIVE_SMS},
                    Constants.READ_SMS_PERMISSION);
   // }

        }

Upvotes: 20

Related Questions