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

Поэтому я понимаю (я думаю) о намерениях трансляции и получении сообщений.

Итак, теперь моя проблема / то, что я не могу решить, – это отправить сообщение из метода 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 } } } 

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

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

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

Том

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

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... как в моем примере. Это помогает избежать ситуации, когда другие приложения или системные компоненты могут попытаться обработать ее.

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

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

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

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

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

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

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

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

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

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

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

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

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

 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); 

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

Работает почти так же, как и обычные трансляции, но всякая «болтовня» является локальной для приложения, в котором он работает.

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

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

Пример:

 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);