Oreo BroadcastReceiver SMS Received not working
Asked Answered
Y

6

15

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?

Yokefellow answered 14/2, 2018 at 14:28 Comment(10)
SMS_RECEIVED is on the broadcast whitelist, so your original approach with the <intent-filter> should still work.Hazeghi
I also thought that, but it somehow doesn't, even though the implementation works for all previous OSes :( . Could there be something about receiving SMSes on Oreo in general that breaks this?Yokefellow
"it somehow doesn't, even though the implementation works for all previous OSes" -- that's strange. I do not see any issues filed about it not working, and I would have thought that somebody would have complained by now if that was broken. What device(s) are you testing on?Hazeghi
So far I've used it HMD Global (Nokia 8) and a Nexus, both Oreo. I also know of a OnePlus 3, also with Oreo, that can't catch the sms in the onReceive. Basically everything API 26 and over doesn't catch it, everything below does.Yokefellow
I just tried it on a Pixel 2, running Android 8.1, and I had no problem with receiving the SMS_RECEIVED broadcast, when registered in the manifest. I log a message to LogCat, and the message shows up.Hazeghi
That's good and bad to hear ;). Do you do it the same way as me? Could you paste some code?Yokefellow
I ran this seriously old app from one of my books, just updating the minSdkVersion to 4 to eliminate some Lint errors (did I mention that this app is old?).Hazeghi
hi, @Hazeghi can you please look my question here... I also tried this same way.but not working for me. #49593650Cavill
Same is the case with Samsung S8. This is what I did to make it work only ONCE: Turned SMS permission off and on after some seconds manually and it worked. Did any one of you solve this problem?Clarineclarinet
@WaqasAhmedAnsari Hey, thank you man! Turning off and on again in permission settings helped me too. (Nexus 5X, Android 8.1) I did nothing else.Jillion
C
20

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);
   // }

        }
Confectionary answered 28/5, 2018 at 1:20 Comment(1)
I've been struggling for hours and was using the same READ_SMS permission. You saved my day.Vano
H
5

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.

Hirschfeld answered 24/8, 2018 at 13:47 Comment(0)
G
5

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

Gentianella answered 25/8, 2018 at 9:51 Comment(2)
The auto start is a big problem , There isn't anything we can do about it until and unless the user enables, it goes for the push notifications as well bro.Confectionary
In Android 9, there is two places that I have turned off the battery optimization for my app that works: In setting---> Battery optimization and Optimize battery usage. The Android 9 changes are very strange and Google should revise them seriously.Rakeoff
N
4

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

Nopar answered 27/5, 2018 at 16:42 Comment(2)
Why do you copy other people's text into your answer?Cardinal
Sorry, my intention is not to copy another answer after get the solution i just add the solution for this problem. I'm sorry for that. I forgot to mention person who will solve this issue.Nopar
K
2

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.

Kuntz answered 24/6, 2018 at 11:59 Comment(1)
You need to give the permission <uses-permission android:name="android.permission.RECEIVE_SMS"/> in <manifest>...</manifest> section AND add the android:permission="android.permission.BROADCAST_SMS" permission as <receiver ...> attribute - Tested with my LG G6 on Android 8Insightful
K
1

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.

Kan answered 7/5, 2020 at 18:4 Comment(1)
In Vivo mobile , manually check autostart permission So sms receive work when app closed or killed. (test on android 9)Cuprite

© 2022 - 2024 — McMap. All rights reserved.