我正在开发一个应用程序,它需要接收短信并且不允许任何其他应用程序接收短信。
应用程序必须在 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/