Présentation de Linkify

Linkify est une classe auxiliaire qui crée des liens hypertexte au sein des classes Vue de texte (et dérivées de la Vue de texte) par correspondance de modèle RegEx. Les liens hypertextes fonctionnent en créant de nouvelles intentions qui sont utilisées pour démarrer une nouvelle activité lorsque l'utilisateur clique sur le lien. Le texte correspondant à un modèle RegEx spécifié sera converti en un lien hypertexte cliquable déclenchant implicitement startActivity (nouvelle intention (Intent.ACTION_VIEW, uri)), en utilisant le texte correspondant comme adresse URI cible.Vous pouvez spécifier n'importe quel modèle de chaîne à traiter comme un lien cliquable. pour plus de commodité, la classe Linkify fournit des préréglages pour les types de contenu courants. 

Types de lien Linkify natifs

 La classe Linkify a des préréglages capables de détecter et de lier les URL Web, les adresses électroniques, les adresses de carte et les numéros de téléphone. Pour appliquer un préréglage, utilisez la méthode Linkify.addLinks statique en transmettant une vue à Linkify et un masque binaire d'une ou plusieurs des constantes suivantes de la classe Linkify auto-descriptives: WEB_URLS, EMAIL_ADDRESSES, PHONE_NUMBERS, MAP_ADDRESSES et ALL.

  1. TextView textView = findViewById(R.id.myTextView);
  2. Linkify.addLinks(textView, Linkify.WEB_URLS|Linkify.EMAIL_ADDRESSES);

 Vous pouvez également lier des vues directement dans une mise en page à l'aide de l'attribut android: autoLink. Il prend en charge une ou plusieurs des valeurs suivantes: none, Web, email, téléphone, carte, etc.

 

  1. Introducing Linkify
  2. < TextView
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:text="@string/linkify_me"
  6. android:autoLink="phone|email" />

 Création de chaînes de liens personnalisées

Pour lier vos propres données, vous devez définir vos propres chaînes linkify. Pour ce faire, créez un nouveau motif RegEx qui correspond au texte que vous souhaitez afficher sous forme de liens hypertexte. Comme pour les types natifs, vous pouvez lier la vue texte cible en appelant Linkify.addLinks; Cependant, plutôt que de transmettre l'une des constantes prédéfinies, transmettez votre modèle RegEx. Vous pouvez également transmettre un préfixe qui sera ajouté à l'URI cible lors du clic sur un lien. Le Listing 6-12 montre une vue en cours de liaison pour prendre en charge les données sismiques fournies par un fournisseur de contenu Android. Notez que plutôt que d'inclure l'ensemble du schéma, le RegEx spécifié correspond à tout texte commençant par «quake» et suivi d'un nombre, avec des espaces facultatifs. Le schéma complet est ensuite ajouté à l'URI avant que l'intention ne soit déclenchée.

 LISTING 6-12: Création de chaînes de liens personnalisées dans Linkify

 

  1. // Define the base URI.
  2. String baseUri = "content://com.paad.earthquake/earthquakes/";
  3. // Construct an Intent to test if there is an Activity capable of
  4. // viewing the content you are Linkifying.
  5. Use the Package Manager
  6. // to perform the test.
  7. PackageManager pm = getPackageManager();
  8. Intent testIntent = new Intent(Intent.ACTION_VIEW,Uri.parse(baseUri));
  9. boolean activityExists = testIntent.resolveActivity(pm) != null;
  10. // If there is an Activity capable of viewing the content
  11. // Linkify the text. if (activityExists) {
  12. int flags = Pattern.CASE_INSENSITIVE;
  13. Pattern p = Pattern.compile("\\bquake[\\s]?[0-9]+\\b", flags);
  14. Linkify.addLinks(myTextView, p, baseUri);
  15. }
  16.  

