Vous êtes sur la page 1sur 37

Développement Applications Mobiles

Ch4. Le modèle de composants


-. .-
NAVIGATION ENTRE ACTIVITÉS

walid.zeddini@gmail.com

www.zeddini.com
Objectifs
Une des caractéristiques d’Android est son approche fortement modulaire qui permet
aux applications de collaborer entre elles. Une application est constituée de plusieurs
composants, chacun de ces composants pouvant être réutilisé depuis une autre
application ce qui évite ainsi de devoir réinventer la roue.
Ce chapitre traite de ce modèle d’architecture, les différents types de composants, la
façon de les invoquer et leur cycle de vie sont passés en revue.

Ressources :
http://developer.android.com/ tout, tout, tout
Cours, TD/TP, code http://www.u-picardie.fr/ferment/android
http://www.vogella.com/android.html tutoriel
http://saigeethamn.blogspot.fr/ tutoriel
http://www.franck-simon.com cours tres complet
l'Art du developpement, M. Murphy, Pearson livre simplePro Android 4, S
Komatineni D MacLean, Apress livre complet
Le livre écrit par Florent Garin « Android »
Le livre de Mark Murphy chez Pearson
Le cours de Victor Matos :
http://grail.cba.csuohio.edu/~matos/notes/cis-493/Android-Syllabus.pdf
Plusieurs livres :
Android A Programmers Guide - McGraw Hill
Professional Android Application Development - Wrox

2
4.1 UNE FORTE MODULARITÉ
Il y a plus d’une dizaine d’années, l’avènement des langages objets a fait naître
l’espoir de pouvoir développer facilement des éléments de code réutilisables d’une
application à l’autre. Malheureusement, si le paradigme objet, avec des notions telles
que l’encapsulation, favorise la création de librairies, il n’en demeure pas moins que
développer une portion de code réellement exploitable dans un contexte autre que
celui d’origine n’est toujours pas chose aisée.
Pour faciliter la collaboration entre les éléments de programme, le modèle
applicatif d’Android définit la notion de composants d’applications. Un composant
est un module de l’application qui pourra être activé depuis un autre programme
Android. Lorsqu’un module est activé, l’application à laquelle il appartient est lancée
si nécessaire, il est donc exécuté dans son propre processus.
Les fonctionnalités du module sont donc réutilisées en mettant en œuvre des
communications interprocessus.

4.2 QUATRE FAMILLES DE COMPOSANTS


Android prévoit quatre catégories de composants :
• les objets de la classe Activity,
• les objets de la classe Service,
• les objets de la classe BroadcastReceiver,
• et enfin les objets du type ContentProvider.

Les objets de ces types sont donc des morceaux de l’application qui pourront être
invoqués par d’autres applications pour remplir une tâche précise. C’est un peu comme
si le programme avait un point d’entrée officiel, celui de l’activité principale qui se
lance lorsque l’utilisateur clique sur l’icône de l’application, et des points d’entrée
alternatifs démarrés par d’autres programmes.

4.3 LA NAVIGATION ENTRE ACTIVITÉS


Les activités sont des composants centraux des applications. Ce sont également les
composants les plus remarquables car ils portent les éléments visuels de l’interface
utilisateur agencés sur l’écran.
La navigation entre les écrans peut se faire de deux façons différentes : soit
explicitement, soit implicitement. Dans les deux cas, l’ordre de changement d’activité
est véhiculé par un objet de type Intent (intention en anglais).
Dans le mode explicite, les activités s’enchaînent les unes aux autres par invocation

3
directe. C’est-à-dire qu’une activité donnée déclenche l’affichage d’une autre activité
en appelant la méthode startActivity avec un Intent mentionnant clairement le nom
de l’activité. On verra par la suite comment créer concrètement des objets Intent.
Le mode explicite est donc très classique : comme dans la plupart des applications,
les écrans à afficher sont invariablement les mêmes d’une exécution à l’autre et identi-
fiés à l’avance. Aucune particularité n’est à noter dans ce mode de fonctionnement si
ce n’est qu’Android permet d’afficher des activités n’appartenant pas à l’application
d’origine.
Le mode implicite par contre est une spécificité d’Android extrêmement puissante.
Dans ce mode, le nom de l’activité n’est pas précisé nominativement. L’objet Intent qui
encapsule la demande de changement ne porte pas l’identification de l’activité mais
un descriptif des caractéristiques ou plutôt des capacités de traitement dont l’activité
devra être dotée. Ensuite, une mécanique de résolution se met en marche, Android
recherche dans tout le système, et non pas uniquement dans l’application courante, les
activités répondant aux exigences exprimées dans l’Intent. À la fin de cet algorithme,
l’activité identifiée s’affiche alors. Au cas où il y aurait plusieurs activités en mesure
d’assurer le service demandé, leur liste est proposée à l’utilisateur qui devra alors en
sélectionner une. Il peut arriver aussi qu’aucune activité ne puisse couvrir le besoin.
Si cela se produit, une exception est alors lancée.

4.3.1 L’objet Intent


L’objet au cœur du dispositif de la navigation des écrans est l’Intent qui informe des
« intentions » de l’activité sur le traitement suivant à réaliser. Un Intent est composé
de trois attributs essentiels qui participent à l’identification de l’activité à afficher :
• Action
• Data/Type
• Category

L’action est une chaîne de caractères qui symbolise le traitement à


déclencher. De nombreuses constantes sont définies dans le SDK pour les
actions nativement disponibles. Parmi elles, on peut citer à titre d’exemple
Intent.ACTION_WEB_SEARCH pour demander de réaliser une recherche sur
Internet ou encore Intent.ACTION_CALL pour passer un appel téléphonique.
L’attribut Data est une donnée qui détaille l’action de l’Intent dont elle dépend
directement. Elle peut être d’ailleurs nulle, certaines actions n’appelant pas forcément
à devoir être précisées. Pour illustration, dans l’exemple ACTION_CALL, l’attribut
Data sera le numéro de téléphone à composer.
L’attribut Data est couplé avec un autre attribut qui est le type MIME de la
donnée à traiter. En principe, on spécifie soit le type soit la « data ». L’appel à la
méthode setType(String) efface l’attribut data qui aurait pu être renseigné par la
méthode setData(Uri) et réciproquement. La raison de cela est que dans la majorité
des cas, le type MIME peut être déterminé en fonction du data. Si on souhaite
malgré tout explicitement fixer le type MIME de la donnée, il faut utiliser la méthode

