Utiliser Intents pour lancer des activités

L'intention la plus courante d'Intents est de connecter vos composants d'application et de communiquer entre eux. Par exemple, les intentions sont utilisées dans Activités pour démarrer de nouvelles activités, vous permettant de créer un flux de travail composé de plusieurs écrans.

 Remarque  Les instructions de cette section concernent le démarrage de nouvelles activités, mais la même approche s'applique également aux services. Des informations détaillées sur le démarrage (et la création) de services sont disponibles au chapitre 11, «Utilisation de l’arrière-plan» Pour créer et afficher une activité, appelez startActivity en transmettant une intention, comme suit:

  1. startActivity(myIntent);

 La méthode startActivity recherche et démarre l'activité unique qui correspond le mieux à votre intention. Vous pouvez construire une intention qui spécifie explicitement le démarrage d'une classe d'activité particulière ou inclure une action que l'activité cible doit pouvoir effectuer. Dans ce dernier cas, le temps d'exécution choisira dynamiquement une activité à travers la résolution de l'intention.  Lorsque vous utilisez startActivity, votre application ne reçoit aucune notification à la fin de l'activité récemment lancée. Pour suivre les commentaires d'une sous-activité, utilisez startActivityForResult, comme décrit plus loin dans ce chapitre.

 Commencer explicitement de nouvelles activités

 «Applications et activités et fragments, Oh My!», Vous avez appris que les applications sont composées d'un certain nombre d'écrans interdépendants (Activités) qui doivent être inclus dans le manifeste de l'application. Pour passer d’une activité à l’autre, vous pouvez indiquer explicitement le début d’une activité en créant une nouvelle intention, en spécifiant le contexte de l’activité en cours et la classe de l’activité à lancer. Une fois défini, transmettez cette intention à startActivity, comme indiqué dans le Listing 6-1, pour lancer la nouvelle activité.

 LISTING 6-1: Lancer explicitement une activité spécifique

  1. Intent intent = new Intent(MyActivity.this, MyOtherActivity.class); startActivity(intent);

 Une fois que startActivity a été appelée, la nouvelle activité (dans cet exemple, MyOtherActivity) est créée, démarrée et reprise - remplaçant MyActivity en haut de la pile d’activités. Lorsque vous appelez la fin de la nouvelle activité ou que vous appuyez sur le bouton de retour du matériel, la ferme et la retire de la pile. Vous pouvez également continuer à naviguer vers d'autres activités à l'aide de startActivity.  Notez que chaque fois que vous appelez startActivity, une nouvelle activité sera ajoutée à la pile. En appuyant sur retour (ou en appelant terminer), chacune de ces activités sera supprimée; Si une activité n'est pas fermée de cette manière, elle restera sur la pile pendant l'exécution de l'application. En conséquence, il est possible d’avoir plusieurs instances de la même activité dans votre pile d’activités.

 Intention implicite et liaison tardive

Une intention implicite est utilisée pour demander au système de rechercher et de démarrer une activité pouvant exécuter une action particulière, sans que vous sachiez exactement quelle application, ou quelle activité, sera démarrée. Par exemple, pour permettre aux utilisateurs de passer des appels depuis votre application, vous pouvez implémenter un nouveau numéroteur ou (si vous ne vous détestez pas), vous pouvez utiliser une intention implicite qui demande que l'action (numérotation) soit effectuée sur un numéro de téléphone ( représenté sous forme d'URI):

 

  1. if (somethingWeird && itDontLookGood) {
  2.  
  3. Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:555-2368"));
  4.  
  5. startActivity(intent); }

 Android résout cette intention en recherchant, puis en démarrant, une activité pouvant exécuter l'action de numérotation sur un URI de numéro de téléphone - dans ce cas, généralement l'application de numérotation téléphonique fournie.  Lors de la construction d'une nouvelle intention implicite, vous spécifiez une action à effectuer et l'URI des données sur lesquelles effectuer cette action. Vous pouvez envoyer des données supplémentaires à l'activité cible en ajoutant des extras à l'intention.  Les suppléments sont un mécanisme utilisé pour attacher des valeurs primitives à une intention. Vous pouvez utiliser la méthode putExtra surchargée sur n’importe quelle intention pour associer une nouvelle paire nom / valeur (NVP):

  1. intent.putExtra("STRING_EXTRA", "Beverly Hills"); intent.putExtra("INT_EXTRA", 90210);

 Les extras sont stockés dans l’intention sous la forme d’un objet Bundle, disponible à partir de l’activité démarrée à l’aide de la méthode getExtras. Vous pouvez extraire chaque valeur supplémentaire directement de l'intention à l'aide de la méthode get [type] Extra correspondante:

 

  1. Intent intent = getIntent();
  2.  
  3. String myStringExtra = intent.getStringExtra("STRING_EXTRA"); int myIntExtra = intent.getIntExtra("INT_EXTRA", DEFAULT_INT_VALUE);

 Lorsque vous utilisez une intention implicite pour démarrer une activité, Android la résoudra, au moment de l'exécution, dans la classe d'activité la mieux adaptée à l'exécution de l'action requise sur le type de données spécifié. Cela signifie que vous pouvez créer des projets qui utilisent les fonctionnalités d'autres applications sans savoir exactement quelle application vous empruntez à l'avance.  Dans les cas où plusieurs activités peuvent potentiellement effectuer une action donnée, un choix est présenté à l'utilisateur. Le processus de résolution de l’intention est déterminé par une analyse des filtres d’intention des activités, décrits en détail plus loin dans ce chapitre.  Diverses applications natives fournissent des activités capables d'effectuer des actions sur des données spécifiques. Les applications tierces, y compris les vôtres, peuvent être enregistrées pour prendre en charge de nouvelles actions ou fournir un autre fournisseur d'actions natives. Vous serez présenté à certaines des actions natives, ainsi qu'à la façon d'enregistrer vos propres activités pour les prendre en charge, plus loin dans ce chapitre.

 Déterminer si une intention résoudra