Notez que dans cet exemple, y compris les espaces entre «quake» et un nombre retournera une correspondance, mais l’URI résultant ne sera pas valide. Vous pouvez implémenter et spécifier une ou les deux interfaces TransformFilter et MatchFilter pour résoudre ce problème. Ces interfaces, définies en détail dans la section suivante, offrent un contrôle supplémentaire sur la structure d'URI cible et la définition des chaînes correspondantes. Elles sont utilisées comme dans le code de squelette suivant:

 

  1. Linkify.addLinks(myTextView, p,baseUri,new MyMatchFilter(),new MyTransformFilter());

 Utilisation du filtre de correspondance Pour ajouter des conditions supplémentaires aux correspondances de modèle RegEx, implémentez la méthode acceptMatch dans un filtre de correspondance. Quand une correspondance potentielle est trouvée, acceptMatch est déclenchée, les index de début et de fin de la correspondance (ainsi que le texte intégral faisant l'objet de la recherche) étant transmis en tant que paramètres. 

Listing 6-13 montre une implémentation de MatchFilter qui annule toute correspondance immédiatement précédée d'un point d'exclamation.

 

  1. class MyMatchFilter implements MatchFilter {
  2. public boolean acceptMatch(CharSequence s, int start, int end) {
  3. return (start == 0 || s.charAt(start-1) != '!');
  4. }
  5. }

Utilisation du filtre de transformation 

Le filtre de transformation vous permet de modifier l'URI implicite généré par le texte du lien correspondant. Découpler le texte du lien de l'URI cible vous donne plus de liberté pour afficher les chaînes de données à vos utilisateurs.Pour utiliser le filtre de transformation, implémentez la méthode transformUrl dans votre filtre de transformation. Lorsque Linkify trouve une correspondance réussie, il appelle transformUrl en lui transmettant le modèle RegEx utilisé et la chaîne de texte correspondante (avant l'ajout de l'URI de base). Vous pouvez modifier la chaîne correspondante et la renvoyer de telle sorte qu'elle puisse être ajoutée à la chaîne de base en tant que données pour un objectif de vue.

 Comme indiqué dans le Listing 6-14, l’implémentation TransformFilter transforme le texte correspondant en unURI en minuscule, après avoir également supprimé les caractères d'espacement.

 

  1. class MyTransformFilter implements TransformFilter {
  2. public String transformUrl(Matcher match, String url) {
  3. return url.toLowerCase().replace(" ", "");
  4. }
  5. }

Utilisation Des Intents Pour Les Événements De Diffusion 

Jusqu'à présent, nous avons utilisé Intents pour démarrer de nouveaux composants d'application, mais vous pouvez également utiliser Intents pour diffuser des messages entre composants à l'aide de la méthode sendBroadcast.En tant que mécanisme de transmission de messages au niveau système, Intents peut envoyer des messages structurés au-delà des limites du processus. Par conséquent, vous pouvez implémenter les récepteurs de diffusion pour écouter les intentions de diffusion de votre application et y répondre, pour vos propres émissions ainsi que celles d'autres applications ou du système lui-même.Android diffuse de manière intensive pour annoncer des événements système, tels que des modifications de la connectivité réseau, de l'état d'ancrage et des appels entrants.    

Diffusion d'événements avec intentions

 Dans votre application, construisez l'intention que vous souhaitez diffuser et utilisez la méthode sendBroadcast pour l'envoyer. Comme pour les intentions utilisées pour démarrer les activités, vous pouvez diffuser une intention explicite ou implicite.Les intentions explicites indiquent la classe du récepteur de diffusion que vous souhaitez déclencher, alors que les intentions implicites spécifient l'action, les données et la catégorie de votre intention de manière à permettre aux récepteurs de diffusion potentiels de déterminer avec précision leur intérêt. Les émissions à intention implicite sont particulièrement utiles lorsque plusieurs récepteurs sont des cibles potentielles pour une diffusion. Pour les intentions implicites, la chaîne d'action est utilisée pour identifier le type d'événement en cours de diffusion. Il doit donc s'agir d'une chaîne unique identifiant le type d'événement. Par convention, les chaînes d'action sont construites à l'aide du même formulaire que les noms de package Java:

  1. public static final String NEW_LIFEFORM_ACTION = "com.professionalandroid.alien.action.NEW_LIFEFORM_ACTION";

 Si vous souhaitez inclure des données dans l’intention, vous pouvez spécifier un URI à l’aide de la propriété data de l’intention. Vous pouvez également inclure des extras pour ajouter des valeurs primitives supplémentaires. Considérés en termes de paradigme axé sur les événements, les extras correspondent à des paramètres facultatifs transmis à un gestionnaire d'événements. Le Listing 6-15 montre la création de base d'intentions de diffusion explicites et implicites, cette dernière utilisant l'action définie précédemment avec des informations d'événement supplémentaires stockées en tant qu'extras.

 

  1. Intent explicitIntent = new Intent(this, MyBroadcastReceiver.class); intent.putExtra(LifeformDetectedReceiver.EXTRA_LIFEFORM_NAME, detectedLifeform);
  2. intent.putExtra(LifeformDetectedReceiver.EXTRA_LATITUDE, mLatitude);
  3. intent.putExtra(LifeformDetectedReceiver.EXTRA_LONGITUDE, mLongitude); sendBroadcast(explicitIntent);
  4. Intent intent = new Intent(LifeformDetectedReceiver.NEW_LIFEFORM_ACTION);
  5. intent.putExtra(LifeformDetectedReceiver.EXTRA_LIFEFORM_NAME, detectedLifeform);
  6. intent.putExtra(LifeformDetectedReceiver.EXTRA_LATITUDE, mLatitude);
  7. intent.putExtra(LifeformDetectedReceiver.EXTRA_LONGITUDE, mLongitude); sendBroadcast(intent);

 L'intention explicite ne sera reçue que par la classe MyBroadcastReceiver indiquée, alors que l'intention implicite pourrait potentiellement être reçue par plusieurs récepteurs.

 Écoute pour les émissions d'intention avec les récepteurs de diffusion

 Les récepteurs de diffusion (généralement appelés récepteurs) sont utilisés pour écouter les intentions de diffusion. Pour qu'un récepteur puisse recevoir des émissions, il doit être enregistré, que ce soit en code ou dans le manifeste de l'application (ce dernier cas est appelé récepteur du manifeste). Pour créer un nouveau récepteur de diffusion, étendez la classe BroadcastReceiver et remplacez le gestionnaire d'événements onReceive: 

 

  1. import android.content.BroadcastReceiver;
  2. import android.content.Context; import android.content.Intent;
  3. public class MyBroadcastReceiver extends BroadcastReceiver {
  4. @Override
  5. public void onReceive(Context context, Intent intent) {
  6. //TODO: React to the Intent received.
  7. }
  8. }

 Lorsqu'une intention de diffusion est démarrée, la méthode onReceive sera exécutée sur l'application principale Thread. Tout travail non trivial doit être effectué de manière asynchrone après l'appel de goAsync, comme décrit au Chapitre 11, «Travail en arrière-plan». Dans tous les cas, tous les traitements dans le récepteur de radiodiffusion doivent être terminés dans un délai de 10 secondes ou le système le considérera comme ne répondant pas et tentera de le terminer. Pour éviter cela, les récepteurs de diffusion planifient généralement un travail en arrière-plan ou lancent un service lié pour lancer des tâches potentiellement longues. Il peut également mettre à jour l'interface utilisateur d'activité mère ou déclencher une notification pour informer l'utilisateur des modifications reçues. Le Listing 6-16 montre comment implémenter un récepteur de radiodiffusion qui extrait les données et plusieurs extras de l'objectif de diffusion et les utilise pour déclencher une notification. Dans les sections suivantes, vous apprendrez à l'inscrire dans le code ou dans le manifeste de votre application.

 LISTING 6-16: Mise en œuvre d'un récepteur de diffusion

 

  1. public class LifeformDetectedReceiver
  2. extends BroadcastReceiver {
  3. public static final String NEW_LIFEFORM_ACTION = "com.professionalandroid.alien.action.NEW_LIFEFORM_ACTION";
  4. public static final String EXTRA_LIFEFORM_NAME = "EXTRA_LIFEFORM_NAME";
  5. public static final String EXTRA_LATITUDE = "EXTRA_LATITUDE";
  6. public static final String EXTRA_LONGITUDE = "EXTRA_LONGITUDE";
  7. public static final String FACE_HUGGER = "facehugger";
  8. private static final int NOTIFICATION_ID = 1;
  9. @Override
  10. public void onReceive(Context context, Intent intent) {
  11. // Get the lifeform details from the intent.
  12. String type = intent.getStringExtra(EXTRA_LIFEFORM_NAME);
  13. double lat = intent.getDoubleExtra(EXTRA_LATITUDE, Double.NaN);
  14. double lng = intent.getDoubleExtra(EXTRA_LONGITUDE, Double.NaN);
  15. if (type.equals(FACE_HUGGER)) {
  16. NotificationManagerCompat notificationManager =
  17. NotificationManagerCompat.from(context);
  18. NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
  19. builder.setSmallIcon(R.drawable.ic_alien).setContentTitle("Face Hugger Detected").setContentText(Double.isNaN(lat) || Double.isNaN(lng) ? "Location Unknown" : "Located at " + lat + "," + lng);
  20. notificationManager.notify(NOTIFICATION_ID, builder.build());
  21. }
  22. }
  23. }

 Enregistrement de récepteurs de diffusion dans le code

 Les récepteurs de diffusion qui répondent aux émissions envoyées à partir de votre propre application et ceux qui modifient l'interface utilisateur d'une activité sont généralement enregistrés de manière dynamique dans le code. Un récepteur enregistré par programme peut répondre aux intentions de diffusion uniquement lorsque le composant d'application dans lequel il est enregistré est en cours d'exécution. Cela est utile lorsque le comportement du récepteur est étroitement lié à un composant particulier, par exemple un composant qui met à jour les éléments d'interface utilisateur d'une activité. Dans ce cas, il est judicieux d’enregistrer le récepteur dans le gestionnaire onStart et de le désenregistrer pendant onStop. Le Listing 6-17 montre comment enregistrer et désenregistrer un récepteur de radiodiffusion en code à l'aide duClasse IntentFilter qui définit une action associée à une diffusion implicite à laquelle le récepteur doit répondre.

 LISTING 6-17: Enregistrement et désenregistrement d'un récepteur de radiodiffusion dans le code

 

  1. private IntentFilter filter = new IntentFilter(LifeformDetectedReceiver.NEW_LIFEFORM_ACTION);
  2. private LifeformDetectedReceiver receiver = new LifeformDetectedReceiver();
  3. @Override
  4. public void onStart() {
  5. super.onStart();
  6. // Register the broadcast receiver.
  7. registerReceiver(receiver, filter);
  8. }
  9. @Override
  10. public void onStop() {
  11. // Unregister the receiver unregisterReceiver(receiver);
  12. super.onStop(); }


Enregistrement de récepteurs de diffusion dans votre manifeste d'application

 Les récepteurs de diffusion enregistrés statiquement dans votre manifeste d’application sont toujours actifs et recevront des intentions de diffusion même lorsque votre application a été supprimée ou n’a pas été lancée; votre application sera lancée automatiquement lorsqu'une intention correspondante est diffusée. Pour inclure un récepteur de diffusion dans le manifeste de l'application, ajoutez une balise de récepteur dans le nœud de l'application, en spécifiant le nom de classe du récepteur de diffusion à enregistrer:

< receiver android:name=".LifeformDetectedReceiver"/ >

 Avant Android 8.0 Oreo (API de niveau 26), il était possible pour les récepteurs manifestes d'inclure une balise intentfilter spécifiant une action permettant de prendre en charge l'écoute d'émissions implicites:

 

  1. < receiver android:name=".LifeformDetectedReceiver" >
  2. <intent-filter>
  3. <action android:name="com.professionalandroid.alien.action.NEW_LIFEFORM_ACTION"
  4. />
  5. </intent-filter>
  6. < /receiver >

 Les récepteurs de manifeste vous permettent de créer des applications pilotées par les événements qui répondront aux événements de diffusion même après la fermeture ou la suppression de votre application. Toutefois, il introduit également des risques associés à l'utilisation des ressources. Si une intention est diffusée fréquemment, votre application risque de se réactiver à plusieurs reprises, ce qui pourrait entraîner une perte importante de la batterie. Pour minimiser ce risque, Android 8.0 ne prend plus en charge les récepteurs récepteurs pour les intentions implicites arbitraires. Les applications peuvent continuer à s'inscrire pour des diffusions explicites dans leurs manifestes. Vous pouvez également inscrire des récepteurs à l'exécution pour toute diffusion, implicite ou explicite. Toutefois, seul un nombre limité d'actions du système de diffusion peut être utilisé pour enregistrer une intention implicite dans votre manifeste. Les actions prises en charge sont décrites plus loin dans ce chapitre, dans la section «Surveillance des modifications de l'état du périphérique via les intentions de diffusion».

 Gestion des destinataires du manifeste au moment de l'exécution

 À l'aide du gestionnaire de packages, vous pouvez activer et désactiver les récepteurs du manifeste de votre application lors de l'exécution à l'aide de la méthode setComponentEnabledSetting. Vous pouvez utiliser cette technique pour activer ou désactiver tout composant d'application (y compris les activités et les services), mais cela s'avère particulièrement utile pour les récepteurs manifestes. Pour minimiser l’épuisement potentiel de la batterie causé par votre application, il est recommandé de désactiver les récepteurs manifestes qui écoutent les événements système lorsque votre application n’a pas besoin de réagir. Le Listing 6-18 montre comment activer et désactiver un récepteur manifeste au moment de l'exécution.

 LISTING 6-18: Basculement dynamique des récepteurs de manifeste

 

  1. ComponentName myReceiverName = new ComponentName(this,LifeformDetectedReceiver.class);
  2. PackageManager pm = getPackageManager();
  3. // Enable a manifest receiver
  4. pm.setComponentEnabledSetting(myReceiverName,
  5. PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
  6. PackageManager.DONT_KILL_APP);
  7. // Disable a manifest receiver
  8. pm.setComponentEnabledSetting(myReceiverName,
  9. PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
  10. PackageManager.DONT_KILL_APP);

 Surveillance des changements d'état du périphérique via les intentions de diffusion

 De nombreux services système diffusés dans le but de signaler les modifications d'état du périphérique. Vous pouvez surveiller ces émissions pour ajouter des fonctionnalités à vos propres projets en fonction d'événements tels que l'achèvement du démarrage du périphérique, les modifications de fuseau horaire, les modifications de l'état du dock et de la batterie.Une liste complète des actions de diffusion utilisées et transmises de manière native par Android est disponible à l'adresse developer.android.com/reference/android/content/Intent.html. En raison des restrictions d'enregistrement des manifestes implicites manifestes introduites dans Android 8.0, seul un sous-ensemble des intentions de diffusion système peut être enregistré dans le manifeste. Vous pouvez trouver la liste des exceptions de diffusion implicites sur developer.android.com/guide/components/broadcast-exceptions.html.Les sections suivantes examinent comment créer des filtres d'intention pour enregistrer les récepteurs de diffusion pouvant réagir à certains de ces événements système et comment extraire en conséquence les informations d'état du périphérique.

 Écouter les modifications d'ancrage

Certains appareils Android peuvent être installés dans une station d'accueil pour voiture ou une station d'accueil, la station d'accueil pouvant être analogique (bas de gamme) ou numérique (haut de gamme). En enregistrant un récepteur pour écouter Intent.ACTION_DOCK_EVENT (android.intent.action .ACTION_DOCK_EVENT), vous pouvez déterminer l'état et le type d'ancrage sur les appareils prenant en charge les ancrages: <action android: name = "android.intent.action.ACTION_DOCK_EVENT" />L'événement d'intention de diffusion de l'événement d'ancrage est persistant, ce qui signifie que vous recevrez l'état actuel du quai lorsque vous appelez registerReciver, même si aucun destinataire n'est spécifié. Le Listing 6-19 montre comment extraire l'état d'ancrage actuel de l'intention renvoyée en appelant registerReceiver, à l'aide de l'intention .ACTION_DOCK_EVENT Intent. Notez que si le périphérique ne prend pas en charge la connexion, l’appel à registerReceiver retournera la valeur null.

 

  1. boolean isDocked = false;
  2. boolean isCar = false;
  3. boolean isDesk = false;
  4. IntentFilter dockIntentFilter = new IntentFilter(Intent.ACTION_DOCK_EVENT);
  5. Intent dock = registerReceiver(null,dockIntentFilter);
  6. if (dock != null) {
  7. int dockState = dock.getIntExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_UNDOCKED);
  8. isDocked = dockState != Intent.EXTRA_DOCK_STATE_UNDOCKED;
  9. isCar = dockState == Intent.EXTRA_DOCK_STATE_CAR;
  10. isDesk = dockState == Intent.EXTRA_DOCK_STATE_DESK || dockState == Intent.EXTRA_DOCK_STATE_LE_DESK || dockState == Intent.EXTRA_DOCK_STATE_HE_DESK; }

 Écoute des modifications de l'état de la batterie et de la connectivité des données

 Avant l'introduction de Job Scheduler, la raison la plus courante d'écouter les modifications de l'état de la batterie et de la connectivité des données était de retarder les téléchargements volumineux ou les processus de récupération de la batterie qui prenaient beaucoup de temps jusqu'à ce que l'appareil soit connecté à un réseau de données approprié et / ou en charge. . Le Chapitre 11, «Utilisation de l’arrière-plan», explique comment utiliser le planificateur de travaux et le répartiteur de travaux Firebase pour planifier des travaux en utilisant des critères tels que la connectivité réseau et l’état de charge de la batterie. Cette solution est plus efficace et complète que la surveillance manuelle de ces changements d’état. Pour surveiller les modifications du niveau de la batterie et de l'état de charge au sein d'une activité, vous pouvez enregistrer un récepteur à l'aide d'un filtre d'intention qui écoute l'émission Intent.ACTION_BATTERY_CHANGED par le gestionnaire de batterie. Le Listing 6-20 montre comment extraire la charge actuelle de la batterie et l’état de charge du changement d’état collant de la batterie. Intention.

 LISTING 6-20: Détermination des informations sur la batterie et l'état de charge

 

  1. IntentFilter batIntentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
  2. Intent battery = context.registerReceiver(null, batIntentFilter);

 