4
setDataAndType(Uri,String).
On pourrait se demander pourquoi renseigner le type si on ne fournit pas de
donnée. La réponse est que l’activité appelée et appelante communiquent dans les
deux sens. L’intention (Intent) est créée par l’activité de départ et transmise à la
suivante. Celle-ci a aussi la possibilité de retourner des données, toujours transportées
par un objet de type Intent, à la première activité. On peut donc imaginer que l’Intent
initial ne contienne pas de data mais seulement le type MIME souhaité pour le format
de la réponse.
La catégorie, quant à elle, apporte une classification à l’action. La catégorie
Intent.CATEGORY_LAUNCHER positionne l’activité comme étant exécutable,
cette catégorie est utilisée de pair avec l’action Intent.ACTION_MAIN. Android
positionne les activités de cette catégorie dans le lanceur d’applications. La catégorie
CATEGORY_HOME marque l’activité à afficher au démarrage du téléphone.
L’objet Intent possède également d’autres attributs tels que les flags et les extras. Ces
attributs sont d’autres possibilités de transmission d’informations à l’activité appelée.
Ces attributs sont néanmoins accessoires dans la mesure où ils n’entrent pas en compte
dans le processus de recherche de l’activité cible.

Une application Android pourrait inclure n'importe quel nombre d'activités.


• Une activité utilise le setContentView (...) méthode pour exposer (en général) une interface
utilisateur unique à partir de laquelle un certain nombre d'actions pourrait être effectué.
• Les activités sont indépendantes les unes des autres, mais ils coopèrent généralement par
l’échange des données et des actions.
• En règle générale, l'une des activités est désignée comme la première (principale) qui doit
être présentée à l'utilisateur lorsque l'application est lancée.
• Le passage d'une activité à l'autre se fait en demandant à la l'activité en cours d'exécution
d'une intention.
• Les Activités interagissent les uns avec les autres dans un mode asynchrone.

5
Les intentions sont invoquées avec des options suivantes :

from: http://code.google.com/android/reference/android/content/Intent.html

Les principaux arguments d'une intention sont les suivants:


1. Action : L'action intégré (built-in) pour être réalisé, tels comme ACTION_VIEW,
ACTION_EDIT, ACTION_MAIN, ... ou créé par l'utilisateur : user-created-activity
2. Data : Les données primaires pour fonctionner sur, par exemple un numéro de téléphone à
appeler (exprimée en Uri).

Typiquement l'intention est appelée comme suit:


Intent myActivity = new Intent (action, data);

startActivity (myActivity);

action Les données primaires


intégrée ou (comme URI)
activité créé par tel :/ /
l'user http://

6
Examples de pairs action/data sont :

from: http://code.google.com/android/reference/android/content/Intent.html

ACTIONS INTÉGRÉES STANDARD (BUILT‐IN STANDARD ACTIONS)Liste


