Обновление Intent Extras между заказанным BroadcastReceivers android - PullRequest
2 голосов
/ 18 июня 2011

В настоящее время я получаю SMS_Received Broadcast от системы и пытаюсь изменить значения в намерении до того, как другие вещательные приемники его получат (например, приложение обмена сообщениями по умолчанию)

Однако, независимо от того, каким образомЯ пытаюсь изменить намерение, слушатели вещания не видят обновленные значения.И поскольку система не позволяет отправлять SMS-сообщения, я не могу прервать их и отправить повторно.Я делаю что-то не так или нет такого способа?

// Пример кода, который я пробовал

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

Ответы [ 2 ]

4 голосов
/ 24 октября 2012

Вы не можете изменить полученное намерение, но если вы ... хе-хе ... намереваетесь изменить полученное SMS, потому что это упорядоченная трансляция, вы можете остановить трансляцию, изменить дополнения к цели, а затем ретранслировать его:

Добавьте следующее в файл ApplicationManifest.xml перед тегом Application:

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

Обратите внимание, что это появится на странице разрешений вашего приложения в Play Store. Будьте готовы объяснить это.

И добавьте это к тегу Intent-Filter в вашем Receiver:

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

Хотя это функциональный пример, я бы рекомендовал делать большую часть этого в новом потоке, чтобы не блокировать поток пользовательского интерфейса, если ваша обработка сообщений интенсивно использует процессор. Например, я сделал это по-своему, потому что я использую много регулярных выражений для манипулирования сообщением, а также для выполнения довольно сложных запросов к базе данных относительно сообщения.

Если я сделал что-то не так или мог бы сделать лучше, пожалуйста, не стесняйтесь меня поправлять. Большая часть этого кода находится в моем собственном проекте, и я хотел бы иметь возможность гарантировать его функциональность.

Хорошего дня.

0 голосов
/ 18 июня 2011

(1) Вы не можете просто изменить объект Intent. Это локальный объект только для вашего экземпляра.

(2) Существуют API-интерфейсы для возврата данных от получателя (настройка результата и т. Д.), Но вы можете использовать их только в том случае, если трансляция отправляется как заказанная трансляция. Очень немногие отправляются таким образом; в документации должно быть указано, когда они есть.

Обратите внимание, что трансляции, как правило, параллельны, поэтому нет смысла пытаться изменить то, что получат другие - они вполне могут выполняться точно в то же время, что и вы.

...