Подтвердить что ты не робот

Использование трансляции/широковещательного приемника для отправки сообщений от службы к активности

Итак, я понимаю (я думаю) о намерениях трансляции и получая им сообщения.

Итак, моя проблема/то, что я не могу решить, - это отправить сообщение из метода onReceive получателя в действие. Допустим, у меня есть приемник как таковой:

public class ReceiveMessages extends BroadcastReceiver 
{
@Override
   public void onReceive(Context context, Intent intent) 
   {    
       String action = intent.getAction();
       if(action.equalsIgnoreCase(TheService.DOWNLOADED)){    
           // send message to activity
       }
   }
}

Как отправить сообщение активности?

Должен ли я создать экземпляр получателя в действии, в котором я хочу отправить сообщения и каким-то образом отслеживать его? Или что? Я понимаю концепцию, но не приложение.

Любая помощь будет абсолютно потрясающей, спасибо.

Tom

4b9b3361

Ответ 1

EDITED Исправлены примеры кода для регистрации/отмены регистрации BroadcastReceiver, а также удаления декларации манифеста.

Определите ReceiveMessages как внутренний класс внутри Activity, который должен прослушивать сообщения из Service.

Затем объявите переменные класса, такие как...

ReceiveMessages myReceiver = null;
Boolean myReceiverIsRegistered = false;

В onCreate() используйте myReceiver = new ReceiveMessages();

Тогда в onResume()...

if (!myReceiverIsRegistered) {
    registerReceiver(myReceiver, new IntentFilter("com.mycompany.myapp.SOME_MESSAGE"));
    myReceiverIsRegistered = true;
}

... и в onPause()...

if (myReceiverIsRegistered) {
    unregisterReceiver(myReceiver);
    myReceiverIsRegistered = false;
}

В Service создайте и передайте Intent...

Intent i = new Intent("com.mycompany.myapp.SOME_MESSAGE");
sendBroadcast(i);

И об этом. Сделайте "действие" уникальным для вашего пакета/приложения, т.е. com.mycompany..., как в моем примере. Это помогает избежать ситуации, когда другие приложения или системные компоненты могут попытаться обработать его.

Ответ 2

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

Сценарий A: Только активность

Если вам нужно только получать трансляцию, когда у вас есть активность на переднем плане, зарегистрируйте операцию BroadcastReceiver с помощью registerReceiver(). Как указано в @MisterSquonk, вы зарегистрируете приемник в onResume() и отмените регистрацию в onPause().

Сценарий B: активность, если на переднем плане, другое другое; Заказная трансляция

Если вы хотите, чтобы активность переднего плана обрабатывала широковещательную рассылку, но вы хотите, чтобы что-то еще произошло, если это действие не находится на переднем плане (например, поднять Notification), а широковещательная передача - упорядоченная трансляция (например, входящая SMS), то вы все равно будете использовать решение Scenario A, но с более высоким приоритетом IntentFilter (см. setPriority()). Кроме того, вы зарегистрировали бы BroadcastReceiver через элемент <receiver> в манифесте с более низким приоритетом <intent-filter> для той же широковещательной передачи. В действии BroadcastReceiver вызовите abortBroadcast(), чтобы использовать это событие и не допустить его доступа к зарегистрированному манифестам BroadcastReceiver.

Сценарий C: действие, если на переднем плане, другое другое; Регулярное вещание

Если сценарий B почти подходит, но широковещательная передача, которую вы слушаете, не является упорядоченной трансляцией, вам нужно будет начать с сценария B. Однако иметь трансляцию, которую оба приемника имеют в своих фильтрах, являются вашими собственными, используя частную строку действий, предложенную @MisterSquonk. Кроме того, в манифесте зарегистрирован еще один BroadcastReceiver, чей <intent-filter> предназначен для реальной трансляции, которую вы слушаете. Этот приемник просто вызывал sendOrderedBroadcast() для отправки упорядоченной трансляции, которую прослушивают другие приемники.

Сценарий D: активность независимо от переднего плана

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

Если, однако, вы уверены, что это не часть вашей модели данных, вы можете реализовать сценарий B или сценарий C, а также добавить некоторую информацию в статическом члене данных. Ваши действия могут проверить, что статический член данных в onResume(), чтобы получить информацию о трансляции, когда они возвращаются на передний план.

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

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

Ответ 3

Чтобы транслировать намерение:

Intent intent = new Intent("com.yourcompany.testIntent");
intent.putExtra("value","test");
sendBroadcast(intent);

Для получения того же намерения используйте:

IntentFilter filter = new IntentFilter("com.yourcompany.testIntent");
        BroadcastReceiver receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
              String value =  intent.getExtras().getString("value");
            }
        };
registerReceiver(receiver, filter);

Ответ 4

Возможно, это не актуально во время вопроса, но в пакете поддержки Android есть LocalBroadcastManager.

Работает практически так же, как и обычные трансляции, но всякая "болтовня" локальна для приложения, в котором он запущен.

Преимущества:

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

Пример:

Intent i = new Intent("my.local.intent");
LocalBroadcastManager.getInstance(context).sendBroadcast(i);

и получить

receiver = new MyBroadcastReceiverToHandleLocalBroadcast();

IntentFilter i = new IntentFilter();
i.addAction("my.local.intent");
LocalBroadcastManager.getInstance(context).registerReceiver(receiver, i);