Oreo+ 中的短信广播接收器

SMS Broadcast Receiver in Oreo+

我正在尝试拦截发送到我设备的 SMS 消息。大约一年前我写了一个应用程序来执行此操作,但我发现它不再捕获消息(即使代码未更改)。

我认为这与权限无关。我尝试在 SDK 23(需要运行时权限)和 SDK 22(没有运行时权限)下编译。 (在23的情况下,我验证了权限RECEIVE_SMS被成功授予)。

关于这个问题的大多数 questions/answers 已经很老了。恕我直言答案似乎并不开明,例如添加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>

BUILD.GRADLE

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "27.0.3"

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

在三星 S7 运行 Oreo V8.0.0 上测试。我通过从另一个 phone 发送短信来测试这一点。这些已正确接收但从未触发 SmsRecv()。

在我的阅读中,我遇到了这样的想法,即现在 短信广播接收器将不再工作,除非它是设备上的默认短信应用程序(是吗?)。

非常感谢任何建议。

我终于知道哪里出了问题。显然,Android 版 Oreo+ 不再提供 隐式 广播*(即清单文件 中指定的广播)。您现在必须在您的代码中显式注册您的接收器(即使用 registerReceiver())。

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

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

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

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

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

        unregisterReceiver( MyReceiver );
    

经过更改,该应用程序运行完美。