停止短信移动到收件箱

时间:2014-02-17 07:48:47

标签: android sms broadcastreceiver android-4.4-kitkat

在Android 4.4之前,我可以通过设置优先级来阻止邮件进入收件箱

    <receiver android:name="com.serviceschedular.helperClasses.SmsReceiver" >
        <intent-filter android:priority="1000">
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />          
        </intent-filter>
    </receiver>

然后在onRecieve()消息中使用abortBroadcast()。但是在Android 4.4中我们需要定义SMS_DELIVER_ACTION以使我们的消息传递应用程序成为默认值:

Getting Your SMS Apps Ready for KitKat

通过这样做我可以先收到消息,但他们不会移动到任何其他消息传递应用程序,但如果它不符合我的标准,我还需要将它们发送到消息传递应用程序。那么有什么方法可以实现这个功能吗?

1 个答案:

答案 0 :(得分:6)

当Android系统收到SMS时,它会播放一个有效的广播Intent,其动作为“android.provider.Telephony.SMS_RECEIVED”。所有已注册的接收器(包括系统默认SMS应用程序)都按照其intent-filter中设置的优先级顺序接收此Intent。未指定具有相同优先级的广播接收者的顺序。任何BroadcastReceiver都可以阻止任何其他已注册的广播接收器使用abortBroadcast()接收广播。

所以,你需要的就是这样的广播接收器:

public class SmsFilter extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
            Bundle extras = intent.getExtras();
            if (extras != null) {
                Object[] pdus = (Object[])extras.get("pdus");

                if (pdus.length < 1) return; // Invalid SMS. Not sure that it's possible.

                StringBuilder sb = new StringBuilder();
                String sender = null;
                for (int i = 0; i < pdus.length; i++) {
                    SmsMessage message = SmsMessage.createFromPdu((byte[]) pdus[i]);
                    if (sender == null) sender = message.getOriginatingAddress();
                    String text = message.getMessageBody();
                    if (text != null) sb.append(text);
                }
                if (sender != null && sender.equals("999999999")) {
                    // Process our sms...
                    abortBroadcast();
                }
                return;
            }
        }

        // ...
    }
}

看起来系统默认的SMS处理应用程序使用优先级0,因此您可以尝试使用1作为应用程序。将这些行添加到

的AndroidManifest.xml:

<receiver android:name=".SmsFilter">
    <intent-filter android:priority="1">
        <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
</receiver>

不要忘记必要的权限:

<uses-permission android:name="android.permission.RECEIVE_SMS"/>

顺便说一下,您可以使用以下代码找到所有已注册的接收器及其优先级:

Intent smsRecvIntent = new Intent("android.provider.Telephony.SMS_RECEIVED");
List<ResolveInfo> infos = context.getPackageManager().queryBroadcastReceivers(smsRecvIntent, 0);
for (ResolveInfo info : infos) {
    System.out.println("Receiver: " + info.activityInfo.name + ", priority=" + info.priority);
      }

=============================================== ==================

用于防止短信进入Android Kitkat的收件箱

KitKat中引入了一项更改,它一次只允许一个应用程序(默认的SMS应用程序)对SMS DB具有写入权限并能够使用它。

您有2种方法可以解决您的问题:

  • 关注如何在您需要执行更改期间请求用户将默认SMS应用程序切换到您的应用程序的Google建议(一旦您完成此操作,允许用户切换回原始默认SMS应用程序)。
  • 找一个临时的hacky方式去做你需要做的事。作为提示,有一个隐藏的API:   您可能会利用AppOpsManager来为您的应用程序提供写入权限(OP_WRITE_SMS),请访问此XDA页面以了解有关它的更多信息:

How to write to SMS Content Provider in Android KitKat WITHOUT being default SMS app

如果您有任何疑问,请回复...

<强>更新

从Android 4.4 Kitkat开始,如果不是默认的SMS应用程序,则无法执行任何类型的SMS相关操作。还原和备份应用程序也无法执行此操作。他们中的大多数已经更新了他们的应用程序以支持此功能,现在要求用户选择它们作为默认的SMS应用程序。

Android KitKat更新已停止支持与其他应用编写短信。你只能听,但不能写。如果您想发送短信,您必须将其发送到默认的短信意图,并且用户必须在发送短信之前批准并点击发送。

您的参考:SMS provider