Oreo BroadcastReceiver短信收到不起作用

old*_*t76 9 android broadcastreceiver android-broadcastreceiver android-8.0-oreo

我正在处理的应用程序允许用户允许应用程序读取确认SMS的内容以自行输入验证码.对于使用早于Oreo(API 26)的OS的所有设备,BroadcastReceiver的实现正常工作并允许正确接收SMS.通过这个实现,我的意思是将接收器对象放在AndroidManifest中.

<receiver android:name=".SmsReceiver">
        <intent-filter>
            <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
        </intent-filter>
</receiver>
Run Code Online (Sandbox Code Playgroud)

但是,从Oreo开始,必须将BroadcastReceivers显式注册到适当的上下文.我已经实现了如下:

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);
        }
Run Code Online (Sandbox Code Playgroud)

在接收Manifest.permission.READ_SMS的许可时执行此代码块.SmsReceiver类扩展了BroadcastReceiver并覆盖了它的onReceive()方法.

在这里,我有几个问题:

  1. 我测试了这个实现,并在我的SmsReceiver中的onReceive()方法上设置了断点.当SMS到达时,应用程序永远不会进入onReceive()方法.为什么会这样?

  2. 我按照Android Developer网站上描述的方式实例化我的IntentFilter,即使用ConnectivityManager.CONNECTIVITY_ACTION操作.我知道SmsReceiver有效,因为onReceive()中的断点总是在接收器注册时被击中.但是,该操作仅仅是CONNECTIVITY_ACTION.SMS_RECEIVED_ACTION永远不会被接收器捕获.是否绝对有必要使用此操作实例化IntentFilter,还是可以将其删除?

  3. 还有其他我想念的东西会导致我的接收器没有收到到达的短信吗?

Roh*_*rma 14

以前我要求-Manifest.permission.READ_SMS没有用,然后我将权限更改为--Manifest.permission.RECEIVE_SMS然后它开始在oreo工作,我也在清单中指定了接收器我不知道是否有帮助不是,但这对我来说是一天

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

        }
Run Code Online (Sandbox Code Playgroud)


Pra*_*dal 5

对我来说这个作品:

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

在获得许可后,在主要活动中提及上述代码.在那之后覆盖这个:

@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");
            }
 }
Run Code Online (Sandbox Code Playgroud)

就这样.因此,现在不需要在手动几秒钟后关闭和打开SMS权限.


sha*_*dak 5

@rohit sharma给出的答案最初对我有用,但后来我还在 oneplus、mi、oppo 和 vivo 等各种设备上测试了我的应用程序,发现

1.在vivo、oppo和mi(有miui)设备上,有一种叫做自动启动的东西,默认情况下是禁用的,所以SMS_RECIEVED_ACTION不起作用(这里的工作是指在sms_recieved上启动应用程序或在后台运行任何服务)甚至被列入白名单从最近给出的隐含禁令名单中。

2.在oneplus设备上有电池优化功能,如果您的应用被列为进行电池优化(默认情况下为是),那么SMS_RECIEVED_ACTION仅在您的应用处于前台或后台时,如果您的应用被杀死或在手机之后起作用重新启动广播接收器将无法工作。要使 SMS_RECIEVD_ACTION 工作,您必须从电池优化中删除该应用程序。有关这方面的更多信息,您可以在此处关注此线程


小智 4

同时关闭和打开短信权限。几秒钟后,它起作用了。

  • 为什么你要把别人的文字复制到你的答案中? (4认同)