des actions standard que les intentions peuvent utiliser pour les activités de lancement
(généralement par le biais startActivity (intention).
ACTION_MAIN
ACTION_VIEW
ACTION_ATTACH_DATA
ACTION_EDIT
ACTION_PICK
ACTION_CHOOSER
ACTION_GET_CONTENT
ACTION DIAL
ACTION_ANSWER
ACTION_INSERT
ACTION_DELETE
ACTION_RUN
ACTION_SYNC
ACTION_PICK_ACTIVITY
ACTION_SEARCH
ACTION WEB SEARCH
ACTION_ACTION_CALL
ACTION_SEND
ACTION_SENDTO
ACTION_WEB_ACTION_FACTORY_TEST

7
Pour la liste des actions voir:
http://developer.android.com/reference/android/content/Intent.html

ACTION_AIRPLANE_MODE_CHANGED ACTION_ALL_APPS ACTION_ANSWER


ACTION_ATTACH_DATA ACTION_BATTERY_CHANGED ACTION_BATTERY_LOW
ACTION_EDIT ACTION_EXTERNAL_APPLICATIONS_AVAILABLE ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE
ACTION_FACTORY_TEST ACTION_GET_CONTENT ACTION_GTALK_SERVICE_CONNECTED
ACTION_MEDIA_SCANNER_STARTED ACTION_MEDIA_SHARED ACTION_MEDIA_UNMOUNTABLE
ACTION_MEDIA_UNMOUNTED ACTION_MY_PACKAGE_REPLACED ACTION_NEW_OUTGOING_CALL
ACTION_SCREEN_OFF ACTION_SCREEN_ON ACTION_SEARCH
ACTION_SEARCH_LONG_PRESS ACTION_SEND ACTION_SENDTO
ACTION_BATTERY_OKAY ACTION_BOOT_COMPLETED ACTION_BUG_REPORT
ACTION_CALL ACTION_CALL_BUTTON ACTION_CAMERA_BUTTON
ACTION_CHOOSER ACTION_CLOSE_SYSTEM_DIALOGS ACTION_CONFIGURATION_CHANGED
ACTION_GTALK_SERVICE_DISCONNECTED ACTION_HEADSET_PLUG ACTION_INPUT_METHOD_CHANGED
ACTION_INSERT ACTION_INSERT_OR_EDIT ACTION_LOCALE_CHANGED
ACTION_MAIN ACTION_MANAGE_PACKAGE_STORAGE ACTION_MEDIA_BAD_REMOVAL
ACTION_PACKAGE_ADDED ACTION_PACKAGE_CHANGED ACTION_PACKAGE_DATA_CLEARED
ACTION_PACKAGE_FIRST_LAUNCH ACTION_PACKAGE_INSTALL ACTION_PACKAGE_REMOVED
ACTION_PACKAGE_REPLACED ACTION_PACKAGE_RESTARTED ACTION_PASTE
ACTION_SEND_MULTIPLE ACTION_SET_WALLPAPER ACTION_SHUTDOWN
ACTION_SYNC ACTION_SYSTEM_TUTORIAL ACTION_TIMEZONE_CHANGED
ACTION_TIME_CHANGED ACTION_TIME_TICK ACTION_UID_REMOVED
ACTION_CREATE_SHORTCUT ACTION_DATE_CHANGED ACTION_DEFAULT
ACTION_DELETE ACTION_DEVICE_STORAGE_LOW ACTION_DEVICE_STORAGE_OK
ACTION_DIAL ACTION_DOCK_EVENT ACTION_MEDIA_BUTTON
ACTION_MEDIA_CHECKING ACTION_MEDIA_EJECT ACTION_MEDIA_MOUNTED
ACTION_MEDIA_NOFS ACTION_MEDIA_REMOVED ACTION_MEDIA_SCANNER_FINISHED
ACTION_MEDIA_SCANNER_SCAN_FILE ACTION_PICK ACTION_PICK_ACTIVITY
ACTION_POWER_CONNECTED ACTION_POWER_DISCONNECTED ACTION_POWER_USAGE_SUMMARY
ACTION_PROVIDER_CHANGED ACTION_REBOOT ACTION_RUN
ACTION_UMS_CONNECTED ACTION_UMS_DISCONNECTED ACTION_USER_PRESENT
ACTION_VIEW ACTION_VOICE_COMMAND ACTION_WALLPAPER_CHANGED
ACTION_WEB_SEARCH

Les Attributs secondaires d’une Intention:


En plus des attributs primaires action/data (principaux arguments), il existe un nombre
d'attributs secondaires que vous pouvez également inclure avec un Intent, par exemple:
1. Category
2. Components
3. Type
4. Extras

8
ACTIONS INTÉGRÉES STANDARD BROADCAST
Liste des actions standard que les intentions peuvent utiliser pour la réception des Broadcast
(généralement par registerReceiver (BroadcastReceiver, IntentFilter) ou une balise
<receiver>dans le manifeste) :

ACTION_TIME_TICK
ACTION_TIME_CHANGED
ACTION_TIMEZONE_CHANGED
ACTION_BOOT_COMPLETED
ACTION_PACKAGE_ADDED
ACTION_PACKAGE_CHANGED
ACTION PACKAGE REMOVED
ACTION_PACKAGE_ACTION_UID_REMOVED
ACTION_BATTERY_CHANGED

« Un exemple valant mieux qu’un


long discours »
Exemple complet 1:
Une Activity1 affiche une interface pour accepter un numéro de téléphone et demande à une
Activity2 (intégré) pour faire l'appel

Avec 20123456 est le N° de téléphone


d’un contact déjà enregistré

9
Tag XML :
<?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:orientation="vertical" >

<TextView
android:id="@+id/label1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#ff0000cc"
android:text="@string/lb"
android:textSize="20sp"
android:textStyle="bold" />

<EditText
android:id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="54dp"
android:text="tel:5554-20123456"
android:inputType="text" />

<Button
android:id="@+id/btnPickContact"
android:layout_width="149dp"
android:layout_height="wrap_content"
android:text="@string/bt" >
</Button>
</LinearLayout>

10
La classe MainActivity.java
package tn.rnu.isi.intentdemo1;

import android.os.Bundle;
import android.app.Activity;
import android.view.View.OnClickListener;
import android.content.Intent;
import android.net.Uri;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {


TextView label1;
EditText text1;
Button btnCallActivity2;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
setContentView(R.layout.activity_main);
label1 = (TextView) findViewById(R.id.label1);
text1 = (EditText) findViewById(R.id.text1);
btnCallActivity2 = (Button)
findViewById(R.id.btnPickContact);
btnCallActivity2.setOnClickListener(new ClickHandler());
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_LONG).show();
}
}

private class ClickHandler implements OnClickListener {


@Override
public void onClick(View v) {
try {
// myActivity2 palce un appel téléphonique
// pour ACTION_CALL ou ACTION_DIAL
// utilise 'tel:' data formatté: "tel:555-20123456"
// pour ACTION_VIEW utilise data: "http://www.youtube.com"
// (On a besoin aussi INTERNET permission - Manifest)
String myData = text1.getText().toString();
Intent myActivity2 = new Intent(Intent.ACTION_DIAL,
Uri.parse(myData));
startActivity(myActivity2);

} catch (Exception e) {
label1.setText(e.getMessage());
}
}// onClick
}// ClickHandler

}// MainActivity

11
1- Appeler immédiatement

String myData = "tel:20123456";


Intent myActivity2 = new Intent(Intent.ACTION_CALL,
Uri.parse(myData));
startActivity(myActivity2);

Il ne faut pas oublier d’ajouter les permissions nécessaires dans le fichier


manifeste :
<uses-permission
android:name="android.permission.CALL_PHONE" >
</uses-permission>

2- Afficher tous les contacts


Modifier l' Exemple complet 1 en remplaçant la méthode
"clickHandler" par le code suivant :

String myData = "content://contacts/people/";


Intent myActivity2 = new Intent(Intent.ACTION_VIEW,
Uri.parse(myData));
startActivity(myActivity2);

3- Afficher un contact particulier


Modifier l' Exemple complet 1 en remplaçant la méthode
"clickHandler" par le code suivant :

String myData = "content://contacts/people/2";


Intent myActivity2 = new Intent(Intent.ACTION_VIEW,
Uri.parse(myData));
startActivity(myActivity2);

4- Editer un contact particulier


Modifier l' Exemple complet 1 en remplaçant la méthode
"clickHandler" par le code suivant :

