Broadcast Receivers Android

Les récepteurs de diffusion sont utilisés pour répondre aux messages de diffusion envoyés par d'autres applications ou par le système. Ces messages sont parfois appelés événements ou intents. Par exemple, une application peut lancer une diffusion pour informer d'autres applications que certaines données ont été téléchargées sur l'appareil et sont disponibles pour elles. Ainsi, les récepteurs de diffusion peuvent définir les actions appropriées pour intercepter ces communications.

Voici deux étapes importantes pour faire fonctionner les intents de diffusion du système avec les récepteurs de diffusion.

  • Création d'un récepteur de diffusion
  • Enregistrement d'un récepteur de diffusion

Il y a une étape supplémentaire. Pour implémenter des intents personnalisés, vous devez créer et diffuser ces intents.


Création d'un récepteur de diffusion

Un récepteur de diffusion doit être implémenté comme une sous-classe de la classe BroadcastReceiver et redéfinir la méthode onReceive() pour recevoir les messages qui prennent un objet Intent en paramètre.

public class MyReceiver extends BroadcastReceiver {
   @Override
   public void onReceive(Context context, Intent intent) {
      Toast.makeText(context, "Intent Detected.", Toast.LENGTH_LONG).show();
   }
}

Enregistrement d'un récepteur de diffusion

Une application enregistre un récepteur de diffusion dans AndroidManifest.xml pour écouter des intents de diffusion spécifiques. Supposons que nous allons enregistrer MyReceiver pour écouter l'événement ACTION_BOOT_COMPLETED généré par le système. Cet événement est envoyé lorsque le processus de démarrage du système Android est terminé.

广播接收器(Broadcast Receivers)

<application
   android:icon="@drawable/ic_launcher"
   android:label="@string/app_name"
   android:theme="@style/AppTheme" >
   <receiver android:name="MyReceiver">

      <intent-filter>
         <action android:name="android.intent.action.BOOT_COMPLETED">
         </action>
      </intent-filter>

   </receiver>
</application>

Désormais, chaque fois que l'appareil Android est démarré, il sera intercepté par le récepteur de diffusion MyReceiver, et la logique implémentée dans onReceive() sera exécutée.

De nombreux événements générés par le système sont définis comme des valeurs constantes statiques dans la classe Intent. Le tableau suivant répertorie les événements système importants.

Constante d'événement Description
android.intent.action.BATTERY_CHANGED Une diffusion sticky contenant l'état de charge de la batterie, son niveau et d'autres informations.
android.intent.action.BATTERY_LOW Indique un état de batterie faible sur l'appareil.
android.intent.action.BATTERY_OKAY Indique que la batterie, après avoir été faible, est maintenant rétablie.
android.intent.action.BOOT_COMPLETED Diffusé une fois après que le système a terminé son démarrage.
android.intent.action.BUG_REPORT Affiche une activité pour signaler un bug.
android.intent.action.CALL Appelle la personne spécifiée par les données d'appel.
android.intent.action.CALL_BUTTON L'utilisateur clique sur le bouton « Appeler » pour ouvrir le composeur ou une autre interface appropriée pour composer le numéro.
android.intent.action.DATE_CHANGED La date a changé.
android.intent.action.REBOOT L'appareil a été redémarré.

Diffusion d'intents personnalisés

Si vous souhaitez générer et envoyer des intents personnalisés dans votre application, vous devez créer et envoyer ces intents via sendBroadcast() dans votre classe d'activité. Si vous utilisez la méthode sendStickyBroadcast(Intent), l'intent est persistant, ce qui signifie que l'intent que vous envoyez reste après la fin de la diffusion.

public void broadcastIntent(View view)
{
   Intent intent = new Intent();
   intent.setAction("com.example.CUSTOM_INTENT");
   sendBroadcast(intent);
}

Un intent avec com.example.CUSTOM_INTENT peut être enregistré de la même manière que nous avons enregistré les intents générés par le système précédemment.

<application
   android:icon="@drawable/ic_launcher"
   android:label="@string/app_name"
   android:theme="@style/AppTheme" >
   <receiver android:name="MyReceiver">

      <intent-filter>
         <action android:name="com.example.CUSTOM_INTENT">
         </action>
      </intent-filter>

   </receiver>
</application>

Exemple

