Oreo +中的SMS广播接收器 [英] SMS Broadcast Receiver in Oreo+
问题描述
我正在尝试拦截传递到我的设备的SMS消息。我写了一个应用程序大约一年前就这样做了,但我发现它不再捕获消息(即使代码未更改)。
I am trying to intercept SMS messages delivered to my device. I wrote an app to do that a year or so ago, and I find it is no longer catching messages (even though code is unchanged).
我不相信它与许可相关。我尝试在SDK 23(需要运行时权限)和SDK 22(没有运行时权限)下进行编译。 (对于23岁,我验证了已成功授予RECEIVE_SMS权限。)
I don't believe it is permission-related. I tried compiling under SDK 23 (requiring runtime permissions) and SDK 22 (no runtime permissions). (In the case of 23, I verified that permission RECEIVE_SMS is successfully granted).
关于此问题的大多数问题/答案都已经很老了。恕我直言,答案似乎并不明智,例如添加BROADCAST_SMS权限,调用本机代码等。
Most questions/answers about this issue are quite old. IMHO The answers didn't seem enlightened, e.g. adding BROADCAST_SMS permission, invoking native code, etc.
我的方法是实现广播接收器。以下代码除外。
My approach was to implement a broadcast receiver. Code excepts below.
广播接收器
// 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
BUILD.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的Samsung S7上进行了测试。我通过从另一部手机发送短信来对此进行了测试。这些被正确接收,但从未触发SmsRecv()。
Tested on Samsung S7 running Oreo V8.0.0. I tested this by sending text messages from another phone. These were received correctly but never triggered SmsRecv().
在我的阅读中,我遇到了这样的概念,即 now SMS广播接收器将不再除非它是设备上的默认SMS应用程序,否则它就可以工作(是吗?)。
In my reading, I encountered the notion that now an SMS broadcast receiver will no longer work unless it is the default SMS app on the device (huh?).
任何建议都值得赞赏。
推荐答案
我终于弄清楚出了什么问题。显然,Android版本Oreo +不再提供隐式广播*(即,清单文件< receiver>中指定的广播)。现在,您必须在代码中显式注册接收者(即,使用 registerReceiver())。
I finally figured out what was wrong. Apparently, Android version Oreo+ does not deliver implicit broadcasts any more* (i.e., those specified in the manifest file <receiver>). You now must explicitly register your receiver (i.e., with registerReceiver()) in your code.
(*注:Mike M正确指出,根据Android文档,已将接收的SMS广播排除在此限制之外,但实际上对我而言并非如此)。
(*Note: Mike M correctly pointed out that received SMS broadcasts are excluded from this restriction according to Android doc, but nonetheless this was not so for me in practice).
所以我要做的是:
- 完全删除< ; receiver>从清单。
-
在我的活动onCreate()中创建接收者实例和intentFilter;
- Completely Remove <receiver> from manifest.
Create an instance of my receiver and an intentFilter in my activities onCreate();
MyReceiver = new SmsRecv();
MyFilter = new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION );
在活动的onResume()中注册接收者。
Register the receiver in my Activity's onResume().
i = registerReceiver( MyReceiver, MyFilter);
在活动的onPause()中取消注册接收者。 (这是防止泄漏所必需的)。
Unregister the receiver in my Activity's onPause(). (This is neccessary to prevent leaks).
unregisterReceiver( MyReceiver );
通过更改,该应用程序可以完美运行。
With the changes, the app worked perfectly.
这篇关于Oreo +中的SMS广播接收器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!