String myData = "content://contacts/people/2";


Intent myActivity2 = new Intent(Intent.ACTION_EDIT,
Uri.parse(myData));
startActivity(myActivity2);

12
5- Faire une recherche sur Google à la recherche des associations tunisiennes
Modifier l' Exemple complet 1 en remplaçant la méthode "clickHandler" par le code
suivant :

Intent intent = new Intent (Intent.ACTION_WEB_SEARCH );

intent.putExtra(SearchManager.QUERY,
"associations tunisiennes ");
startActivity(intent);

Data Secondaire

6- Envoi d'un message texte (en utilisant des attributs


supplémentaires)
“address”, “sms_body” sont des mot clé
Modifier l' Exemple complet 1 en remplaçant la méthode
"clickHandler" par le code suivant :

Intent intent = new Intent( Intent.ACTION_SENDTO,


Uri.parse("sms:5551234"));
intent.putExtra("sms_body", "Vous allez au stade?");
startActivity(intent);

7- Afficher photos (à l'aide des attributs supplémentaires)


Modifier l' Exemple complet 1 en remplaçant la méthode
"clickHandler" par le code suivant :

Intent myIntent = new Intent();


myIntent.setType("image/pictures/*");
myIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivity(myIntent);

13
8- Voir une page web
Modifier l' Exemple complet 1 en remplaçant la méthode
"clickHandler" par le code suivant :

String myData = "http://www.youTube.com";


Intent myActivity2 = new Intent(Intent.ACTION_VIEW,
Uri.parse(myData));
startActivity(myActivity2);

Il ne faut pas oublier d’ajouter les permissions nécessaires dans le


fichier manifeste :
<uses-permission
android:name="android.permission.INTERNET " >
</uses-permission>

9- Géolocalisation par coordonnées Long/Lat


Modifier l' Exemple complet 1 en remplaçant la méthode
"clickHandler" par le code suivant :

String geoCode ="geo:41.5020952,-81.6789717";


Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse(geoCode));
startActivity(intent);
Il ne faut pas oublier d’ajouter les permissions nécessaires dans le fichier manifeste :
<uses-permission android:name="
android.permission.ACCESS_COARSE_LOCATION " >
</uses-permission>
10- Lancer Music player
Modifier l' Exemple complet 1 en remplaçant la méthode
"clickHandler" par le code suivant :

Intent myActivity2 = new


Intent("android.intent.action.MUSIC_PLAYER");
startActivity(myActivity2);

11- Ecouter Music SD


Modifier l' Exemple complet 1 en remplaçant la méthode "clickHandler" par le code
suivant :

// écouter une chanson "tiratata.mp3" sauvegardé sur la


carte SD
Intent myActivity2 =
new Intent(android.content.Intent.ACTION_VIEW);
Uri data = Uri.parse("file:///sdcard/tiratata.mp3");
String type = "audio/mp3";
myActivity2.setDataAndType(data, type);
startActivity(myActivity2);

14
12- Envoyer Email
Modifier l' Exemple complet 1 en remplaçant la méthode "clickHandler" par le code
suivant :

Uri uri = Uri.parse("mailto:mariem.zeddini@isi.rnu.tn");


Intent myActivity2 = new Intent(Intent.ACTION_SENDTO, uri);
// On peut sauter les deux étapes [subject/text]
myActivity2.putExtra(Intent.EXTRA_SUBJECT,
"subject sera ici");
myActivity2.putExtra(Intent.EXTRA_TEXT,
"Le corps de l'email ici");
startActivity(myActivity2);

13- “Paramètres” du Système


Modifier l' Exemple complet 1 en remplaçant la méthode "clickHandler"
par le code suivant :

Intent intent = new


Intent(android.provider.Settings.ACTION_SETTINGS);
startActivity(intent);

14- “Paramètres Régionaux” du Système


Modifier l' Exemple complet 1 en remplaçant la méthode "clickHandler" par le code
suivant :

Intent intent = new Intent(


android.provider.Settings.ACTION_LOCALE_SETTINGS);
startActivity(intent);

15
Démarrage des activités et obtenir des résultats
La méthode startActivity (intention) est utilisée pour démarrer une nouvelle activité, qui sera
placé au sommet de la pile de l'activité. L’appelant continue, cependant, à exécuter dans son
propre thread.
Parfois, vous voulez obtenir un résultat en retour de la dite sous-activité lorsqu'elle se
termine.
Par exemple, vous pouvez démarrer une activité qui permet à l'utilisateur de choisir une
personne à partir d'une liste de contacts; lorsqu'elle se termine, elle retourne la personne qui a
été sélectionné.

Afin d'obtenir des résultats retour de la dite activité, nous utilisons la méthode :
startActivityForResult ( Intent, requestCodeID )

Où requestCodeID est une valeur arbitraire que vous choisissez pour identifier l'appel.
Le résultat envoyé par la sous-activité pourrait être repris par le Listener comme méthode
asynchrone.
onActivityResult (requestCodeID, resultCode, Intent )
Avant qu’une activité invoquée, quitte ou sort, elle peut appeler SetResult(resultCode) pour
renvoyer un signal de terminaison à l'activité parente.
• Il est commode de fournir un code de résultat, qui peut être des résultats standard :
Activity.RESULT_CANCELED, Activity.RESULT_OK, ou des valeurs personnalisés.
• Toutes ces informations peuvent être renvoyées au parent avec la méthode :
onActivityResult (int requestCodeID, int resultCode, Intention data)
• Si une activité enfant échoue pour une raison quelconque (comme un crash), l'activité
parente recevra un résultat avec le code RESULT_CANCELED.

16
Exemple complet 2:
1. Afficher tous les contacts et en choisir un particulier (Intent. ACTION_PICK).
2. Pour une interaction réussie, l'activité principale accepte l'URI renvoyé identifiant la
personne que nous voulons appeler (contenu :/ / contacts / people / n).
3. Afficher l'entrée du contact sélectionné permettant de faire des appels, envoyer des SMS,
emailing (Intent.ACTION_VIEW).