Présentation du gestionnaire de diffusion locale

 

  1. int status = battery.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
  2. boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL;

Note that you can’t register the battery changed action within a manifest Receiver; however, you can monitor connection and disconnection from a power source and a low battery level using the following action strings, each prefixed with android.intent.action:

  • ACTION_BATTERY_LOW
  • ACTION_BATTERY_OKAY
  • ACTION_POWER_CONNECTED
  • ACTION_POWER_DISCONNECTED

Les niveaux de charge et l’état de la batterie étant régulièrement modifiés, il est donc généralement recommandé de ne pas enregistrer les récepteurs pour écouter ces émissions, à moins que votre application ne propose des fonctionnalités spécifiquement liées à ces modifications. Pour surveiller les modifications de la connectivité réseau, enregistrez un récepteur de radiodiffusion dans votre application pour écouter l'action ConnectivityManager.CONNECTIVITY_ACTION (les applications ciblant Android 7.0 Nougat (API de niveau 24) et ultérieures ne recevront pas cette diffusion si elles déclarent le récepteur dans leur manifeste. La diffusion du changement de connectivité n’est pas collante et ne contient aucune information supplémentaire concernant le changement. Pour extraire des détails sur l'état actuel de la connectivité, vous devez utiliser le gestionnaire de connectivité, comme indiqué dans le listing 6-21.

 LISTING 6-21: Détermination des informations d'état de connectivité

 

  1. String svcName = Context.CONNECTIVITY_SERVICE;
  2. ConnectivityManager cm =(ConnectivityManager)context.getSystemService(svcName);
  3. NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
  4. boolean isConnected = activeNetwork.isConnectedOrConnecting();
  5. boolean isMobile = activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE;

