更新有序BroadcastReceivers android之间的Intent extras

时间:2011-06-17 20:43:15

标签: android android-intent broadcastreceiver edit extras

我目前正在从系统获取SMS_Received广播,并尝试在其他广播接收者获取之前更改意图中的值(例如默认消息传递应用)

但是,无论我尝试更改意图的方式,广播侦听器都看不到更新的值。并且因为系统不允许您发送SMS_Received广播,所以我不能中止这个并重新发送一个。我做错了什么或者没有办法做到这一点?

//我尝试过的一些示例代码

Intent updatedIntent = changeIncomingIntent(intent, context);
intent.putExtras(updatedIntent.getExtras());
intent.replaceExtras(updatedIntent.getExtras());

2 个答案:

答案 0 :(得分:4)

你无法改变收到的意图,但如果你......嘿嘿...... 打算修改收到的短信,因为这是一个有序的广播,你可以停止广播,修改意图的附加内容,然后重新广播:

将以下内容添加到Application标记之前的ApplicationManifest.xml中:

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

请注意,这将显示在Play商店的应用的权限页面上。准备解释它。

并将其添加到Receiver中的Intent-Filter标记:

android:priority="2147483647"

这是Java中可能的最高整数,确保您的接收者获得第一优先权。请注意,其他应用程序中的接收器(特别是GO SMS)可能正在使用相同的策略,这可能意味着两个接收器最终会对消息进行争夺。如果发生这种情况,您可能必须卸载其他应用程序。

然后在你的接收器中:

public void onReceive(Context context, Intent intent){

    //Messages are delivered as extras in the intent

    Bundle bundle = intent.getExtras();

    //If this intent was rebroadcasted already, ignore it.
    if(bundle.getBooleanExtra("rebroadcast", false)        
         return;

    //Abort the broadcast
    abortBroadcast();

    //Some examples use regular arrays,
    // but I prefer a more sophisticated solution.
    ArrayList<SmsMessage> msgs = new ArrayList<SmsMessage>();

    //Check to make sure we actually have a message
    if(bundle != null){

        //Get the SMS messages
        //They are delivered in a raw format, 
        //called Protocol Description Units or PDUs

        //Messages can sometimes be delivered in bulk,
        //so that's why it's an array

        Object[] pdus = (Object[]) bundle.get("pdus");

        //I prefer the enhanced for-loop. Why reinvent the wheel?
        for(Object pdu : pdus)
            msgs.add(SmsMessage.createFromPdu((byte[])pdu));

        //Do stuff with the message.                                
        ArrayList<SmsMessage> newMessages = smsReceived(msgs);

        //Convert back to PDUs
        ArrayList<Object> pdus;
        Iterator<SmsMessage> iterator = newMessages.iterator();

        //Iterate over the messages and convert them
        while(iterator.hasNext()){
            pdus.add(iterator.next().getPdu())
        }

        //Convert back to an Object[] for bundling
        Object[] pduArr = pdus.toArray();

        //Redefine the intent.

        //It already has the broadcast action on it, 
        //so we just need to update the extras
        bundle.putExtra("pdus", pduArr);

        //Set a rebroadcast indicator so we don't process it again
        //and create an infinite loop
        bundle.putExtra("rebroadcast", true);

        intent.putExtras(bundle);

        //Finally, broadcast the modified intent with the original permission
        sendOrderedBroadcast(intent, "android.permission.RECEIVE_SMS");

    else{
        //For some reason, there was no message in the message.
        //What do you plan to do about that? I'd just ignore it.
    }
}

虽然这是一个功能性示例,但我建议在新线程中执行大部分操作,以便在消息处理是处理器密集时不阻止UI线程。例如,我在我的工作中使用了它,因为我使用了大量的正则表达式来操作消息,以及执行与消息相关的一些非常繁重的数据库查询。

如果我做错了或可能做得更好,请不要犹豫,纠正我。大部分代码都在我自己的项目中,我希望能够保证其功能。

度过愉快的一天。

答案 1 :(得分:0)

(1)您不能只修改Intent对象。这是仅适用于您的实例的本地对象。

(2)有来自接收方的结果数据的API(设置结果等),但是如果广播是作为有序广播发送的,则只能使用这些API。很少有人这样发送;文档应该说明它们何时。

请注意,广播通常是并行的,因此尝试更改其他人将收到的内容毫无意义 - 他们很可能会在您完全同时执行。