Использование широковещательного намерения / широковещательного получателя для отправки сообщений из службы в деятельность
Таким образом, я понимаю (я думаю) о намерениях вещания и получении сообщений для них.
Итак, теперь моя проблема / что я не могу решить, это как отправить сообщение с 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
}
}
}
Как бы я отправил сообщение на активность?
Должен ли я создавать экземпляр получателя в активности, на которую я хочу отправлять сообщения, и каким-то образом отслеживать его? Или что? Я понимаю концепцию, но не совсем приложение.
Любая помощь была бы просто потрясающей, спасибо.
Том
4 ответа
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()
,
Сценарий B: Деятельность "Если на переднем плане", "Другое"; Заказанная трансляция
Если вы хотите, чтобы действие на переднем плане обрабатывало трансляцию, но вы хотите, чтобы что-то еще происходило, если это действие не на переднем плане (например, поднимите Notification
), а трансляция является заказной трансляцией (например, входящие SMS), тогда вы все равно будете использовать решение сценария A, но с более высоким приоритетом IntentFilter
(увидеть setPriority()
). Кроме того, вы бы зарегистрировать BroadcastReceiver
через <receiver>
элемент в манифесте, с более низким приоритетом <intent-filter>
для той же передачи. В деятельности BroadcastReceiver
, вызов 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);
Возможно, это не относится к моменту, когда задается вопрос, но в пакете поддержки 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);