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 );
经过更改,该应用程序运行完美。
我正在尝试拦截发送到我设备的 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+ 不再提供 隐式 广播*(即清单文件
(*注意:根据 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 );
经过更改,该应用程序运行完美。