Cet exemple explique comment créer un récepteur de diffusion pour intercepter un intent personnalisé. Une fois familiarisé avec les intents personnalisés, vous pouvez programmer votre application pour intercepter les intents générés par le système. Suivons les étapes ci-dessous pour modifier l'application Android que nous avons créée dans le chapitre de l'exemple Hello World.

Étape Description
1 Utilisez Android Studio pour créer une application Android, nommez-la broadcastreceiver et placez-la sous le package com.example.broadcastreceiver dans le chapitre de l'exemple Hello World.
2 Modifiez le fichier d'activité principale MainActivity.java pour ajouter la méthode broadcastIntent().
3 Créez un nouveau fichier Java nommé MyReceiver.java sous le package com.example.broadcastreceiver pour définir le récepteur de diffusion.
4 Une application peut gérer un ou plusieurs intents personnalisés ou système sans aucune restriction. Chaque intent que vous souhaitez intercepter doit être enregistré dans AndroidManifest.xml à l'aide de la balise <receiver.../>.
5 Modifiez le contenu par défaut du fichier res/layout/activity_main.xml pour inclure un bouton permettant de diffuser un intent.
6 Il n'est pas nécessaire de modifier le fichier de ressources de chaînes ; Android Studio s'occupera du fichier string.xml.
7 Lancez l'émulateur Android pour exécuter l'application et vérifier les résultats des modifications apportées à l'application.

Ci-dessous se trouve le contenu du fichier d'activité principale modifié src/com.example.broadcastreceiver/MainActivity.java. Ce fichier contient chacune des méthodes de cycle de vie de base. Nous avons ajouté la méthode broadcastIntent() pour diffuser des événements personnalisés.

package com.example.broadcastreceiver;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.content.Intent;
import android.view.View;

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    // 广播自定义意图
    public void broadcastIntent(View view){
        Intent intent = new Intent();
        intent.setAction("cn.programmer.CUSTOM_INTENT");
        sendBroadcast(intent);
    }
}

Ci-dessous se trouve le contenu de src/com.example.broadcastreceiver/MyReceiver.java :

package com.example.broadcastreceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "检测到意图。", Toast.LENGTH_LONG).show();
    }
}

Ensuite, modifiez le fichier AndroidManifest.xml. Ici, nous incluons notre récepteur de diffusion en ajoutant la balise <receiver.../> :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.broadcastreceiver"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="22" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>

        </activity>

        <receiver android:name="MyReceiver">

            <intent-filter>
                <action android:name="cn.programmer.CUSTOM_INTENT">
                </action>
            </intent-filter>

        </receiver>

    </application>

</manifest>

Ci-dessous se trouve le contenu du fichier res/layout/activity_main.xml, contenant un bouton permettant de diffuser un intent personnalisé.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="广播实例"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:textSize="30dp" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="www.example.com"
        android:textColor="#ff87ff09"
        android:textSize="30dp"
        android:layout_above="@+id/imageButton"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="40dp" />

    <ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageButton"
        android:src="@drawable/ic_launcher.html"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button2"
        android:text="广播意图"
        android:onClick="broadcastIntent"
        android:layout_below="@+id/imageButton"
        android:layout_centerHorizontal="true" />

</RelativeLayout>

Voici le contenu du fichier res/values/strings.xml, qui définit deux nouvelles constantes.

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">Android Broadcast Receiver</string>
    <string name="action_settings">Settings</string>
    <string name="menu_settings">Settings</string>
    <string name="title_activity_main">Main Activity</string>

</resources>

Exécutons l'application Hello World! que nous venons de modifier. Je suppose que vous avez déjà créé un AVD lors de la configuration de l'environnement. Ouvrez le fichier d'activité dans votre projet, puis cliquez sur l'图片icône dans la barre d'outils pour exécuter l'application dans Android Studio. Android Studio installe l'application sur l'AVD et la démarre. Si tout se passe bien, ce qui suit s'affichera dans la fenêtre de l'émulateur :

图片

Cliquez maintenant sur le bouton « Broadcast Intent » pour diffuser notre intent personnalisé. Cela diffusera notre intent personnalisé « cn.programmer.CUSTOM_INTENT », qui sera intercepté par notre récepteur de diffusion enregistré MyReceiver et exécutera la logique que nous avons implémentée. Un toast apparaîtra en bas de l'émulateur, comme suit :

图片

Vous pouvez essayer d'implémenter d'autres récepteurs de diffusion pour intercepter les intents générés par le système, tels que le démarrage du système, le changement de date, la batterie faible, etc.

Autres extensions