Main Activity Intent.ACTION_PICK Intent.ACTION_VIEW

Placer l’appel Terminer l’appel URI du contact sélectionné

17
Intent.ACTION_PICK
2
Activity‐1 Activité-2 Intégrée
Uri des Contacts
(Afficher de la liste des
contacts)
Activité Appeler
Principale de Intent.ACTION_VIEW Envoyer SMS
l’User Activité-3 Intégrée Envoyer E-mail
(Afficher le contact
sélectionné)

Tag XML :
<?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:orientation="vertical" >

<TextView
android:id="@+id/label1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#ff0000cc"
android:text="Activité Intent"
android:textSize="20sp"
android:textStyle="bold" />

<EditText
android:id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="54px"
android:text="content://contacts/people/"
android:textSize="18sp" />

<Button
android:id="@+id/btnPickContact"
android:layout_width="149px"
android:layout_height="wrap_content"
android:text="Sélectionner Contact" >
</Button>
</LinearLayout>

18
La classe IntentDemo2.java
package tn.rnu.isi.intentdemo2;

import android.os.Bundle;
import android.app.Activity;
import android.view.View.OnClickListener;
import android.content.Intent;
import android.net.Uri;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class IntentDemo2 extends Activity {


TextView label1;
EditText text1;
Button btnCallActivity2;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
setContentView(R.layout.activity_intent_demo2);
label1 = (TextView) findViewById(R.id.label1);
text1 = (EditText) findViewById(R.id.text1);
btnCallActivity2 = (Button) findViewById(R.id.btnPickContact);
btnCallActivity2.setOnClickListener(new ClickHandler());
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_LONG)
.show();
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
//utiliser requestCode pour savoir qui va communiquer, de nouveau
// avec nous
switch (requestCode) {
case (222): {
// 222 C'est notre activité amicale contact sélecteur
if (resultCode == Activity.RESULT_OK) {
String selectedContact = data.getDataString();
// On retourne un URI qui ressemble à:
// content://contacts/people/n
// où n est l’ID du contact sélectionné
label1.setText(selectedContact.toString());

19
// montre unécran avec le contact sélectionné
Intent myAct3 = new Intent(Intent.ACTION_VIEW,
Uri.parse(selectedContact));
startActivity(myAct3);
} else {
// utilisateur a appuyé sur la touche BACK
label1.setText("Selection CANCELLED " + requestCode + " "
+ resultCode);
}
break;
}
}// switch
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_LONG)
.show();
}

}// onActivityResult

private class ClickHandler implements OnClickListener {


@Override
public void onClick(View v) {
try {
// myData se refère à : content://contacts/people/
String myData = text1.getText().toString();
// vous pouvez également essayer ACTION_VIEW
Intent myActivity2 = new Intent(Intent.ACTION_PICK,
Uri.parse(myData));
// démarrer myActivity2.
// Dites-lui que notre requestCodeID (ou pseudo) est de 222
startActivityForResult(myActivity2, 222);
// Toast.makeText(getApplicationContext(),
// "Je ne peux pas attendre", 1).show();
} catch (Exception e) {
label1.setText(e.getMessage());
}
}// onClick
}// ClickHandler

}// IntentDemo2

20
Exemple complet 3:
Affichage des photos et vidéo - Appel d’une sous-activité, la réception des résultats.

La classe IntentDemo3.java
package tn.rnu.isi.intentdemo3;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.widget.Toast;

public class IntentDemo3 extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_intent_demo3);
showVideosImages();
}

private void showVideosImages() {


Intent myIntent = new Intent();
// tous les videos et les images
myIntent.setType("video/*, images/*");
myIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(myIntent, 0);
}// showVideosImages

@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if ((requestCode == 0) && (resultCode == Activity.RESULT_OK)) {
String selectedImage = intent.getDataString();
Toast.makeText(this, selectedImage, 1).show();
Intent myAct3 = new Intent(Intent.ACTION_VIEW,
Uri.parse(selectedImage));
startActivity(myAct3);
}
}// onActivityResult
} // IntentDemo3

21
Exemple complet 4:
Affichage / Lecture de pistes sonores - Appel d’une sous-activité, la réception des résultats.
La classe IntentDemo4.java
package tn.rnu.isi.intentdemo3;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.widget.Toast;

public class IntentDemo4 extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_intent_demo4);
showSoundTracks();
}

private void showSoundTracks() {


Intent myIntent = new Intent();
myIntent.setType("audio/mp3");
myIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(myIntent, 0);
}//showSoundTracks

@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if ((requestCode == 0) && (resultCode == Activity.RESULT_OK)) {
String selectedTrack = intent.getDataString();
Toast.makeText(this, selectedTrack, 1).show();
Intent myAct3 = new Intent(Intent.ACTION_VIEW,
Uri.parse(selectedTrack));
startActivity(myAct3);
}
}// onActivityResult
}//IntentDemo4

22
Retenons
Une activité présente habituellement une seule interface utilisateur visuelle à partir de
laquelle un certain nombre d'actions pourrait être effectué.
Le passage d'une activité à l'autre est accompli par avoir l'activité courante lancer la
suivante à travers des intents.

4.3.2 Bundles (packs) Android


La plupart des langages de programmation supportent la notion de méthode IPC1-appel
avec des arguments circulant bi-directionnellement de l'appelant à la méthode appelée.
Dans android l'appel de l'activité est issu d’une invocation à une autre activité à l'aide
d'un Objet Intent.
Notamment dans Android, l'appelant ne cesse pas d'attendre l'activité appelée pour
renvoyer les résultats. A sa place, une méthode d’écouter le (Listener)
[onActivityResult (...)] devrait être utilisée.
Le conteneur Bundle Android est un mécanisme simple utilisé pour transmettre
des données entre activités.
Un Bundle est une collection de type sécurisé de paires <valeur , nom>.
Il ya un ensemble de méthodes de putXXX et getXXX pour stocker et
récupérer (simple et array) des valeurs de types de données primitifs de / vers
les paquets (bundles). Par exemple :

