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

Регистр вещательного приемника в манифесте против активности

Мне нужна помощь, чтобы понять, когда я могу ожидать, что мой вещательный приемник будет работать, только будучи зарегистрированным в манифесте, или должен быть зарегистрирован из текущей активности или службы.

Так, например, если я зарегистрирую автономный приемник со следующим фильтром намерений, он работает без ссылки на службу/деятельность:

<?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 должны иметь сервис или активность, зарегистрировать их или просто иметь правый фильтр в манифесте?

4b9b3361

Ответ 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, которое транслируется каждую минуту. Это мудрое решение, потому что статический приемник излишне разряжал батарею.