android - 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 应用程序(嗯?)。
任何建议都非常感谢。
解决方案
我终于弄清楚出了什么问题。显然,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 );
通过这些更改,该应用程序运行良好。
推荐阅读
- javascript - 无法使用 npm 安装 create-react-app
- r - 对数据表列的子集执行功能并复合分配
- sql - 如何对每个项目的 Quantity 列的运行总计求和,并仅获取库存在总数中为零的那一天
- sql - 频繁更新表上频繁查询视图的锁定逻辑 - 请告知?
- tensorflow - “点击”现有 Keras 模型中的特定层并分支到新输出?
- c++ - 在 C++ 中,如何将当前函数的所有参数传递给另一个函数?
- azure-active-directory - az ad app permission add - 权限不足,无法完成操作
- r - 如何取 + 或 - SD 的平均值
- twitter-bootstrap - 如何在引导程序中设置小列?
- excel - Excel VBA - 工作表/范围引用无法正常工作