web-dev-qa-db-fra.com

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 par rapport à devoir ê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 avec Android.intent.action.HEADSET_PLUG le récepteur n'est pas déclenché ( Documentation Android )

D'après ce que j'ai trouvé sur ce site, vous devez enregistrer ce récepteur d'une activité ou d'un service qui est déjà en cours d'exécution pour qu'il fonctionne ( Post ).

  • Quelqu'un peut-il me dire pourquoi cela ne fonctionne pas lorsque vous ajustez 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?

  • Existe-t-il une solution pour que je puisse simplement enregistrer mon récepteur dans le manifeste de mon application à l'aide d'un filtre d'intention avec Android.intent.action.HEADSET_PLUG?

  • Comment puis-je identifier les actions de diffusion à partir du documentation Android besoin d'un service ou d'une activité pour les enregistrer par rapport au fait d'avoir simplement le bon filtre dans le manifeste?

67
Arnab C.

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, cela est lié à la durée de vie de l'activité/du 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 en a sécurité, performances, etc., et vous ne pouvez donc enregistrer le récepteur qu'en code.

En ce qui concerne la HEADSET_PLUG broadcast, il semble que l'idée soit que votre application déjà en cours d'exécution puisse obtenir des ajustements spécifiques à l'application de l'interface utilisateur, du volume, etc. Si votre application n'est pas en cours d'exécution, vous ne devriez pas vraiment vous soucier du casque débranché.

AFAIK, il n'y a pas un seul endroit où ces informations sont résumées pour toutes les émissions, mais chaque intention devrait avoir un commentaire dans le JavaDoc sur la façon de s'enregistrer et de l'utiliser, mais apparemment, cela manque par endroits. Vous devriez être en mesure de compiler une liste si vous grep l'arborescence source Android pour Intent.FLAG_RECEIVER_REGISTERED_ONLY .

90
Nikolay Elenkov

Comme d'habitude, les récepteurs de diffusion peuvent être configurés dans le fichier manifesteAndroidManifest.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 dyanmiques

Vous pouvez également enregistrer votre implémentation BroadcastReceiver de manière dynamique dans votre code. Il vous suffit 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 ()

  • receiver: Le BroadcastReceiver que vous souhaitez enregistrer
  • filter: Objet IntentFilter qui spécifie quel événement votre récepteur doit écouter.

Lorsque vous enregistrez votre récepteur de cette manière, il vit aussi longtemps que le composant vit et Android envoie des événements à ce récepteur jusqu'à ce que le composant créateur 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 de manière dynamique, veillez à désinscrire 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 la méthode d'enregistrement

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 souhaite connaître les événements à l'échelle du système:

  • Votre application propose une sorte de service autour de ces événements
  • Votre application souhaite réagir gracieusement aux changements d'état

Les exemples de la première catégorie sont des applications qui doivent fonctionner dès le démarrage de l'appareil ou qui doivent démarrer une sorte de fonctionner chaque fois qu'une application est installée. Battery Widget Pro ou App2SD sont de bons exemples pour ce type d'applications. Pour ce type, vous devez enregistrer le BroadcastReceiver dans le fichier manifeste.

Les exemples de la deuxième catégorie sont des événements qui signalent un changement de circonstances sur lesquelles votre application peut compter. Supposons que votre application dépend d'une connexion Bluetooth établie. Vous devez réagir à un changement d'état - mais uniquement lorsque votre application est active. Dans ce cas, il n'est pas nécessaire de disposer 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 en est l'événement Intent.ACTION_TIME_TICK qui est diffusé toutes les minutes. Ce qui est une sage décision car un récepteur statique déchargerait inutilement la batterie.

19
Haythem BEN AICHA