Incorporer les activités et les services d'une application tierce à votre propre est incroyablement puissant. Cependant, rien ne garantit qu'une application particulière sera installée sur un périphérique, ni même qu'une application installée est capable de traiter votre demande. Par conséquent, il est recommandé de vérifier si votre intention implicite sera résolue en activité avant de la transmettre à startActivity. Vous pouvez utiliser le gestionnaire de packages pour demander quelle activité, le cas échéant, sera lancée en réponse à une intention particulière en appelant resolActivity sur votre objet Intent, en passant par le gestionnaire de packages, comme indiqué dans le listing 6-2.

 

  1. if (somethingWeird && itDontLookGood) {
  2. // Create the implicit Intent to use to start a new Activity.
  3. Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:555-2368"));
  4. // Check if an Activity exists to perform this action.
  5. PackageManager pm = getPackageManager();
  6. ComponentName cn = intent.resolveActivity(pm);
  7. if (cn == null) {
  8. // There is no Activity available to perform the action
  9. // Log an error and modify app behavior accordingly,
  10. // typically by disabling the UI element that would allow
  11. // users to attempt this action.
  12. Log.e(TAG, "Intent could not resolve to an Activity.");
  13. } else
  14. startActivity(intent);
  15. }

Si aucune activité n'est trouvée, vous pouvez choisir de désactiver la fonctionnalité associée (et les contrôles d'interface utilisateur associés) ou de diriger les utilisateurs vers une application appropriée dans le Google Play Store. Notez que Google Play n’est pas disponible sur tous les appareils. C’est donc une bonne pratique de vérifier cela également.

 Retour des résultats des activités

Une activité lancée via startActivity est indépendante de l'activité appelante et ne fournit aucun retour à la fermeture. Lorsqu'un commentaire est requis, vous pouvez démarrer une activité en tant que sous-activité pouvant transmettre les résultats à son parent. Les sous-activités ne sont en réalité que des activités ouvertes différemment; en tant que tel, vous devez toujours les enregistrer dans le manifeste de l'application de la même manière que pour toute autre activité. Toute activité inscrite dans le manifeste peut être ouverte en tant que sous-activité, y compris celles fournies par le système ou des applications tierces. Lorsqu'une sous-activité est terminée, elle déclenche le gestionnaire d'événements onActivityResult dans l'activité parent appelante. Les sous-activités sont particulièrement utiles dans les situations où une activité fournit des données pour une autre, telle qu'un utilisateur qui remplit un formulaire ou sélectionne un élément dans une liste.

 Lancer des sous-activités

La méthode startActivityForResult fonctionne un peu comme startActivity, mais avec une différence importante. En plus de transmettre l'intention explicite ou implicite utilisée pour déterminer quelle activité à lancer, vous transmettez également un code de demande. Cette valeur sera ultérieurement utilisée pour identifier de manière unique la sous-activité qui a renvoyé un résultat. Le Listing 6-3 montre le code squelette pour lancer une sous-activité de manière explicite.

 LISTING 6-3 : Explicitly starting a sub-Activity for a result

 

  1. private static final int SHOW_SUBACTIVITY = 1;
  2. private void startSubActivity() {
  3. Intent intent = new Intent(this, MyOtherActivity.class);
  4. startActivityForResult(intent, SHOW_SUBACTIVITY);
  5. }

