如何防止短信进入Android的收件箱?

时间:2012-02-07 12:05:55

标签: android

我正在开发一个商业短信应用程序。在此应用中,如果传入的消息来自特定号码,例如999999999,它应该转到应用程序的收件箱而不是默认的本机收件箱。所有其他消息都应该转到手机的本机收件箱。我该怎么做?

5 个答案:

答案 0 :(得分:30)

当Android系统收到短信时,它会广播ordered broadcast Intent行动"android.provider.Telephony.SMS_RECEIVED"。所有注册的接收方(包括系统默认的SMS应用程序)都会按照Intent中设置的priority的顺序收到此intent-filter。未指定具有相同优先级的广播接收者的顺序。任何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);
}

更新:作为FantasticJamieBurn said below,从Android 4.4开始,唯一可以截取短信的应用(如果愿意,可阻止)是默认的短信应用(由用户选择)。如果默认短信应用未阻止,则所有其他应用只能收听传入的短信。

另请参阅Android 4.4 API中的SMS Provider

答案 1 :(得分:12)

随着Android 4.4 KitKat(API级别19)的发布,已删除阻止SMS消息并阻止其传递到默认SMS应用程序的选项。非默认SMS应用程序可能会在收到SMS消息时观察到这些消息,但Android 4.4+将忽略任何中止广播的尝试。

如果您的现有应用依赖于中止短信广播,那么您可能需要考虑当用户升级到Android 4.4 +时此行为更改会产生的影响。

http://android-developers.blogspot.co.uk/2013/10/getting-your-sms-apps-ready-for-kitkat.html

答案 2 :(得分:2)

是的,它可以是

public void onReceive(Context context, Intent intent)
{
    Bundle bundle=intent.getExtras();
    Object[] messages=(Object[])bundle.get("pdus");
    SmsMessage[] sms=new SmsMessage[messages.length];

    Toast.makeText(context, "Hello", 1).show();

    for(int n=0;n<messages.length;n++){
        sms[n]=SmsMessage.createFromPdu((byte[]) messages[n]);
    }

    for(SmsMessage msg:sms){
        if(msg.getOriginatingAddress().endsWith(number))
        {
        SMS.updateMessageBox("\nFrom: "+msg.getOriginatingAddress()+"\n"+
                "Message: "+msg.getMessageBody()+"\n");
            /*((SMS) context).delete();*/
        abortBroadcast();
        }
    }
}

在app中收到后使用abortbroadcast()

答案 3 :(得分:1)

您是发送邮件的人吗?如果是这样,请考虑使用数据,因为它们不会显示在收件箱中。

检查this问题以获取有关如何使用它的更多信息

答案 4 :(得分:1)

检查发件人号码是否等于短信发送电话的手机号码。

替换“praetorian droid”先生的以下代码行

if (sender != null && sender.equals("999999999")) {

if (sender != null && sender.equals("YOUR SMS SENDING MOBILE NUMBER HERE")) {

您还可以为用户设置一个设置,以便在他想要更改短信时手动添加短信发送号码。