更新有序的 BroadcastReceiver android 之间的 Intent extras

发布于 2024-11-16 03:47:52 字数 377 浏览 3 评论 0原文

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

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

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

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

I am currently getting the SMS_Received Broadcast from the system and am attempting to change the values in the intent before the other broadcastreceivers get it, (such as the default messaging app)

However, no matter what way I try and change the intent, the broadcast listeners do not see the updated values. And because the system does not let you send out a SMS_Received broadcast I cannot abort this one and resend one out. Am I doing something wrong or is there no way this can be done?

//Some example code I have tried

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烟雨凡馨 2024-11-23 03:47:52

您无法更改收到的意图,但如果您...呵呵...打算修改收到的短信,因为它是有序广播,您可以停止广播,修改意图的extras,然后重新广播它:

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

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

请注意,这将显示在 Play 商店中应用程序的权限页面上。准备好解释一下。

并将其添加到接收器中的 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 线程。例如,我在我的程序中这样做是因为我使用了大量正则表达式来操作消息,并执行一些与消息相关的相当繁重的数据库查询。

如果我做错了什么或者可以做得更好,请随时纠正我。大部分代码都在我自己的项目中,我希望能够保证其功能。

祝你今天过得愉快。

You can't change the received intent, but if you're... hehe... intending to modify a received SMS, because it's an ordered broadcast, you can stop the broadcast, modify the intent's extras, and then rebroadcast it:

Add the following to your ApplicationManifest.xml before the Application tag:

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

Note that this will appear on your app's permissions page in the Play Store. Be prepared to explain it.

And add this to the Intent-Filter tag in your Receiver:

android:priority="2147483647"

That's the highest possible integer in Java, ensuring that your receiver gets first priority. Note that receivers in other applications (notably GO SMS) might be using this same strategy, which may mean that the two receivers end up fighting over a message. If this happens, you'll probably have to uninstall the other app.

And then in your receiver:

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.
    }
}

While this is a functional example, I would recommend doing most of this in a new Thread so as to not block the UI thread if your message handling is processor-intensive. For example, I did it in mine because I employ a lot of regex to manipulate the message, as well as perform some pretty heavy database queries in relation to the message.

If I did something wrong or could have done better, please don't hesitate to correct me. Most of this code is in my own project and I'd like to be able to guarantee its functionality.

Have a nice day.

缱绻入梦 2024-11-23 03:47:52

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

(2) 有一些 API 可用于从接收器返回结果数据(设置结果等),但只有在广播作为有序广播发送时才能使用这些 API。很少有人通过这种方式发送;文档应该说明它们是什么时候。

请注意,广播通常是并行的,因此尝试更改其他人将收到的内容是没有意义的——它们很可能与您同时执行。

(1) You can't just modify the Intent object. That is a local object only for your instance.

(2) There are APIs for resulting data back from the receiver (setting the result and such), but you can only use these if the broadcast is being sent as a ordered broadcast. Very few are sent this way; the documentation should say when they are.

Note that broadcasts are normally parallel, so it makes no sense to try to change what others will receive -- they could very well be executing at the exact same time you are.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文