Bundle myBundle = new Bundle();


myBundle.putDouble ("var1", 3.1415);
...
Double v1 = myBundle.getDouble("var1");

1
Inter-Process Communication
23
24
Android Bundles http://developer.android.com/reference/android/os/Bundle.html
Example des Méthodes publiques
void clear()
Removes all elements from the mapping of this Bundle.
Object clone()
Clones the current Bundle.
boolean containsKey(String key)
Returns true if the given key is contained in the mapping of this Bundle.
void putIntArray(String key, int[] value)
Inserts an int array value into the mapping of this Bundle, replacing any
existing value for the given key.
void putString(String key, String value)
Inserts a String value into the mapping of this Bundle, replacing any existing
value for the given key.
void putStringArray(String key, String[] value)
Inserts a String array value into the mapping of this Bundle, replacing any
existing value for the given key.
void putStringArrayList(String key, ArrayList<String> value)
Inserts an ArrayList value into the mapping of this Bundle, replacing any
existing value for the given key.
void remove(String key)
Removes any entry with the given key from the mapping of this Bundle.
int size()
Returns the number of mappings contained in this Bundle.

25
Exemple complet 5:
Activity1 recueille deux valeurs de son interface utilisateur et appelle Activity2 pour calculer
la somme d'eux. Le résultat est renvoyé de l'Activity 2 à Activity1.

Etape 1. Créer GUI pour Activity1 (main1.xml)

Tag XML : main1.xml


<?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:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#ff0000ff"
android:text="Activity1"
android:textSize="22sp" />
<EditText
android:id="@+id/EditText01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="Première valeur (double signé)"
android:inputType="numberDecimal|numberSigned|number" />
<EditText
android:id="@+id/EditText02"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="Seconde valeur (un entier positif)"
android:inputType="number" />
<Button
android:id="@+id/btnAdd" L'élément android:inputType
android:layout_width="wrap_content" indique que la première valeur peut
android:layout_height="wrap_content" être numérique, avec en option
android:text="Additionner" />
<TextView
décimales et signe.
android:id="@+id/TextView01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#ff0000ff"
android:text="La somme est..."
android:textSize="28sp" />
</LinearLayout>

26
Etape 2. Créer GUI pour Activity2 (main2.xml)

Tag XML : main2.xml


<?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:background="#ff888888"
android:orientation="vertical" >

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#ff0000ff"
android:text="Activity2"
android:textSize="22sp" />

<EditText
android:id="@+id/etDataReceived"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Donnée reçu..." />

<Button
android:id="@+id/btnDone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fait ‐ Callback" />

</LinearLayout>

Etape 3. Dans l’Activity1 : Après avoir cliqué sur le bouton des données, de l'interface
utilisateur est placé dans un paquet et envoyé à Activity2. Un listener reste attentif attendre des
résultats à venir de l'activité appelée.

27
package tn.rnu.isi.intentbundledemo;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

//Activity 1: obtenir deux valeurs entrées par l'utilisateur,


//les mettre dans un bourdons.
//appeler Activity2 à ajouter les deux chiffres,
//montrer résultat

public class Activity1 extends Activity {


EditText txtVal1;
EditText txtVal2;
TextView lblResult;
Button btnAdd;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main1);
txtVal1 = (EditText) findViewById(R.id.EditText01);
txtVal2 = (EditText) findViewById(R.id.EditText02);
lblResult = (TextView) findViewById(R.id.TextView01);
btnAdd = (Button) findViewById(R.id.btnAdd);

btnAdd.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// obtenir des valeurs de l'interface utilisateur
Double v1 = Double.parseDouble(txtVal1.getText().toString());
Double v2 = Double.parseDouble(txtVal2.getText().toString());

// créer intent pour appeler Activity2


Intent myIntentA1A2 = new Intent(Activity1.this,Activity2.class);
// créer un conteneur pour envoyer des données
Bundle myData = new Bundle();
// ajouter des éléments données <key,value> au conteneur
myData.putDouble("val1", v1);
myData.putDouble("val2", v2);
// attacher le conteneur à l'intent
myIntentA1A2.putExtras(myData);
// Appeler Activity2 , dire au listenr local d'attendre la
// réponse
// requestCode = 101
startActivityForResult(myIntentA1A2, 101);
}
});
} // onCreate()

////////////////////////////////////////////////////////////////////////////

28
// local listener recevant callbacks (rappels) des autres activités

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
try {
if ((requestCode == 101) && (resultCode ==
Activity.RESULT_OK)) {
Bundle myResults = data.getExtras();
Double vresult = myResults.getDouble("vresult");
lblResult.setText("La somme est " + vresult);
}
} catch (Exception e) {

lblResult.setText("Problèmes :" +
requestCode +" " +resultCode);
}
}// onActivityResult
}// Activity1

Etape 4. Activity2 . Appelée à partir Activity1. Extrait des données d'entrée du paquet attaché
à l'intent. Effectue le calcul local. Ajoute le résultat bundle. Retourne signal OK.
package tn.rnu.isi.intentbundledemo;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class Activity2 extends Activity implements


OnClickListener {
EditText dataReceived;
Button btnDone;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);

dataReceived = (EditText) findViewById(R.id.etDataReceived);


btnDone = (Button) findViewById(R.id.btnDone);
btnDone.setOnClickListener(this);

// récupérer appel fait au Activity2 via Intent


Intent myLocalIntent = getIntent();
// chercher dans le tas envoyé à Activity2 des éléments de données
Bundle myBundle = myLocalIntent.getExtras();
Double v1 = myBundle.getDouble("val1");
Double v2 = myBundle.getDouble("val2");