Présentation du directeur de la radiodiffusion locale

La bibliothèque de support Android a été introduite dans le gestionnaire de diffusion local pour simplifier le processus d'enregistrement, d'envoi et de réception d'intentions diffusées uniquement entre les composants de votre application.En raison de la portée réduite de la diffusion, l'utilisation de Local Broadcast Manager est plus efficace que l'envoi d'une diffusion globale. Cela garantit également que l’intention que vous diffusez ne peut pas être reçue par d’autres applications, en évitant tout risque de fuite de données confidentielles ou sensibles. De même, d’autres applications ne peuvent pas transmettre d’émissions à vos récepteurs, ce qui réduit le risque que ces récepteurs deviennent des vecteurs d’explosifs de sécurité. Notez que le récepteur de radiodiffusion spécifié peut également être utilisé pour gérer les émissions globales Intent. Pour utiliser le gestionnaire de diffusion local, vous devez d'abord inclure la bibliothèque de support Android dans votre application, comme décrit au chapitre 2.

 Utilisez la méthode LocalBroadcastManager.getInstance pour renvoyer une instance du gestionnaire de diffusion locale:

  1. LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);

 Pour enregistrer un récepteur de radiodiffusion local, utilisez la méthode registerReceiver de Local Broadcast Manager, de la même manière que vous enregistrez un récepteur global en transmettant un récepteur de diffusion et un filtre d’intention, comme indiqué dans le Listing 6-22.

 LISTING 6-22: Enregistrement et désinscription d'un récepteur de diffusion local

 

  1. @Override
  2. public void onResume() {
  3. super.onResume();
  4. // Register the broadcast receiver.
  5. LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
  6. lbm.registerReceiver(receiver, filter); }
  7. @Override
  8. public void onPause() {
  9. // Unregister the receiver
  10. LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
  11. lbm.unregisterReceiver(receiver);
  12. super.onPause(); }

 Pour transmettre une intention de diffusion locale, utilisez la méthode sendBroadcast du gestionnaire de diffusion locale, en transmettant l’intention de diffuser:

  1. lbm.sendBroadcast(new Intent(LOCAL_ACTION));

 

 Local Broadcast Manager inclut également une méthode sendBroadcastSync qui fonctionne de manière synchrone, bloquant jusqu’à ce que chaque récepteur enregistré ait traité l’intention de diffusion.  

