android - 对 Kitkat 和旧版本使用 SMS BroadcastReceiver

标签 android broadcastreceiver

我正在开发一个应用程序,它需要接收短信并且不允许任何其他应用程序接收短信。

应用程序必须在 Kitkat 和旧版本上都能正常运行。(我将我的应用程序设为 kitkat 中的默认短信应用程序)

这是我在 manifast 文件中尝试过的(不是全部):

    <receiver android:name=".SmsReceiver"
            android:permission="android.permission.BROADCAST_SMS">
        <intent-filter android:priority="2147483647" >
            <action android:name="android.provider.Telephony.SMS_DELIVER" />
        </intent-filter>
    </receiver>



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

第一个接收器是 kitkat 让我的应用程序成为默认的短信应用程序(当我删除这部分 kitkat 不要让我的应用程序成为默认的短信应用程序),第二个是旧版本

在 kitkat 上,问题是我所有的代码都运行了两次(因为我有两个接收者)

在旧版本上,我的应用程序运行了一次 onReceive 方法,但我从 Go SMS Pro 收到了新消息通知,但我只需要我的应用程序接收短信

这是我的 SmsReceiver 类:

public class SmsReceiver extends BroadcastReceiver 
{

    @Override
    public void onReceive(Context context, Intent intent) 
    {
        Bundle bundle = intent.getExtras();
        if (bundle != null) 
        {
            Object[] pdus = (Object[]) bundle.get("pdus");
            if (pdus.length == 0) 
            {
                return;
            }
            SmsMessage[] messages = new SmsMessage[pdus.length];
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < pdus.length; i++) 
            {
                messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                sb.append(messages[i].getMessageBody());
            }
            String sender = messages[0].getOriginatingAddress();
            String message = sb.toString();

            abortBroadcast();// prevent any other broadcast receivers from receiving broadcast

            // things I need to do on SMS

        }
    }// on Rec

}

最佳答案

为了同时支持旧版和新版 Android 的 SMS 处理,我建议使用两种不同的 BroadcastReceiver 类:一种用于新的 SMS_DELIVER_ACTION,另一种注册用于原始的 SMS_RECEIVED 操作,应该在 KitKat(API 级别 19)及更高版本上禁用它,这样您就不会收到两次相同的消息。每个 Receiver 都可以简单地将检索到的消息传递给一个公共(public)处理组件——例如,一个后台 Service——这样你就不会重复代码。

我们可以使用资源 bool 影响版本启用/禁用,默认情况下为 true,但在以 KitKat 开头的版本上为 false。例如:

res/values/booleans.xml:

<resources>
    <bool name="isPreKitKat">true</bool>
</resources>

res/values-v19/booleans.xml:

<resources>
    <bool name="isPreKitKat">false</bool>
</resources>
<receiver
    android:name=".SmsReceiver"
    android:permission="android.permission.BROADCAST_SMS">
    <intent-filter>
        <action android:name="android.provider.Telephony.SMS_DELIVER" />
    </intent-filter>
</receiver>

<receiver
    android:name=".OldSmsReceiver"
    android:enabled="@bool/isPreKitKat"
    android:permission="android.permission.BROADCAST_SMS">
    <intent-filter>
        <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
</receiver>

SMS_DELIVER_ACTION 在 KitKat 之前的版本中不存在,因此 Receiver 永远不应该在这些版本上运行,尽管您可能希望类似地启用/禁用 SmsReceiver 适本地,如果只是出于安全原因。


在较新的版本中,您将无法中止 SMS_RECEIVED_ACTION 广播,因为从 KitKat 开始完全不允许这样做。 ( Source )

Note that—beginning with Android 4.4—any attempt by your app to abort the SMS_RECEIVED_ACTION broadcast will be ignored so all apps interested have the chance to receive it.

但是,如果其他 SMS/消息传递应用按照推荐的方式运行,他们喜欢您无论如何都不应再收听 SMS_RECEIVED_ACTION 广播。如果它们不是默认值,它们将不会获得 SMS_DELIVER_ACTION

因此,除了这些应用程序之外,任何其他能够收听 SMS 的应用程序都希望只在必要时才这样做,并且只用于有效目的,因为在 KitKat 及更高版本上您无法真正采取任何措施来阻止它。


至于您在 KitKat 之前的版本上遇到的 GO SMS Pro 问题,您可能无能为力。在其他来源中,this post thread建议您可以通过确保在 GO SMS Pro 之前安装您的应用程序来解决该问题。但是,您可以从评论中看出这不是一个有保障的解决方案。您可能会建议您的用户关闭 GO SMS Pro 的“禁用其他消息通知”选项,这样您的应用至少可以接收相关的广播,即使它不能中止它们。请注意,环聊经常会导致同样的问题。

关于android - 对 Kitkat 和旧版本使用 SMS BroadcastReceiver,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24959294/

相关文章:

android - PopUp Activity从 "recent apps"开始时再次启动

main.xml 中的 Android 自定义 xml 标记

android recyclerview 不一致检测到无效的 recycler viewholder 位置

android - OpenGL - 为什么 normalize() 不是幂等的?

android - 使用 AlarmManager 广播以调用 Activity

java - 以编程方式删除短信不起作用

android - 为我公司的不同客户使用一个 keystore ?

android:设置单个角时形状角不起作用

android - 广播怎么可能是 "malicious"?

android - 捕捉短信发送和传递事件