29
// opérer sur les données d'entrée
Double vResult = v1 + v2;
// à titre d'illustration. Afficher les données reçues et le résultat
dataReceived.setText("Données reçues : \n" + "val1= " + v1 + "\nval2= "
+ v2 + "\n\nresult= " + vResult);
// ajouter au paquet le résultat calculé
myBundle.putDouble("vresult", vResult);
// oindre bourdon mis à jour pour invoquer l'intention
myLocalIntent.putExtras(myBundle);
// renvoyer en envoyant un signal OK pour appeler l'activité
setResult(Activity.RESULT_OK, myLocalIntent);
// finish();
}// onCreate

@Override
public void onClick(View v) {
//fermer l'écran en cours - fin Activity2
finish();
}// onClick
}// Activity2

Exemple 6:
Activity1 invoque Activity2 l'aide d'une intention. Un paquet contenant un ensemble de
données de différents types, il est envoyé en va-et-vient entre les deux activités

Le code Java complet et les tags XML de cet exemple se trouvent dans l’atelier
« IntentBundleSetDataType » . Nous allons juste présenter le fragment du code relatif au
bundle le PUT et le GET :

Remplir le Bundle :
private class Clicker1 implements OnClickListener {
public void onClick(View v) {
try {
// créer un Intent pour communiquer avec Activity2
Intent myIntentA1A2 = new Intent(Activity1.this,Activity2.class);

30
// preparer un Bundle et ajouter les parties data à envoyer
Bundle myData = new Bundle();
myData.putInt("myRequestCode", IPC_ID);
myData.putString("myString1", "Hello Android");
myData.putDouble("myDouble1", 3.141592);
int[] myLittleArray = { 1, 2, 3 };
myData.putIntArray("myIntArray1", myLittleArray);
// Lier le Bundle et l'Intent qui communique avec Activity2
myIntentA1A2.putExtras(myData);
// Appeler Activity2 et attendre les resultats

startActivityForResult(myIntentA1A2, IPC_ID);
}
catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_LONG).show();
}
}// onClick
}// Clicker1

Extraire du Bundle :
....
// créer un Intent local – nous avons été appelés!
myLocalIntent = getIntent();
// récupérer l'ensemble des données avec toutes les pièces envoyées à nous
Bundle myBundle = myLocalIntent.getExtras();
// extraire les parties individuel (data) du bundle
int int1 = myBundle.getInt("myRequestCode");
String str1 = myBundle.getString("myString1");
double dob1 = myBundle.getDouble("myDouble1");
int[] arr1 = myBundle.getIntArray("myIntArray1");
....

Exemple 6: Annexe A. Le bundle (regroupement) d'objets complexes


Extension de l’Exemple 6 pour permettre Activity1 de créer un objet et le transmettre à
Activity2 dans le bundle IPC en tant que données sérialisées.
Etape 1. Créer un objet Ex : Person. Assurer vous qu’il soit Serializable.
package tn.rnu.isi.intentbundlecomplexobjects;
import java.io.Serializable;
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
private String firstName;
private String lastName;
public Person(String firstName, String lastName) {
super();
this.firstName = firstName;
this.lastName = lastName; }
public String getFullName() {
return firstName + " " + lastName;
}}// Person

31
Etape 2. Modifier Activity1. Créer une instance de la classe Person et ajouter la au bundle en
utilisant la méthode putSerializable (key, object);

Remplir le Bundle par un objet:

Bundle myData = new Bundle();



Person p1 = new Person("Foulen", "Ben Felten");
myData.putSerializable("person", p1);

myIntentA1A2.putExtras(myData);
// Appeler Activity2 et attendre les resultats
startActivityForResult(myIntentA1A2, IPC_ID);

Extraire l’objet du Bundle :

Etape 2. Modifier Activity2. Récupérer l’ une instance de la classe Person du bundle en


utilisant la méthode getSerializable (key);

Bundle myBundle = myLocalIntent.getExtras();


….
Person p = (Person) myBundle.getSerializable("person");

32
4.3.2 La résolution
La résolution est le mécanisme de détermination de la ou des activités aptes à gérer
l’action exprimée par l’intention. L’algorithme repose sur la confrontation de l’objet
Intent et les IntentFilter des activités présentes sur le système Android.
Un IntentFilter est un objet rattaché à une activité par lequel cette dernière informe
publiquement de ses capacités. Cette déclaration est réalisée comme on peut s’en
douter dans le fichier manifeste.
Une activité peut définir un ou plusieurs IntentFilter, chacun étant une fonction que l’activité
peut remplir. Pour être sélectionnée, une activité devra avoir un IntentFilter remplissant à
lui seul entièrement le contrat matérialisé par l’Intent.
L’extrait suivant du manifeste déclare un unique IntentFilter pour l’activité Intent-
TesterActivity. Celui-ci possède trois actions, une catégorie et une entrée data avec le type
MIME d’indiqué :
<activity
android:name=".IntentTesterActivity"
android:label="@string/app_name" >

<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.DELETE" />
<category android:name="android.intent.category.LAUNCHER" />
<data android:mimeType="vidéo/mpeg" />
</intent-filter>

</activity>

La résolution des intentions peut se schématiser comme on le voit sur la figure 5.1.
En détail, l’algorithme compare un à un les trois attributs majeurs des intentions et des
IntentFilters que sont les actions, les data/type et les catégories.
Si la comparaison échoue sur un de ces points, la fonctionnalité représentée par l’IntentFilter
sera écartée pour incompatibilité.
Pour être valide par rapport à l’Intent, l’IntentFilter devra avoir dans sa liste des actions ,
celle qui est spécifiée dans l’Intent.
Si l’Intent n’en mentionne aucune, ce premier test sera validé à condition que
l’IntentFilter ait au moins une action.
Vient ensuite le test des catégories. Toutes les catégories référencées dans l’Intent devront
être présentes dans la déclaration de l’IntentFilter.
Bien sûr, l’IntentFilter pourra en définir d’autres encore ; Qui peut le plus peut le moins.
Toutefois, les IntentFilter devront en plus mentionner la catégorie
Intent.CATEGORY_DEFAULT car les activités lancées par la méthode
Context.startActivity sont tenues d’avoir cette catégorie.
Enfin, le test portera sur la nature des données. La logique est toujours la même : l’URI
et/ou le type MIME de l’Intent doit figurer dans la liste des objets traitables par l’activité.