Comme pour les activités ordinaires, vous pouvez démarrer des sous-activités implicitement ou explicitement. Le Listing 6-4 utilise une intention implicite de lancer une nouvelle sous-activité pour choisir un contact. 

LISTING 6-4 : Implicitly starting a sub-Activity for a result

 

  1. private static final int PICK_CONTACT_SUBACTIVITY = 2;
  2. private void startSubActivityImplicitly() {
  3. // Create an Intent that requests an Activity capable
  4. // of allowing users to pick a contact.
  5. Uri uri = Uri.parse("content://contacts/people");
  6. Intent intent = new Intent(Intent.ACTION_PICK, uri);
  7. startActivityForResult(intent, PICK_CONTACT_SUBACTIVITY);
  8. }

Renvoi des résultats d'une sous-activité

Lorsque votre sous-activité est prête à être renvoyée, appelez setResult avant la fin pour renvoyer un résultat à l'activité appelante. La méthode setResult prend deux paramètres: le code de résultat et les données de résultat elles-mêmes, représentées en tant qu'intention. Le code de résultat indique le succès de l'exécution de la sous-activité, généralement l'une ou l'autre. RESULT_OK ou Activity.RESULT_CANCELED. Dans certaines circonstances, où ni le résultat obtenu, ni le résultat obtenu ne sont corrects ou annulés, vous souhaiterez utiliser vos propres codes de réponse pour gérer les choix spécifiques à l’application; setResult prend en charge toute valeur entière. Le résultat recherché comprend souvent un URI de données pointant vers un élément de contenu (tel que le contact sélectionné, le numéro de téléphone ou le fichier multimédia) et un ensemble d’extras utilisés pour renvoyer des informations supplémentaires.Le Listing 6-5, tiré de la méthode onCreate d’une sous-activité, montre comment les boutons OK et Annuler peuvent retourner des résultats différents à l’activité appelante.

 LISTING 6-5: Returning a result from a sub-Activity

 

  1. Button okButton = findViewById(R.id.ok_button);
  2. okButton.setOnClickListener(new View.OnClickListener() {
  3. public void onClick(View view) {
  4. // Create a URI that points to the currently selected item
  5. Uri selectedHorse = Uri.parse("content://horses/" + selected_horse_id);
  6. Intent result = new Intent(Intent.ACTION_PICK, selectedHorse);
  7. setResult(RESULT_OK, result);
  8. finish();
  9. }
  10. }) ;
  11. Button cancelButton = findViewById(R.id.cancel_button);
  12. cancelButton.setOnClickListener(new View.OnClickListener() {
  13. public void onClick(View view) {
  14. setResult(RESULT_CANCELED);
  15. finish();
  16. }
  17. }) ;

Si l'activité est fermée lorsque l'utilisateur appuie sur la touche de retour matérielle ou si finish est appelé sans qu'un appel à setResult n'ait été préalablement effectué, le code de résultat est défini sur RESULT_CANCELED et le résultat Intent est défini sur null.

 Gestion des résultats de sous-activité

Lorsqu'une sous-activité se ferme, le gestionnaire d'événements onActivityResult est déclenché dans l'activité appelante. Remplacez cette méthode pour gérer les résultats renvoyés par les sous-activités.

 Le gestionnaire onActivityResult reçoit un certain nombre de paramètres:

  • Request code (Code de demande): code de demande utilisé pour lancer la sous-activité renvoyée.
  • Code de résultat - Le code de résultat défini par la sous-activité pour indiquer son résultat. Il peut s'agir de n'importe quelle valeur entière, mais sera généralement soit Activity.RESULT_OK, soit Activity.RESULT_CANCELED.
  •  Données : une intention utilisée pour regrouper les données retournées. En fonction de l’objet de la sous-activationpeut contenir un URI qui représente un élément de contenu sélectionné. La sous-activité peut également renvoyer des informations en tant que suppléments dans l’intention de données renvoyée.  
  • Remarque Si la sous-activité se ferme de manière anormale ou ne spécifie pas de code de résultat avant sa fermeture, le code de résultat est Activity.RESULT_CANCELED.  

Le listing 6-6 montre le code squelette pour l'implémentation du gestionnaire d'événements onActivityResult dans une activité. 