Présentation des intentions en attente

 La classe PendingIntent fournit un mécanisme permettant de créer des intentions pouvant être déclenchées plus tard par votre système, par le système ou par une autre application..Une intention en attente est généralement utilisée pour regrouper les intentions qui seront déclenchées en réponse à un événement futur, par exemple lorsqu'un utilisateur touche une notification.

 Introducing Pending Intents

 Remarque Lorsqu'elles sont utilisées, les intentions en attente exécutent l'intention fournie avec les mêmes autorisations et identités que si vous les aviez exécutées vous-même, dans votre propre application. La classe PendingIntent propose des méthodes statiques pour construire des intentions en attente utilisées pour démarrer une Activité, pour démarrer des services en arrière-plan ou au premier plan, ou pour diffuser des intentions implicites ou explicites:

 

  1. int requestCode = 0; int flags = 0;
  2. // Start an Activity
  3. Intent startActivityIntent = new Intent(this, MyActivity.class);
  4. PendingIntent.getActivity(this, requestCode, startActivityIntent, flags);
  5. // Start a Service
  6. Intent startServiceIntent = new Intent(this, MyService.class);
  7. PendingIntent.getService(this, requestCode, startServiceIntent, flags);
  8. // Start a foreground Service (API Level 26 or higher)
  9. Intent startForegroundServiceIntent = new Intent(this, MyFGService.class);
  10. PendingIntent.getForegroundService(this, requestCode, startForegroundServiceIntent flags);
  11. // Broadcast an Intent to an explicit Broadcast Receiver
  12. Intent broadcastExplicitIntent = new Intent(this, MyReceiver.class);
  13. PendingIntent.getBroadcast(this, requestCode, broadcastExplicitIntent, flags);
  14. // Broadcast an implicit Intent (API Level 25 or lower)
  15. Intent broadcastImplicitIntent = new Intent(NEW_LIFEFORM_ACTION);
  16. PendingIntent.getBroadcast(this, requestCode, broadcastImplicitIntent, flags);

 La classe PendingIntent inclut des constantes statiques qui peuvent être utilisées pour spécifier des indicateurs afin de mettre à jour ou d'annuler toute intention en attente existante correspondant à l'action spécifiée, ainsi que de spécifier si cette intention doit être déclenchée une seule fois. Les différentes options sont examinées plus en détail lorsque des notifications sont introduites au chapitre 11.  Étant donné que les intentions en attente sont déclenchées en dehors de la portée de votre application, il est important de prendre en compte le contexte de l'utilisateur lorsque ces intentions sont susceptibles d'être exécutées; une intention qui démarre une nouvelle activité ne doit être utilisée qu'en réponse à une action directe de l'utilisateur, telle que la sélection d'une notification.  Pour améliorer la durée de vie de la batterie, Android 8.0 Oreo (API, niveau 26) a imposé des limites strictes à l'exécution en arrière-plan des applications qui affectent les intentions en attente.  Depuis Android 8.0, les applications ne peuvent pas démarrer de nouveaux services d’arrière-plan si l’application elle-même est inactive en arrière-plan. Par conséquent, une intention en attente créée à l'aide de la méthode startService ne peut pas démarrer un nouveau service si l'application est en arrière-plan lorsqu'elle est déclenchée. Pour cette raison, la méthode startForegroundService a été introduite dans Android 8.0. Les intentions en attente créées à l'aide de cette méthode sont autorisées à démarrer un nouveau service qui, une fois démarré, a cinq secondes pour devenir un service de premier plan via un appel à startForeground. Dans le cas contraire, l'application sera arrêtée et l'application ne répondra pas.  Comme mentionné précédemment, Android 8.0 a également supprimé la prise en charge de l'utilisation de votre manifeste pour l'enregistrement des diffusions Intent implicites. Les intentions en attente sont généralement déclenchées lorsque votre application ne s'exécute pas. Il est donc nécessaire d'utiliser une intention explicite pour garantir le déclenchement du récepteur cible.