33
L’IntentFilter peut recourir à l’usage de « wildcards ». Ainsi dans l’exemple de déclaration
précédent, le type MIME supporté par l’activité est « vidéo/mpeg ». Cela veut dire qu’un
Intent référençant une vidéo au format mov, dont le type MIME est « vidéo/quicktime » ne
pourra pas être passé à cette activité.

34
Par contre, si l’IntentFilter avait déclaré comme type MIME « vidéo/* », cela aurait convenu. À l’instar du type,
l’URI peut n’être définie qu’en partie au niveau du filtre :
<data android:mimeType="vidéo/*"
android:scheme="http"/>

Cette déclaration accepte toutes les vidéos accessibles par http.


<data android:mimeType="vidéo/*" android:scheme="http"
android:host="www.youtube.com” />

Et celle-ci toutes les vidéos délivrées par youtube. Plus l’URI est précisée finement dans l’IntentFilter, plus
la contrainte de sélection sera forte.
Ci-dessous, un exemple de code déclenchant l’affichage du dialer avec un numéro prérempli :
private void startDialActivity(){
Intent dial = new Intent();
dial.setAction(Intent.ACTION_DIAL);
dial.setData(Uri.parse("tel:1234567"));
startActivity(dial);
}
Le dialer est une activité native d’Android, l’exemple montre clairement que les activités peuvent
s’enchaîner sans devoir nécessairement appartenir à la même application.
Du point de vue système bas niveau, il est à souligner que l’activité dialer tourne dans son propre
processus et non pas dans celui de l’activité appelante.
Si on s’amuse à créer une activité réagissant à l’action Intent.ACTION_DIAL et à l’enregistrer tel quel dans
le système par la définition d’un IntentFilter ad hoc :

<activity android:name=".ActivityTruqee" >


<intent-filter>
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="tel" />
</intent-filter>
</activity>

Alors, à l’exécution du code précédent, comme deux activités présentes sur Android seront capables de
recevoir l’objet Intent, une boîte de dialogue demandant à l’utilisateur de trancher apparaîtra :

35
La résolution implicite est une fonctionnalité très puissante. Cependant, il est tout à fait légitime de vouloir
appeler une activité précise et avoir l’assurance qu’aucune autre activité ne pourra intervenir à la place.
Ceci arrive d’autant plus fréquemment que les activités à enchaîner se trouvent au sein de la même
application.
Pour cela, la construction de l’objet Intent doit se faire en nommant l’activité au travers des méthodes
setComponent, setClassName ou setClass :

Intent explicit = new Intent();


explicit.setClassName("tn.rnu.isi.intenttester",
"tn.rnu.isi.intenttester.ActivityTruqee ");
startActivity(explicit);

Ce qu’il faut retenir :


Comme on l’a vu auparavant, une activité A lance une activité B en lui transmettant un Intent qui est une sorte
de message contenant toutes les informations nécessaires à B pour une bonne compréhension de ce que A attend
de lui.

En sens inverse, lorsque B aura achevé son traitement, il aura sans doute des informations à fournir à A pour
rendre compte des opérations effectuées, en tout cas au minimum pour annoncer si le traitement s’est soldé par
un succès ou un échec.
Si l’activité A a démarré l’activité B par la méthode startActivity(Intent), la communication retour ne sera pas
possible. A ne sera même pas alertée de la fin de l’activité B.
Par recevoir cette notification, accompagnée éventuellement de données complémentaires, l’activité devra être
amorcée par la méthode startActivityForResult(lntent, int).
L’entier passé en plus de l’lntent est un simple code qui sera renvoyé tel quel à l’activité A lors du retour, lui
permettant d’identifier l’activité venant de s’achever.
La valeur de l’entier peut être librement choisie par l’activité émettant l’lntent, ce code est indispensable lorsque
cette activité en lance plusieurs autres car les notifications de fin sont toutes acheminées par le même canal, par
la méthode onActivityResult, il est donc crucial de pouvoir distinguer la provenance du message de retour.
La figure en bas, montre un scénario complet d’une collaboration entre deux activités. Le point de départ est le
lancement de l’lntent et le point d’arrivée est la réception de la notification de retour par la première activité.
Les flèches en pointillés reliant les deux activités indiquent clairement que le couplage entre les activités est
faible : aucune des deux ne connaît l’autre, elles communiquent par messages interposés acheminés par le
framework d’Android.

Au niveau du code source, l’étape (1) serait (dans la classe de l’activité A) :


Intent intent = new Intent();
intent.setClassName("tn.rnu.isi.intenttester",
"tn.rnu.isi.intenttester.ActivityTruqee ");
startActivityForResult(intent, TRUQUEE_REQUEST_CODE);

Avec la définition de la constante suivante (qui ne requiert pas de visibilité de type public) :
private static final int TRUQUEE_REQUEST_CODE = 0;
L’étape (2) est prise en charge par Android et non implémentée par du code applicatif. Ensuite, en (3) et (4),
dans la méthode onCreate de l’activité B, on aurait :
Intent intent = getIntent();
//...
//intent.getData();
//traitement...
//intent.setData(data);
//...
setResult(RESULT_OK, intent);
finish();

36
Enfin, la méthode onActivityResult de A s’exécute avec les informations de résultat en paramètre :
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){

if (requestCode == TRUQUEE_REQUEST_CODE) {

final TextView resultText = (TextView) findViewById(R.id.resultText);


//...
//traitement du retour
//data.getData();
//...
resultText.setText(RESULT_OK==resultCode?"Succès":"Echec") ;
//...

37

Vous aimerez peut-être aussi