LISTING 6-6: Implementing an On Activity Result handler

  1. private static final int SELECT_HORSE = 1;
  2. private static final int SELECT_GUN = 2;
  3. Uri selectedHorse = null;
  4. Uri selectedGun = null;
  5. @Override
  6. public void onActivityResult(int requestCode,int resultCode,Intent data) {
  7. super.onActivityResult(requestCode,resultCode,data);
  8. switch(requestCode) {
  9. case (SELECT_HORSE):
  10. if (resultCode == Activity.RESULT_OK)
  11. selectedHorse = data.getData();
  12. break;
  13. case (SELECT_GUN):
  14. if (resultCode == Activity.RESULT_OK)
  15. selectedGun = data.getData();
  16. break;
  17. default: break;
  18. }
  19. }


Utilisation d'actions natives de la plate-forme pour lancer des activités

Les applications distribuées dans le cadre de la plateforme Android utilisent également Intents pour lancer des activités et des sous-activités. La liste suivante (non exhaustive) répertorie certaines des actions natives disponibles en tant que constantes de chaîne statiques dans la classe d'intention. Lors de la création d'intentions implicites, vous pouvez utiliser ces actions, appelées intentions d'activité, pour démarrer des activités et des sous-activités au sein de vos propres applications.

Remarque Plus tard, vous découvrirez les filtres d'intention et la manière d'enregistrer vos propres activités en tant que gestionnaires pour ces actions.

  • ACTION_DELETE : lance une activité qui vous permet de supprimer les données spécifiées à l’URI de données de l’intention.
  • ACTION_DIAL : fait apparaître une application de numérotation avec le numéro à composer pré-rempli à partir de l’URI de données de l’intention. Par défaut, cela est géré par le numéroteur de téléphone Android natif. Le numéroteur peut normaliser la plupart des schémas de numéros. Par exemple, les numéros de téléphone tels que: 555-1234 et tel: (212) 555 1212 sont valables.  
  • ACTION_EDIT : demande une activité pouvant modifier les données à l’URI de données de l’intention.  
  • ACTION_INSERT : ouvre une activité capable d’insérer de nouveaux éléments dans le curseur spécifié dans l’URI de données de l’intention. Lorsqu'elle est appelée en tant que sous-activité, elle doit renvoyer un URI au nouvel élément inséré.
  • ACTION_PICK : lance une sous-activité qui vous permet de choisir un élément dans le fournisseur de contenu spécifié par l'URI de données de l'objectif. Lorsqu'il est fermé, il doit renvoyer un URI à l'élément sélectionné. L'activité lancée dépend des données collectées. Par exemple, transmettre du contenu: // contacts / people invoquera la liste de contacts native. 
  • ACTION_SEARCH : généralement utilisé pour lancer une activité de recherche spécifique. Lorsqu'il est déclenché sans activité spécifique, l'utilisateur est invité à sélectionner l'une des applications prenant en charge la recherche. Indiquez le terme de recherche sous forme de chaîne dans les options de l’intention en utilisant SearchManager.QUERY comme clé.
  • ACTION_SENDTO : lance une activité pour envoyer des données au contact spécifié par l'URI de données de l'objectif. 
  • ACTION_SEND : lance une activité qui envoie les données spécifiées dans l'intention. Le contact du destinataire doit être sélectionné par l'activité résolue. Utilisez setType pour définir le type MIME des données transmises. Les données elles-mêmes doivent être mémorisées à l'aide de la touche EXTRA_ TEXT ou EXTRA_STREAM, en fonction du type. Dans le cas de la messagerie électronique, les applications Android natives accepteront également les extras via les clés EXTRA_EMAIL, EXTRA_CC, EXTRA_BCC et EXTRA_ SUBJECT. Utilisez l'action ACTION_SEND uniquement pour envoyer des données à un destinataire distant (et non à une autre application du périphérique).
  • ACTION_VIEW : il s'agit de l'action générique la plus courante. View demande que les données fournies dans l’URI de données de l’intention soient visualisées de la manière la plus raisonnable possible. Différentes applications gèrent les demandes de vues en fonction du schéma d'URI des données fournies. Nativement http: les adresses s'ouvriront dans le navigateur; tel: les adresses ouvriront le numéroteur pour appeler le numéro; geo : les adresses seront affichées dans l'application Google Maps; et le contenu du contact sera affiché dans le gestionnaire de contacts.
  • ACTION_WEB_SEARCH : ouvre le navigateur pour effectuer une recherche Web basée sur la requête complétée.en utilisant la clé SearchManager.QUERY.

Remarque Outre ces actions d'activité, Android inclut un grand nombre d'actions de diffusion utilisées pour créer des intentions diffusées afin d'annoncer des événements système.