Un BroadcastReceiver
est un composant android responsable de l'écoute des événements ou des intentions de diffusion à l'échelle du système.
Dans [Android] (https://camposha.info/android/introduction), la plupart des événements système sont diffusés par des objets Intent
. Pour ce faire, ces objets Intent
sont envoyés aux BroadcastReceivers en utilisant les méthodes Context.sendBroadcast()
.
Lorsqu'un tel événement est diffusé, le BroadcastReceiver
le reçoit et réagit soit en créant une notification dans la barre d'état, soit en exécutant une tâche donnée.
Un BroadcastReceiver
est un composant android comme les Activity
et les Service
, il doit donc la plupart du temps être enregistré dans le fichier manifeste android.
Cependant, contrairement aux Activity
, les BroadcastReceiver n'ont pas d'interface utilisateur.
En tant que classe, BroadcastReceiver est abstrait, et possède donc normalement une méthode appelée onReceive()
que nous surchargeons pour effectuer la tâche que nous voulons voir se produire lorsque la tâche est reçue.
La plupart des événements système standard sont définis comme des chaînes d'action et peuvent être trouvés dans la documentation de l'API pour la classe Intent
.
Supposons, par exemple, que votre application doive être notifiée chaque fois que l'utilisateur connecte ou déconnecte le chargeur à l'appareil, deux actions de diffusion définies dans la classe Intent
le font :
ACTION_PUISSANCE_DÉCONNECTÉE
ACTION_POWER_CONNECTED
.
Voici un exemple.
public class PhoneChargerConnectedListener extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_POWER_CONNECTED.equals(action)) {
context.startService(
new Intent(MyService.ACTION_POWER_CONNECTED));
} else if (Intent.ACTION_POWER_DISCONNECTED.equals(action)) {
context.startService(
new Intent(MyService.ACTION_POWER_DISCONNECTED));
}
}
}
Dans cette méthode, la seule chose que vous faites est d'appeler Context.startService()
pour déléguer l'événement à un service
qui effectue le travail réel.
Comment enregistrer un BroadcastReceiver
?
Eh bien, nous pouvons enregistrer broadcastReceiver de deux façons.
1. Via AndroidManifest.xml
La méthode par défaut pour implémenter les BroadcastReceivers est de les déclarer dans le manifeste android.
De ce fait, il est possible pour le BroadcastReceiver
de notifier votre service
même si l'utilisateur n'a pas démarré votre application.
Ceci est particulièrement utile pour les applications qui doivent démarrer sur certains événements système sans interaction de l'utilisateur.
<receiver android_name=".PhoneChargerConnectedListener">
<intent-filter>
<action android_name="android.intent.action.ACTION_POWER_CONNECTED"/>
<action android_name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
</intent-filter>
</receiver>
Cette méthode est aussi la plus simple.
En utilisant AndroidManifest.xml
pour enregistrer BroadcastReceiver, votre application recevra les diffusions jusqu'à ce que vous désinstalliez l'application. Cela signifie que vous sacrifiez un peu de contrôle sur le cycle de vie du BroadcastReceiver
car vous ne pouvez pas simplement l'enregistrer et le désenregistrer comme vous le souhaitez.
Pour ce faire, vous consultez la prochaine façon d'enregistrer les récepteurs de diffusion.
2. Par voie programmatique
Les récepteurs de diffusion peuvent également être enregistrés de manière programmatique dans les [Activités] (https://camposha.info/android/activity) et les services.
En fait, certaines intentions de diffusion ne peuvent être enregistrées que de manière programmatique. D'autre part, certains ne fonctionnent que si vous les déclarez dans votre manifeste.
Lorsque vous enregistrez un BroadcastReceiver de manière programmatique, vous devez également penser à le désenregistrer dans le callback correspondant.
Voici un exemple :
public class MyActivity extends AppCompatActivity {
private PhoneChargerConnectedListener myPhoneChargerConnectedListener;
@Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_POWER_CONNECTED);
intentFilter.addAction(Intent.ACTION_POWER_DISCONNECTED);
myPhoneChargerConnectedListener = new PhoneChargerConnectedListener();
registerReceiver(myPhoneChargerConnectedListener, intentFilter);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(myPhoneChargerConnectedListener);
}
}
Dans ce cas, nous avons enregistré le BroadcastReceiver
de manière programmatique en utilisant la méthode registerReceiver()
de la classe Context. En utilisant cette méthode, nous pouvons contrôler le cycle de vie de notre BroadcastReceiver
en l'enregistrant et le désenregistrant selon nos besoins.
Exemple de BroadcastReceiver
avec AlarmManager
Voyons un exemple simple de récepteur de diffusion avec un gestionnaire d'alarme.
Nous aurons une activité
et une classe.
(a). MainActivity.java
Commencez par créer une activity
dans votre android studio.
Ici nous avons notre classe MainActivity
. Cette classe sera dérivée de AppCompatActivity qui réside dans la bibliothèque de support.
Nous aurons trois méthodes :
onCreate()
,initializeViews()
,go()
.
L'interface utilisateur de cette activité
sera gonflée à partir de content_main.xml
en utilisant la méthode setContentView()
.
Les vues que nous utilisons sont EditTexts et Buttons.
Nous les référençons à partir de notre spécification de layout en utilisant findViewById()
.
Nous allons initialiser et démarrer notre alarme dans la méthode go()
.
package com.tutorials.hp.alarmmanagerstarter;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
Button startBtn;
EditText timeTxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
initializeViews();
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
/*
INITIALIZE VIEWS
*/
private void initializeViews()
{
timeTxt= (EditText) findViewById(R.id.timeTxt);
startBtn= (Button) findViewById(R.id.startBtn);
startBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
go();
}
});
}
/*
INITIALIZE AND START OUR ALARM
*/
private void go()
{
//GET TIME IN SECONDS AND INITIALIZE INTENT
int time=Integer.parseInt(timeTxt.getText().toString());
Intent i=new Intent(this,MyReceiver.class);
//PASS CONTEXT,YOUR PRIVATE REQUEST CODE,INTENT OBJECT AND FLAG
PendingIntent pi=PendingIntent.getBroadcast(this,0,i,0);
//INITIALIZE ALARM MANAGER
AlarmManager alarmManager= (AlarmManager) getSystemService(ALARM_SERVICE);
//SET THE ALARM
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+(time*1000),pi);
Toast.makeText(MainActivity.this, "Alarm set in "+time+" seconds", Toast.LENGTH_SHORT).show();
}
}
(b). MonReceveur.java
- Notre classe MyReciever.
- Dérive de la classe android.content.BroadcastReceiver.
- Méthodes : onReceive().
- Nous affichons un message de toast dans notre méthode
onReceive()
pour simuler une sonnerie d'alarme.
package com.tutorials.hp.alarmmanagerstarter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
/*
RING ALARM WHEN IN WHEN WE RECEIVE OUR BROADCAST
*/
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm Ringing...", Toast.LENGTH_SHORT).show();
}
}
(c) activity_main.xml
- Notre fichier principal de mise en page
activité
. - Doit être gonflé en MainActivity.
- La balise racine est relativeLayout.
- Contient un EditText et un bouton.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
tools_context="com.tutorials.hp.alarmmanagerstarter.MainActivity"
>
<EditText
android_id="@+id/timeTxt"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_alignParentLeft="true"
android_layout_alignParentTop="true"
android_layout_marginTop="28dp"
android_ems="10"
android_hint="Number of seconds"
android_inputType="numberDecimal" />
<Button
android_id="@+id/startBtn"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_alignRight="@+id/timeTxt"
android_layout_below="@+id/timeTxt"
android_layout_marginRight="60dp"
android_layout_marginTop="120dp"
android_text="Start" />
</RelativeLayout>
(d). AndroidManifest.xml
Nous allons devoir enregistrer notre classe BroadcastReceiver
dans notre manifest android.
Voici mon manifeste dans son intégralité :
<?xml version="1.0" encoding="utf-8"?>
<manifest
package="com.tutorials.hp.alarmmanagerstarter">
<application
android_allowBackup="true"
android_icon="@mipmap/ic_launcher"
android_label="@string/app_name"
android_supportsRtl="true"
android_theme="@style/AppTheme">
<activity
android_name=".MainActivity"
android_label="@string/app_name"
android_theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android_name="android.intent.action.MAIN" />
<category android_name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android_name="MyReceiver" >
</receiver>
</application>
</manifest>
Exemples de BroadcastReceiver
rapides
1. Ecouter les changements d'état du réseau avec BroadcastReceiver
Tout d'abord, nous devons créer une classe java, et la faire dériver de android.content.BroadcastReceiver
.
Comme champs d'instance nous aurons un booléen isNetWorkConnected
qui contiendra pour nous le vrai ou le faux indiquant si le réseau est connecté ou non.
Nous aurons également un objet Contexte.
Nous fournissons deux constructeurs, un qui va injecter dans notre classe l'objet Context
.
Ensuite, nous surchargeons la méthode onReceive()
de la classe BroadcastReceiver
. Normalement, cette méthode reçoit deux objets, un objet Context
et un objet Intent
.
Ici, nous allons initialiser un ConnectivityManager
en utilisant la méthode getSystemService()
,de la classe Context
.
En utilisant l'instance de ConnectivityManager
, nous invoquons la méthode getActiveNetworkInfo()
pour recevoir des informations sur le réseau que nous conservons dans un objet android.net.NetworkInfo
.
Finalement, nous définissons la valeur isConnected()
comme étant le booléen isNetWorkConnected
.
Ensuite, nous avons aussi la méthode isNetWorkAvailable()
, qui va essentiellement vérifier pour nous si le réseau est disponible.
C'est juste une méthode publique qui a besoin de l'instance de cette classe pour être invoquée comme nous allons le voir dans un court instant.
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.widget.Toast;
import java.util.concurrent.CopyOnWriteArrayList;
public class NetWorkStateReceiver extends BroadcastReceiver {
public boolean isNetWorkConnected;
private Context mContext;
public NetWorkStateReceiver() {
super();
}
public NetWorkStateReceiver(Context context) {
mContext = context;
}
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectivityManager = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
isNetWorkConnected = true;
} else {
isNetWorkConnected = false;
Toast.makeText(context, "No network Connection", Toast.LENGTH_SHORT).show();
}
}
/**
* Check if network is available
* @return boolean value
*/
public boolean isNetWorkAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager)
mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null) {
return networkInfo.isConnected();
}
return false;
}
}
Ensuite, dans votre MainActivity ou n'importe où, vous pouvez venir et commencer par instancier la classe ci-dessus :
publi class MainActivity extends AppCompatActivity{
NetWorkStateReceiver receiver;
@Override
public void onCreate(Bundle savedInstanceState){
.....
receiver = new NetWorkStateReceiver(this);
if(receiver.isNetWorkAvailable())
{
//do something network is available
}
}
}
Dans votre AndroidManifest.xml
vous devez d'abord ajouter les permissions appropriées ainsi qu'enregistrer votre BroadcastReceiver
:
<?xml version="1.0" encoding="utf-8"?>
<manifest
>
<uses-permission android_name="android.permission.INTERNET" />
<uses-permission android_name="android.permission.ACCESS_NETWORK_STATE" />
<application>
....
<receiver
android_name=".broadcasts.NetWorkStateReceiver"
android_enabled="true"
android_exported="true" />
....
</application>
2. Comment créer un BroadcastReceiver
personnalisé ?
Voici une classe abstraite personnalisée de BroadcastReceiver. Evidemment, elle dérive de la classe BroadcastReceiver
. Nous procédons et redéfinissons les méthodes importantes de cette classe comme les méthodes registerReceiver()
, unregisterReceiver()
et sendBroadcast()
.
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;
public abstract class LocalBroadcastCommunicator extends BroadcastReceiver {
// The action name used to send and alsoe receive intents
private static String sAction = null;
private static <T> void registerReceiver(LocalBroadcastCommunicator receiver, Context context) {
sAction = receiver.getClass().getName();
LocalBroadcastManager.getInstance(context).registerReceiver(receiver, new IntentFilter(sAction));
}
private static <T> void unregisterReceiver(LocalBroadcastCommunicator receiver, Context context) {
LocalBroadcastManager.getInstance(context).unregisterReceiver(receiver);
}
public static void sendBroadcast(Context context, Intent intent) {
if(sAction == null) {
/* If sAction is null at this point, no receiver has been registered yet and there's no
* point in sending a broadcast. */
return;
}
intent.setAction(sAction);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
public void registerReceiver(Context context) {
registerReceiver(this, context);
}
public void unregisterReceiver(Context context) {
unregisterReceiver(this, context);
}
}
Exemples complets
1. Comment afficher une notification pour une batterie faible en utilisant BroadcastReceiver
.
Nous allons créer un BatteryManager simple en utilisant la classe BroadcasteReceiver. Nous allons afficher le niveau de la batterie dans un TextView et montrer la progression dans la barre de progression.
Voici quelques-unes des API que vous ne connaissez peut-être pas et que nous utilisons :
(a). BroadcastReceiver
.
C'est la classe de base pour le code qui recevra les intentions envoyées par sendBroadcast()
.
(b). IntentFilter
IntentFilter est une description structurée des valeurs Intent
à faire correspondre. Un IntentFilter peut correspondre à des actions
, des catégories
, et des données
(via leur type, leur schéma, et/ou leur chemin) dans un Intent
.
(c). Gestionnaire de batterie
Cette classe contient des chaînes et des constantes utilisées pour les valeurs dans l'Intent
ACTION_BATTERY_CHANGED
.
MainActivity.java
Il s'agit de l'activité
principale.
package com.example.ankitkumar.broadcastreceiver_batterymanager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ProgressBar;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView batteryLevel;
ProgressBar myProgressBar;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
batteryLevel = (TextView)findViewById(R.id.textView);
myProgressBar = (ProgressBar)findViewById(R.id.progressBar);
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(myBroadcastReceiver, intentFilter);
}
BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
context.unregisterReceiver(this);
int currentLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
int level = -1;
if (currentLevel >= 0 && scale > 0) {
level = (currentLevel * 100) / scale;
}
batteryLevel.setText("Battery Level remaining :"+ level +"%");
myProgressBar.setProgress(level);
}
};
}
activity_main.xml
Voici le layout de l'activité
principale.
Ici, nous aurons un TextView pour montrer le niveau de la batterie et une barre de progression pour montrer le pourcentage de la batterie.
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout
tools_context="com.example.ankitkumar.broadcastreceiver_batterymanager.MainActivity" android_paddingTop="@dimen/activity_vertical_margin" android_paddingRight="@dimen/activity_horizontal_margin" android_paddingLeft="@dimen/activity_horizontal_margin" android_paddingBottom="@dimen/activity_vertical_margin" android_layout_height="match_parent" android_layout_width="match_parent" android_id="@+id/activity_main" >
<TextView
android_layout_height="wrap_content" android_layout_width="wrap_content" android_id="@+id/textView" android_layout_centerHorizontal="true" android_layout_centerVertical="true" android_textSize="20sp" android_text="Hello World!"/>
<ProgressBar
android_layout_height="20dp" android_layout_width="match_parent" android_id="@+id/progressBar" android_layout_alignParentRight="true" android_layout_alignParentEnd="true" android_layout_below="@+id/textView" android_layout_marginTop="25dp" android_max="100" style="?android:attr/progressBarStyleHorizontal"/>
</RelativeLayout>
Téléchargement
No. | Emplacement | Lien | |||
---|---|---|---|---|---|
1. | GitHub | Télécharger | |||
2. | GitHub | Browse | |||
2. | GitHub | Créateur original : @AnkitKumar111 | 2. | GitHub | Parcourir |
2. Utiliser BroadcastReceiver
pour écouter les SMS entrants et les afficher
Nous écoutons le SMS entrant, puis le lisons et l'affichons dans un message Toast.
MainActivity.java (Activité principale)
Voici la principale activité
.
package com.example.ankitkumar.msgreceive;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//checking wether the permission is already granted
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS}, 1);
}
}
}
IcomingSMS.java
Notre fichier IncomingSMS.java
. Voici quelques-unes des APIs que nous utilisons :
(a). SmsManager
C'est une classe définie dans le paquet android.telephony
qui est responsable de la gestion des opérations SMS telles que l'envoi de messages SMS de données, de texte et de pdu.
(b). SmsMessage
Ceci représente un message du service de messages courts.
package com.example.ankitkumar.msgreceive;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
import static android.telephony.SmsMessage.createFromPdu;
public class IncomingSms extends BroadcastReceiver {
// Get the object of SmsManager
final SmsManager sms = SmsManager.getDefault();
@Override
public void onReceive(Context context, Intent intent) {
// Retrieves a map of extended data from the intent.
final Bundle bundle = intent.getExtras();
try {
if (bundle != null) {
final Object[] pdusObj = (Object[]) bundle.get("pdus");
for (int i = 0; i < pdusObj.length; i++) {
SmsMessage currentMessage = createFromPdu((byte[]) pdusObj[i]);
String phoneNumber = currentMessage.getDisplayOriginatingAddress();
String senderNum = phoneNumber;
String message = currentMessage.getDisplayMessageBody();
Log.i("SmsReceiver", "senderNum: " + senderNum + "; message: " + message);
int duration = Toast.LENGTH_LONG;
final Toast toast = Toast.makeText(context, "senderNum: " + senderNum + ", message: " + message, duration);
toast.show();
//Countdown Timer for extending normal time of toast notification
new CountDownTimer(9000, 1000) {
public void onTick(long millisUntilFinished) {
toast.show();
}
public void onFinish() {
toast.show();
}
}.start();
} // end for loop
} // bundle is null
} catch (Exception e) {
Log.e("SmsReceiver", "Exception smsReceiver" + e);
}
}
}
activity_main.xml
Ceci représente la mise en page de l'activité
principale.
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout
tools_context="com.example.ankitkumar.msgreceive.MainActivity" android_background="#f2f2f2" android_layout_height="match_parent" android_layout_width="match_parent" >
<ImageView
android_background="@drawable/ic_sms" android_layout_height="200sp" android_layout_width="200sp" android_contentDescription="@string/app_name" android_layout_centerInParent="true" android_alpha="0.4"/>
</RelativeLayout>
Téléchargement
No. | Emplacement | Lien | |||
---|---|---|---|---|---|
1. | GitHub | Télécharger | |||
2. | GitHub | Browse | 2. | GitHub | [Original Creator : @ @Chevalier.com]. |
2. | GitHub | [Créateur original : @AnkitKumar111] (https://github.com/AnkitKumar111) |
Android LocalBroadcastManager
(gestionnaire de diffusion locale)
*Tutoriel et exemple du LocalBroadcastManager
d'Android avec IntentService
.
Ceci est un tutoriel et un exemple du LocalBroadcastManager
d'Android. Nous voulons voir ce qu'est le LocalBroadcastManager
et comment l'utiliser avec un IntentService
.
Tutoriel vidéo
Certaines personnes préfèrent toujours les tutoriels vidéo. Dans ce cas, voici la version vidéo de ce tutoriel.
Ce que vous apprenez dans ce tutoriel
Voici quelques-uns des points que vous apprendrez dans ce tutoriel.
- Ce qu'est un
LocalBroadcastManager
et sa définition API. - Les avantages du
LocalBroadcastManager
. - Comment utiliser
LocalBroadcastManager
avecIntentService
.
Qu'est-ce que LocalBroadcastManager
?
Eh bien, LocalBroadcastManager
est une classe d'aide qui nous permet de nous enregistrer et d'envoyer des diffusions d'Intents aux objets locaux de notre processus.
Voici sa définition de l'API :
public final class LocalBroadcastManager
extends Object
java.lang.Object
↳ android.support.v4.content.LocalBroadcastManager
Les avantages de LocalBroadcastManager
.
Voici quelques-uns des avantages du LocalBroadcastManager
par rapport à l'envoi de diffusions globales avec la méthode sendBroadcast(
Intent)
:
- Les données de votre application restent privées car cette classe ne travaille qu'avec certains objets de votre processus d'application.
- Elle est plus sûre car elle ne travaille que dans le processus de votre application.
- C'est également plus efficace que d'envoyer une diffusion globale à travers le système.
(a). BroadcastSenderIntentService
Voici notre classe IntentService
. Nous allons dériver de la classe android.app.IntentService
et surcharger la méthode onHandleIntent()
. A l'intérieur de cette méthode, nous allons simuler une tâche lourde en invoquant la méthode sleep()
de notre classe thread
.
package info.camposha.localbroadcastandintentservice;
import android.app.IntentService;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
public class BroadcastSenderIntentService extends IntentService {
public BroadcastSenderIntentService() {
super("BroadcastSenderIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
String message = getString(R.string.running);
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(MainActivity.MESSAGE_SENT_ACTION);
broadcastIntent.putExtra(MainActivity.MESSAGE_EXTRA, message);
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
message = getString(R.string.finished);
broadcastIntent = new Intent();
broadcastIntent.setAction(MainActivity.MESSAGE_SENT_ACTION);
broadcastIntent.putExtra(MainActivity.MESSAGE_EXTRA, message);
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);
}
}
(b). MainActivity.java
Voici notre activité
principale. Nous commençons par définir plusieurs constantes de chaînes de caractères qui seront utiles lors de l'envoi et de la réception de nos intents car elles agissent comme des identifiants.
package info.camposha.localbroadcastandintentservice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
public static final String MESSAGE_SENT_ACTION = "info.camposha.MESSAGE_RECEIVED_ACTION";
public static final String MESSAGE_EXTRA = "info.camposha.MESSAGE_EXTRA";
private static final String MESSAGE_FROM_SERVICE_KEY = "info.camposha.MESSAGE_FROM_SERVICE_KEY";
private BroadcastReceiver receiver;
private TextView serviceMessageView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
serviceMessageView = findViewById(R.id.service_message_textview);
if (savedInstanceState != null) {
serviceMessageView.setText(savedInstanceState.getString(MESSAGE_FROM_SERVICE_KEY));
}else{
serviceMessageView.setText("Null");
}
}
@Override
protected void onResume() {
super.onResume();
receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
String message = bundle.getString(MESSAGE_EXTRA);
serviceMessageView.setText(message);
}
};
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, new IntentFilter(MESSAGE_SENT_ACTION));
}
@Override
protected void onPause() {
super.onPause();
if (receiver != null) {
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
receiver = null;
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(MESSAGE_FROM_SERVICE_KEY, serviceMessageView.getText().toString());
}
public void onStartServiceClicked(View view) {
startService(new Intent(this, BroadcastSenderIntentService.class));
}
}
activity_main.xml
Voici le layout de notre activité
principale. Nous avons ici un textview et un bouton.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
tools_context=".MainActivity">
<TextView
android_id="@+id/headerLabel"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_alignParentTop="true"
android_layout_centerHorizontal="true"
android_fontFamily="casual"
android_text="LocalBroadcastReceiver"
android_textAllCaps="true"
android_textSize="24sp"
android_textStyle="bold" />
<LinearLayout
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_centerHorizontal="true"
android_layout_centerVertical="true"
android_gravity="center"
android_orientation="vertical" >
<TextView
android_id="@+id/textView1"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_text="@string/service_status"
android_textSize="16dp" />
<TextView
android_id="@+id/service_message_textview"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_text="@string/not_running"
android_textSize="16dp" />
</LinearLayout>
<Button
android_id="@+id/button1"
android_onClick="onStartServiceClicked"
android_text="@string/start_service"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_alignParentBottom="true"
android_layout_centerHorizontal="true"
android_layout_marginBottom="12dp"
android_fontFamily="serif-monospace" />
</RelativeLayout>
AndroidManifest.xml
Dans nos manifes android, il faut s'assurer que nous enregistrons le service
. Voici le mien :
<?xml version="1.0" encoding="utf-8"?>
<manifest
package="info.camposha.localbroadcastandintentservice">
<application
android_allowBackup="true"
android_icon="@mipmap/ic_launcher"
android_label="@string/app_name"
android_roundIcon="@mipmap/ic_launcher_round"
android_supportsRtl="true"
android_theme="@style/AppTheme">
<activity android_name=".MainActivity">
<intent-filter>
<action android_name="android.intent.action.MAIN" />
<category android_name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android_name=".BroadcastSenderIntentService" />
</application>
</manifest>
Exemple de LocalBroadcastManager
en Kotlin
Un exemple kotlin AndroidX localbroadcastmanager avec IntentService
et BroadcastReceiver
.
Regardez le tutoriel vidéo ici :
Étape 1 : Ajouter les dépendances
Ajouter AndroiX localbroadcastmanager comme une dépendance dans votre fichier gradle :
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
Étape 2 : Conception de la mise en page
Concevez une mise en page avec un textvew et un bouton :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/dateText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Initial value"
android:textSize="20dp"
android:textStyle="bold"/>
<Button
android:id="@+id/startButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="Start Service"/>
</LinearLayout>
Step 3 : Créer IntentService
Nous créons une classe intentservice puis surchargeons la méthode onHandleIntent :
package info.camposha.ms_localbroadcastmanager
import android.app.IntentService
import android.content.Intent
import android.util.Log
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import java.util.*
//IntentService is a ntentService is a base class for Services that handle asynchronous
// requests (expressed as Intents) on demand.
class MyIntentService : IntentService("MyIntentService") {
override fun onHandleIntent(arg0: Intent?) {
val intent = Intent(CUSTOM_ACTION)
//get date to send
intent.putExtra("DATE", Date().toString())
Log.d(MyIntentService::class.java.simpleName, "sending broadcast")
// send local broadcast
//LocalBroadcastManager is a Helper to register for and send broadcasts of Intents
// to local objects within your process.
LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
}
companion object {
const val CUSTOM_ACTION = "YOUR_CUSTOM_ACTION"
}
}
Step 4 : Créer MainActivity
Nous créons notre lanceur activity
:
package info.camposha.ms_localbroadcastmanager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import kotlinx.android.synthetic.main.activity_main.*
//Our main activity
class MainActivity : AppCompatActivity(), View.OnClickListener {
//override onCreate
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
startButton.setOnClickListener(this)
}
//when activity is paused
override fun onPause() {
super.onPause()
// unregister local broadcast
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver)
}
//when activity is resumed
override fun onResume() {
super.onResume()
// register local broadcast
val filter = IntentFilter(MyIntentService.CUSTOM_ACTION)
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filter)
}
/**
Create a BroadcastReceiver
* BroadcastReceiver is a Base class for code that will receive intents sent by sendBroadcast().
* Broadcast receiver to receive the data
*/
private val mReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val date = intent.getStringExtra("DATE")
dateText.text = date
}
}
//when user clicks the start button, start our intent service
override fun onClick(view: View) {
if (view.id == R.id.startButton) {
// start intent service
val intent = Intent(this, MyIntentService::class.java)
startService(intent)
}
}
}
Étape 5 : Enregistrement des composants
Enregistrez deux composants dans le fichier android manifext :
- MainActivity
IntentService
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyIntentService"/>
Étape 6 : Exécuter
Exécutez le projet et vous obtiendrez ce qui suit :
Télécharger le code
Téléchargez le code ici.