首页 > 解决方案 > Oreo+ 中的 SMS 广播接收器

问题描述

我正在尝试拦截发送到我的设备的 SMS 消息。大约一年前我写了一个应用程序来做到这一点,我发现它不再捕获消息(即使代码没有改变)。

我不相信它与许可有关。我尝试在 SDK 23(需要运行时权限)和 SDK 22(无运行时权限)下编译。(在23的情况下,我验证成功授予RECEIVE_SMS权限)。

关于这个问题的大多数问题/答案都很老了。恕我直言,答案似乎并不开明,例如添加 BROADCAST_SMS 权限、调用本机代码等。

我的方法是实现一个广播接收器。下面的代码除外。

广播接收器

//  SmsRecv.java - SMS Receiver    

package com.ramrod.SmsReceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class SmsRecv extends BroadcastReceiver {

    //@ Handler for received sms messages
    @Override
    public void onReceive(
        Context ctx,
        Intent intent)
    {    
        // NEVER REACHED!
        Main.toast( "SMS RECEIVED." );
        // PROCESS MESSAGE HERE...    
    }

显现

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.ramrod.SmsReceiver"
      android:versionCode="100"
      android:versionName="1.00">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />

    <application
      android:icon="@drawable/icon"
      android:label="SmsReceiver"
      android:theme="@android:style/Theme"
    >
      <activity android:name=".Main"
            android:label="SmsReceiver"
          >
          <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
      </activity>

      <receiver android:name=".SmsRecv"
          android:exported="true"
          android:enabled="true"
          >
          <intent-filter android:priority="999999" >
              <action android:name="android.provider.Telephony.SMS_RECEIVED" />
          </intent-filter>
      </receiver>

    </application>
</manifest>

构建.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "27.0.3"

    defaultConfig {
        applicationId "com.ramrod.SmsReceiver"
        minSdkVersion 23
        targetSdkVersion 23
    }
    ...

在运行 Oreo V8.0.0 的三星 S7 上测试。我通过从另一部手机发送短信对此进行了测试。这些被正确接收但从未触发 SmsRecv()。

在我的阅读中,我遇到了一个概念,即现在SMS 广播接收器将不再工作,除非它是设备上的默认 SMS 应用程序(嗯?)。

任何建议都非常感谢。

标签: androidbroadcastreceiversms

解决方案


我终于弄清楚出了什么问题。显然,Android 版本 Oreo+ 不再提供隐式广播*(即清单文件 <receiver> 中指定的那些)。您现在必须在代码中显式注册您的接收器(即使用registerReceiver())。

(*注意:Mike M 正确地指出,根据 Android 文档,接收到的 SMS 广播不受此限制,但实际上对我来说并非如此)。

所以我为完成这项工作所做的是:

  • 从清单中完全删除 <receiver>。
  • 在我的活动 onCreate() 中创建我的接收器和一个 intentFilter 的实例;

        MyReceiver = new SmsRecv();
        MyFilter   = new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION );  
    
  • 在我的 Activity 的 onResume() 中注册接收器。

        i = registerReceiver( MyReceiver, MyFilter);  
    
  • 在我的 Activity 的 onPause() 中取消注册接收器。(这是防止泄漏所必需的)。

        unregisterReceiver( MyReceiver );
    

通过这些更改,该应用程序运行良好。


推荐阅读