Регистр вещательного приемника в манифесте против активности
Мне нужна помощь, чтобы понять, когда я могу ожидать, что мой вещательный приемник будет работать, только будучи зарегистрированным в манифесте, или должен быть зарегистрирован из текущей активности или службы.
Так, например, если я зарегистрирую автономный приемник со следующим фильтром намерений, он работает без ссылки на службу/деятельность:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.blk_burn.standalonereceiver"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<receiver android:name="TestReceiver">
<intent-filter>
<action android:name="android.media.AUDIO_BECOMING_NOISY"/>
</intent-filter>
</receiver>
</application>
</manifest>
Однако, если я заменяю android.media.AUDIO_BECOMING_NOISY
на android.intent.action.HEADSET_PLUG
, приемник не запускается (Android-документация)
Из того, что я нашел на этом сайте, вам необходимо зарегистрировать этот ресивер из активности или службы, которая уже работает для работы (Сообщение).
-
Может ли кто-нибудь сказать мне, почему это не работает, когда вы просто корректируете свой фильтр намерений в манифесте и почему вам нужно, чтобы служба работала в фоновом режиме, которая ссылается/регистрирует ресивер?
-
Есть ли работа, чтобы я мог просто зарегистрировать приемник в своем манифесте приложения, используя фильтр намерений с android.intent.action.HEADSET_PLUG
?
-
Как я могу определить, какие действия в трансляции из документации по android должны иметь сервис или активность, зарегистрировать их или просто иметь правый фильтр в манифесте?
Ответы
Ответ 1
Если ваш приемник зарегистрирован в манифесте, и ваше приложение не запущено, для обработки широковещательной передачи будет создан новый процесс. Если вы зарегистрируете его в коде, это связано с жизнью активности/службы, в которой вы его зарегистрировали. Для некоторых трансляций нет смысла создавать новый процесс приложения, если он не существует, или есть некоторые безопасность, производительность и т.д., и, следовательно, вы можете зарегистрировать приемник только в коде.
Что касается широковещательной передачи HEADSET_PLUG
, кажется, идея состоит в том, что ваше уже запущенное приложение может заставить это делать настройки приложения для пользовательского интерфейса, тома и т.д. Если ваше приложение не работает, вам все равно не нужно о отсоединении наушников.
AFAIK, нет единого места, где эта информация суммируется для всех передач, но каждый Intent должен иметь комментарий в JavaDoc о том, как зарегистрироваться и использовать его, но, по-видимому, ему не хватает мест. Вы должны скомпилировать список, если вы grep для дерева исходных текстов Android для Intent.FLAG_RECEIVER_REGISTERED_ONLY.
Ответ 2
Как обычно, широковещательные приемники могут быть настроены в манифесте fileAndroidManifest.xml. BroadcastReceiver, настроенный таким образом, называется статически зарегистрированным.
Вы можете зарегистрировать приемник в файле манифеста с помощью элемента:
<receiver
android:name=".ConnectivityChangeReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
Вложенный элемент используется для указания события, на которое должен реагировать приемник.
Дианмические радиопередатчики
В качестве альтернативы вы можете динамически регистрировать свою реализацию BroadcastReceiver в своем коде. Вам просто нужно вызвать метод registerReceiver() в вашем объекте Context.
Метод registerReceiver() принимает два параметра:
Аргументы метода registerReceiver()
- получатель: BroadcastReceiver, который вы хотите зарегистрировать
- фильтр: Объект IntentFilter, который указывает, какое событие должен прослушивать ваш приемник.
Когда вы регистрируете свой приемник таким образом, он живет до тех пор, пока компонент живет, и Android отправляет события этому приемнику, пока сам создающий компонент не будет уничтожен.
Его задача правильно справиться с жизненным циклом. Таким образом, когда вы добавляете ресивер динамически, позаботьтесь о том, чтобы отменить регистрацию того же приемника в методе onPause() вашей деятельности!
Я предлагаю зарегистрировать приемник в методе onResume() вашей деятельности и отменить регистрацию в методе onPause():
@Override
protected void onPause() {
unregisterReceiver(mReceiver);
super.onPause();
}
@Override
protected void onResume() {
this.mReceiver = new ConnectivityChangeReceiver();
registerReceiver(
this.mReceiver,
new IntentFilter(
ConnectivityManager.CONNECTIVITY_ACTION));
super.onResume();
}
Когда использовать какой метод для регистрации
Какой метод использовать для регистрации вашего BroadcastReceiver зависит от того, что ваше приложение делает с системным событием. Я думаю, что есть две причины, по которым ваше приложение хочет узнать об общесистемных событиях:
- Ваше приложение предлагает некоторую услугу вокруг этих событий.
- Ваше приложение хочет любезно реагировать на изменения состояния.
Примеры для первой категории - это приложения, которые должны работать сразу после загрузки устройства или запускать какую-либо работу при установке приложения. Battery Widget Pro или App2SD - хорошие примеры для таких приложений. Для этого типа вы должны зарегистрировать BroadcastReceiver в файле манифеста.
Примеры для второй категории - это события, которые сигнализируют об изменении обстоятельств, на которые может положиться ваше приложение. Скажите, что ваше приложение зависит от установленного соединения Bluetooth. Вы должны реагировать на изменение состояния - но только тогда, когда ваше приложение активно. В этом случае нет необходимости в статически зарегистрированном широковещательном приемнике. Динамически зарегистрированный был бы более разумным.
Есть также несколько событий, для которых вам даже не разрешено статически регистрироваться. Примером этого является событие Intent.ACTION_TIME_TICK, которое транслируется каждую минуту. Это мудрое решение, потому что статический приемник излишне разряжал батарею.