Android
BroadcastReceiver
Recherche…
Introduction
BroadcastReceiver (récepteur) est un composant Android qui vous permet de vous inscrire à des événements système ou d'application. Tous les récepteurs enregistrés pour un événement sont notifiés par le moteur d'exécution Android une fois que cet événement se produit.
Par exemple, une émission annonçant que l'écran est éteint, que la batterie est faible ou qu'une photo a été capturée.
Les applications peuvent également lancer des diffusions, par exemple pour permettre aux autres applications de savoir que certaines données ont été téléchargées sur le périphérique et peuvent être utilisées.
Introduction au récepteur de diffusion
Un récepteur de diffusion est un composant Android qui vous permet de vous inscrire à des événements système ou d'application.
Un récepteur peut être enregistré via le fichier AndroidManifest.xml
ou dynamiquement via la méthode Context.registerReceiver()
.
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//Your implementation goes here.
}
}
Ici, j'ai pris un exemple de ACTION_BOOT_COMPLETED
qui est déclenché par le système une fois que Android a terminé le processus de démarrage.
Vous pouvez enregistrer un récepteur dans un fichier manifeste comme ceci:
<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>
Maintenant que le périphérique est démarré, la méthode onReceive()
sera appelée et vous pourrez alors faire votre travail (par exemple, démarrer un service, démarrer une alarme).
Notions de base sur BroadcastReceiver
Les BroadcastReceivers sont utilisés pour recevoir les intentions de diffusion envoyées par le système d'exploitation Android, d'autres applications ou dans la même application.
Chaque intention est créée avec un filtre d'intention , qui nécessite une action String. Des informations supplémentaires peuvent être configurées dans Intent.
De même, BroadcastReceivers s'enregistre pour recevoir des intentions avec un filtre d'intention particulier. Ils peuvent être enregistrés par programmation:
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//Your implementation goes here.
}
}, new IntentFilter("Some Action"));
ou dans le fichier AndroidManifest.xml
:
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="Some Action"/>
</intent-filter>
</receiver>
Pour recevoir l'intention, définissez l'action sur quelque chose documenté par Android OS, par une autre application ou API, ou dans votre propre application, en utilisant sendBroadcast
:
mContext.sendBroadcast(new Intent("Some Action"));
En outre, Intent peut contenir des informations, telles que des chaînes, des primitives et des parcelles , qui peuvent être affichées dans onReceive
.
Utiliser LocalBroadcastManager
LocalBroadcastManager est utilisé pour envoyer des Intentions de diffusion dans une application, sans les exposer à des écouteurs indésirables.
Utiliser LocalBroadcastManager est plus efficace et plus sûr que d'utiliser directement context.sendBroadcast()
, car vous n'avez pas à vous soucier des diffusions simulées par d'autres applications, ce qui peut constituer un risque de sécurité.
Voici un exemple simple d'envoi et de réception d'émissions locales:
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("Some Action")) {
//Do something
}
}
});
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(mContext);
manager.registerReceiver(receiver, new IntentFilter("Some Action"));
// onReceive() will be called as a result of this call:
manager.sendBroadcast(new Intent("Some Action"));//See also sendBroadcastSync
//Remember to unregister the receiver when you are done with it:
manager.unregisterReceiver(receiver);
Récepteur de diffusion Bluetooth
ajouter une autorisation dans votre fichier manifeste
<uses-permission android:name="android.permission.BLUETOOTH" />
Dans votre fragment (ou activité)
- Ajouter la méthode du récepteur
private BroadcastReceiver mBluetoothStatusChangedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final Bundle extras = intent.getExtras();
final int bluetoothState = extras.getInt(Constants.BUNDLE_BLUETOOTH_STATE);
switch(bluetoothState) {
case BluetoothAdapter.STATE_OFF:
// Bluetooth OFF
break;
case BluetoothAdapter.STATE_TURNING_OFF:
// Turning OFF
break;
case BluetoothAdapter.STATE_ON:
// Bluetooth ON
break;
case BluetoothAdapter.STATE_TURNING_ON:
// Turning ON
break;
}
};
Enregistrement de diffusion
- Appelez cette méthode sur onResume ()
private void registerBroadcastManager(){
final LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity());
manager.registerReceiver(mBluetoothStatusChangedReceiver, new IntentFilter(Constants.BROADCAST_BLUETOOTH_STATE));
}
Annuler la diffusion
- Appelez cette méthode sur onPause ()
private void unregisterBroadcastManager(){
final LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity());
// Beacon機能用
manager.unregisterReceiver(mBluetoothStatusChangedReceiver);
}
Activation et désactivation d'un récepteur de diffusion par programmation
Pour activer ou désactiver un BroadcastReceiver
, nous devons obtenir une référence au PackageManager
et nous avons besoin d'un objet ComponentName
contenant la classe du récepteur que nous voulons activer / désactiver:
ComponentName componentName = new ComponentName(context, MyBroadcastReceiver.class);
PackageManager packageManager = context.getPackageManager();
Maintenant, nous pouvons appeler la méthode suivante pour activer le BroadcastReceiver
:
packageManager.setComponentEnabledSetting(
componentName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
Ou nous pouvons utiliser COMPONENT_ENABLED_STATE_DISABLED
pour désactiver le récepteur:
packageManager.setComponentEnabledSetting(
componentName,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
BroadcastReceiver pour gérer les événements BOOT_COMPLETED
L'exemple ci-dessous montre comment créer un BroadcastReceiver
capable de recevoir des événements BOOT_COMPLETED
. De cette façon, vous pouvez démarrer un Service
ou démarrer une Activity
dès que le périphérique est mis sous tension.
En outre, vous pouvez utiliser les événements BOOT_COMPLETED
pour restaurer vos alarmes car elles sont détruites lorsque le périphérique est mis hors tension.
REMARQUE: l'utilisateur doit avoir démarré l'application au moins une fois avant de pouvoir recevoir l'action BOOT_COMPLETED
.
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.example" >
...
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
...
<application>
...
<receiver android:name="com.test.example.MyCustomBroadcastReceiver">
<intent-filter>
<!-- REGISTER TO RECEIVE BOOT_COMPLETED EVENTS -->
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
MyCustomBroadcastReceiver.java
public class MyCustomBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action != null) {
if (action.equals(Intent.ACTION_BOOT_COMPLETED) ) {
// TO-DO: Code to handle BOOT COMPLETED EVENT
// TO-DO: I can start an service.. display a notification... start an activity
}
}
}
}
Exemple de LocalBroadcastManager
Un BroadcastReceiver est essentiellement un mécanisme permettant de relayer les intentions via le système d'exploitation pour effectuer des actions spécifiques. Une définition classique étant
"Un récepteur de diffusion est un composant Android qui vous permet d’enregistrer des événements système ou d’application."
LocalBroadcastManager est un moyen d'envoyer ou de recevoir des diffusions au sein d'un processus d'application. Ce mécanisme a beaucoup d'avantages
- Comme les données restent à l'intérieur du processus d'application, les données ne peuvent pas être divulguées.
- Les LocalBroadcasts sont résolus plus rapidement, car la résolution d'une diffusion normale se produit au moment de l'exécution du système d'exploitation.
Un exemple simple de LocalBroastManager est:
SenderActivity
Intent intent = new Intent("anEvent");
intent.putExtra("key", "This is an event");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
ReceiverActivity
- Enregistrer un destinataire
LocalBroadcastManager.getInstance(this).registerReceiver(aLBReceiver, new IntentFilter("anEvent"));
- Un objet concret pour effectuer une action lorsque le récepteur est appelé
private BroadcastReceiver aLBReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // perform action here. } };
- désinscrire lorsque la vue n'est plus visible.
@Override protected void onPause() { // Unregister since the activity is about to be closed. LocalBroadcastManager.getInstance(this).unregisterReceiver(aLBReceiver); super.onDestroy(); }
Communiquer deux activités via un récepteur de diffusion personnalisé
Vous pouvez communiquer deux activités pour que l'activité A puisse être informée d'un événement se produisant dans l'activité B.
Activité A
final String eventName = "your.package.goes.here.EVENT";
@Override
protected void onCreate(Bundle savedInstanceState) {
registerEventReceiver();
super.onCreate(savedInstanceState);
}
@Override
protected void onDestroy() {
unregisterEventReceiver(eventReceiver);
super.onDestroy();
}
private void registerEventReceiver() {
IntentFilter eventFilter = new IntentFilter();
eventFilter.addAction(eventName);
registerReceiver(eventReceiver, eventFilter);
}
private BroadcastReceiver eventReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//This code will be executed when the broadcast in activity B is launched
}
};
Activité B
final String eventName = "your.package.goes.here.EVENT";
private void launchEvent() {
Intent eventIntent = new Intent(eventName);
this.sendBroadcast(eventIntent);
}
Bien entendu, vous pouvez ajouter plus d’informations à la diffusion en ajoutant des extras à l’intention transmise entre les activités. Pas ajouté pour garder l'exemple aussi simple que possible.
Diffusion collante
Si nous utilisons la méthode sendStickyBroadcast (intention), l’intention correspondante est collante, ce qui signifie que l’intention que vous envoyez reste autour de la fin de la diffusion. Un StickyBroadcast, comme son nom l'indique, est un mécanisme permettant de lire les données d'une diffusion, une fois la diffusion terminée. Cela peut être utilisé dans un scénario où vous souhaiterez peut-être vérifier Activity's onCreate()
la valeur d'une clé dans l'objet avant l'activité a été lancée.
Intent intent = new Intent("com.org.action");
intent.putExtra("anIntegerKey", 0);
sendStickyBroadcast(intent);
Utiliser les diffusions commandées
Les diffusions ordonnées sont utilisées lorsque vous devez spécifier une priorité pour les auditeurs de diffusion.
Dans cet exemple, firstReceiver
recevra la diffusion toujours avant un secondReceiver
:
final int highPriority = 2;
final int lowPriority = 1;
final String action = "action";
// intent filter for first receiver with high priority
final IntentFilter firstFilter = new IntentFilter(action);
first Filter.setPriority(highPriority);
final BroadcastReceiver firstReceiver = new MyReceiver();
// intent filter for second receiver with low priority
final IntentFilter secondFilter = new IntentFilter(action);
secondFilter.setPriority(lowPriority);
final BroadcastReceiver secondReceiver = new MyReceiver();
// register our receivers
context.registerReceiver(firstReceiver, firstFilter);
context.registerReceiver(secondReceiver, secondFilter);
// send ordered broadcast
context.sendOrderedBroadcast(new Intent(action), null);
De plus, le récepteur de diffusion peut interrompre la diffusion ordonnée:
@Override
public void onReceive(final Context context, final Intent intent) {
abortBroadcast();
}
dans ce cas, tous les récepteurs de priorité inférieure ne recevront pas de message de diffusion.
État d'arrêt Android
Depuis Android 3.1, toutes les applications, lors de l'installation, sont arrêtées. En état d'arrêt, l'application ne s'exécutera pour aucune raison, sauf par un lancement manuel d'une activité ou par une intention explicite concernant une activité, un service ou une diffusion.
Lorsque vous écrivez une application système qui installe directement des APK, veuillez prendre en compte le fait que l’application nouvellement installée ne recevra aucune diffusion tant qu’elle n’a pas été arrêtée.
Un moyen simple d'activer une application consiste à envoyer une diffusion explicite à cette application. comme la plupart des applications implémentent INSTALL_REFERRER
, nous pouvons l'utiliser comme point d'accrochage
Analysez le manifeste de l'application installée et envoyez une diffusion explicite à chaque récepteur:
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
intent.setComponent(new ComponentName(packageName, fullClassName));
sendBroadcast(intent);