我的运营商(我住在委内瑞拉)经常给我发短信,有些是垃圾,有些是我关心的,我真的不想从市场上下载一个短信应用,因为我做的事情非常具体和简单。
基本思想:我有一个捕获短信接收意图的BroadcastReceiver,为了对操作系统友好,我在这里不做任何处理(我希望能够构建尽可能复杂的规则,并且不存在长时间运行的问题,可能使用db或其他异步任务,这些任务在BroadcastReceiver中无法完成),instead i将同一个包发送到处理sms的IntentService
一般来说,这很好,如果我不想让系统注意到我收到了一条短信,我可以停止广播,IntentService可以完美地处理短信。
问题:
如何处理服务中的短消息,然后决定是否希望系统注意到我收到了短消息?
我强烈希望避免在BroadcastReceiver中进行处理。(This has important repercussions to what you can do in an onReceive(Context, Intent) implementation: anything that requires asynchronous operation is not available, because you will need to return from the function to handle the asynchronous operation, but at that point the BroadcastReceiver is no longer active and thus the system is free to kill its process before the asynchronous operation completes.
我已经考虑过处理短信,如果不符合我的标准,我可以重新发布短信接收广播与一个额外的包,以检查它是否已经过验证。但我不能让它工作。
代码:

public class SmsReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        if(!intent.getExtras().getBoolean("previouslyChecked",false)){
            this.abortBroadcast();
            Intent serviceIntent = new Intent(context, SmsRecievedServices.class);
            serviceIntent.putExtras(intent);
            context.startService(serviceIntent);
        }
    }
}

public class SmsRecievedServices extends IntentService {

    public SmsRecievedServices() {
        super("SmsRecievedServices");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Bundle bundle = intent.getExtras();
        if(!smsMatchesCriteria(bundle)){
            Intent intent2 = new Intent("android.provider.Telephony.SMS_RECEIVED");
            bundle.putBoolean("previouslyChecked",true);
            intent2.putExtras(bundle);
            sendOrderedBroadcast(intent2,"android.permission.RECEIVE_SMS");
        }
    }
}

广播接收者得到了意图,并且没有取消广播,但是系统没有接收到短信。有什么想法吗?
编辑(回应布伦德尔的评论):
我想也许我再加一个会毁了它,所以我试着做了如下的事情:
public class SmsReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        int randomNum = (int)Math.ceil(Math.random()*100);
        if(randomNum > 20){
            this.abortBroadcast();
            Intent serviceIntent = new Intent(context, SmsRecievedServices.class);
            serviceIntent.putExtras(intent);
            context.startService(serviceIntent);
        }
    }
}

public class SmsRecievedServices extends IntentService {

    public SmsRecievedServices() {
        super("SmsRecievedServices");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.i("SMSManager","Forwarding intent");
    Bundle bundle = intent.getExtras();
    Intent intent2 = new Intent("android.provider.Telephony.SMS_RECEIVED");
    intent2.putExtras(bundle);
    sendOrderedBroadcast(intent2, "android.permission.RECEIVE_SMS");
        }
}

logcat输出为:
02-10 22:06:24.632: I/SMSManager(424): RandomNumber: 74
02-10 22:06:24.673: I/SMSManager(424): Forwarding intent
02-10 22:06:24.683: I/SMSManager(424): RandomNumber: 64
02-10 22:06:24.803: I/SMSManager(424): Forwarding intent
02-10 22:06:24.824: I/SMSManager(424): RandomNumber: 28
02-10 22:06:24.832: I/SMSManager(424): Forwarding intent
02-10 22:06:24.854: I/SMSManager(424): RandomNumber: 14

如您所见,该消息被系统隐藏了三次,第四次im没有调用abort broadcast,因为随机数小于20。无论是在收件箱还是通知栏中,操作系统都不会显示新的短信。

最佳答案

消息应用程序中android.provider.Telephony.SMS_RECEIVED意图的接收者受到保护,并且将只处理平台发送的意图(它将丢弃欺骗意图)。
避免在广播接收器中进行处理的唯一方法是将android.permission.WRITE_SMS权限添加到您的应用程序中,并亲自将sms写入数据库。
由于sms/mms提供商不是一个发布的api,它可能会因版本和供应商的不同而有所不同,因此与它集成可能会很糟糕。
如果您想取消消息,通常应该在接收器中处理消息。任何耗时的操作(例如列出大量联系信息)都应该通过应用程序中的缓存机制来解决。

07-24 09:47
查看更多