Registre du récepteur de diffusion dans le manifeste par rapport à L'activité

J'ai besoin d'aide pour comprendre quand je peux m'attendre à ce que mon récepteur de diffusion fonctionne lorsqu'il vient d'être enregistré dans le manifeste plutôt que d'être enregistré à partir d'une activité ou d'un service en cours d'exécution.

Ainsi, par exemple, si j'enregistre un récepteur autonome avec le filtre d'intention suivant, cela fonctionne sans avoir de référence de service / Activité:

<?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>

Cependant, si je remplace android.media.AUDIO_BECOMING_NOISY par android.intent.action.HEADSET_PLUG le récepteur n'est pas déclenché (Documentation Android )

De ce que je trouvé sur ce site, vous devez enregistrer ce récepteur à partir d'une activité ou d'un service déjà en cours d'exécution pour qu'il fonctionne (Post).

  • Quelqu'un peut-il me dire pourquoi cela ne fonctionne pas en ajustant simplement votre filtre d'intention dans le manifeste et pourquoi vous devez avoir un service en arrière-plan qui référence/enregistre le récepteur?

  • Y a-t-il un travail pour que je puisse simplement enregistrer mon récepteur dans le manifeste de mon application en utilisant un filtre d'intention avec android.intent.action.HEADSET_PLUG?

  • Comment puis-je identifier quelles actions de diffusion de la documentation android doivent avoir un service ou une activité les enregistrer plutôt que d'avoir le bon filtre dans le manifeste?

58
demandé sur Community 2012-06-04 07:28:15

2 réponses

Si votre récepteur est enregistré dans le manifeste et que votre application n'est pas en cours d'exécution, un nouveau processus sera créé pour gérer la diffusion. Si vous l'enregistrez dans le code, il est lié à la durée de vie de l'activité/service dans lequel vous l'avez enregistré. Pour certaines émissions, cela n'a pas vraiment de sens de créer un nouveau processus d'application s'il n'existe pas, ou s'il y a de la sécurité, des performances, etc. implications, et donc vous ne pouvez enregistrer le récepteur dans le code.

Quant à la diffusion HEADSET_PLUG, Il semble l'idée est que votre application déjà en cours d'exécution peut faire des ajustements spécifiques à l'application de L'interface utilisateur, du volume, etc. Si votre application ne fonctionne pas, vous ne devriez pas vraiment vous soucier de débrancher le casque.

AFAIK, il n'y a pas d'endroit unique cette information est résumée pour toutes les diffusions, mais chaque intention devrait avoir un commentaire dans le JavaDoc sur la façon de l'enregistrer et de l'utiliser, mais apparemment il manque dans les endroits. Vous devriez être en mesure de compiler une liste si vous grep L'arbre Source Android pour intention.FLAG_RECEIVER_REGISTERED_ONLY .

84
répondu Nikolay Elenkov 2017-03-13 23:32:35

Comme d'habitude, les récepteurs de diffusion peuvent être configurés dans le fichier manifestandroidmanifest.XML. Un BroadcastReceiver configuré de cette manière est appelé enregistré statiquement.

Vous pouvez enregistrer votre récepteur dans le fichier manifeste en utilisant l'élément:

<receiver
   android:name=".ConnectivityChangeReceiver">
   <intent-filter>
      <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
   </intent-filter>
</receiver>

L'élément imbriqué est utilisé pour spécifier l'événement auquel le récepteur doit réagir.

Récepteurs De Diffusion Dyanmic

Comme alternative, vous pouvez enregistrer votre implémentation BroadcastReceiver dynamiquement dans votre code. Vous avez juste besoin d'appeler la méthode registerReceiver() sur votre objet Context.

La méthode registerReceiver () prend deux paramètres:

Les arguments de la méthode registerReceiver ()

  • récepteur: {[19] } Le BroadcastReceiver que vous souhaitez enregistrer
  • filter: L'objet IntentFilter qui spécifie l'événement que votre récepteur doit écouter.

Lorsque vous enregistrez votre récepteur de cette façon, il vit que tant que le composant livesand Android envoie des événements à ce récepteur jusqu'à ce que le composant de création lui-même soit détruit.

C'est votre tâche de gérer correctement le cycle de vie. Ainsi, lorsque vous ajoutez un récepteur dynamiquement, prenez soin de désenregistrer le même récepteur dans la méthode onPause () de votre activité!

Je suggère d'enregistrer le récepteur dans la méthode onResume () de votre activité et de le désinscrire dans votre méthode 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();
}

Quand utiliser Quelle méthode pour registre

La méthode à utiliser pour enregistrer votre BroadcastReceiver dépend de ce que votre application fait avec l'événement système. Je pense qu'il y a essentiellement deux raisons pour lesquelles votre application veut connaître les événements à l'échelle du système:

  • votre application offre une sorte de service autour de ces événements
  • votre application veut réagir gracieusement aux changements d'État

exemples pour la première catégorie les applications doivent-elles fonctionner dès que l'appareil est démarré ou cela doit commencer une sorte de travail chaque fois qu'une application est installée. Battery Widget Pro ou App2SD sont de bons exemples pour ce genre d'applications. Pour ce type, vous devez enregistrer BroadcastReceiver dans le fichier manifeste.

Exemples pour la deuxième catégorie sont des événements que le signal d'un changement de circonstances de votre application peut compter. Disons que votre application dépend d'une connexion Bluetooth établie. Vous devez réagir à un changement d'état, mais seulement lorsque votre application est active. Dans ce cas il n'y a pas besoin d'un récepteur de diffusion enregistré statiquement. Un enregistrement dynamique serait plus raisonnable.

Il y a aussi quelques événements pour lesquels vous n'êtes même pas autorisé à vous inscrire statiquement. Un exemple de ceci est l'Intention.Action_time_tick événement qui est diffusé chaque minute. Ce qui est une sage décision car un récepteur statique viderait inutilement la batterie.

12
répondu Haythem BEN AICHA 2016-11-28 15:43:43