Android - Semaine 3
Chapitre 4: Applications avec attente de résultat,
Services et Broadcast Receivers
1 / 57 Pierre Nerzic
Android - Semaine 3
Le cours de cette semaine concerne
Application avec retour d’information
Services
Broadcast Receivers
2 / 57 Pierre Nerzic
Android - Semaine 3
Applications et
activités
Applications avec attente de résultat
3 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Lancement avec attente de résultat
Le lancement d’une activité avec attente de résultat est plus
complexe. Il faut définir un code d’appel RequestCode fourni
au lancement.
private static final int APPEL_ACTIV2 = 1;
Intent intent = new Intent(this, [Link]);
startActivityForResult(intent, APPEL_ACTIV2);
Ce code identifie l’activité lancée, afin de savoir plus tard que
c’est d’elle qu’on revient. Par exemple, on pourrait lancer au
choix plusieurs activités : édition, copie, suppression
d’informations. Il faut pouvoir les distinguer au retour.
Consulter cette page.
4 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Lancement avec attente, suite
Ensuite, il faut définir une méthode callback qui sera
appelée lorsqu’on revient dans notre activité :
@Override
protected void onActivityResult(
int requestCode, int resultCode, Intent data)
{
// uti a fait back
if (resultCode == Activity.RESULT_CANCELED)return;
// selon le code d'appel
switch (requestCode) {
case APPEL_ACTIV2: // on revient de Activ2
...
}
}
5 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Méthode onActivityResult
Cette méthode est appelée quand on revient dans l’activité
initiale :
onActivityResult(int requestCode, int resultCode,
Intent data)
requestCode est le code d’appel de
startActivityForResult
resultCode vaut soit RESULT_CANCELED soit
RESULT_OK , voir le transparent précédent
data est fourni par l’activité appelée et qui vient
de se terminer.
Ces deux dernières viennent d’un appel à
setResult(resultCode, data)
6 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Lancement avec attente, version améliorée
Les dernières versions de l’API proposent mieux pour
récupérer un résultat d’une activité lancée. On n’a plus le
couple startActivityForResult et onActivityResult , mais
ceci :
D’abord une variable du type
ActivityResultLauncher<Intent> dans l’activité. Il en
faut une par type d’action à faire au retour de l’activité
lancée. Elle représente un lanceur pour la seconde
activité.
L’initialisation de ces lanceurs dans la méthode
onCreate, Un écouteur qui sera appelé au retour de
l’activité lancée, Le lancement de l’activité dans ce
cadre.
7 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Lanceur d’activité
Il faut commencer par définir une variable membre. Il en faut
une par activité qui sera lancée ultérieurement :
private ActivityResultLauncher<Intent> activ2Launcher;
Par exemple, cette variable activ2Launcher permettra de lancer
Activ2. Elle doit être initialisée dans onCreate() :
@Override
protected void onCreate(Bundle savedInstanceState) {
...
activ2Launcher = registerForActivityResult(
new [Link](),
this::onActiv2Ended);
L’écriture this::nomMeth est appelée référence de méthode,
8 / 57 voir page 55. C’est le nom de la méthode à appelerPierre
auNerzic
Android - Semaine 3
Applications
Écouteur de retour d’activité
Il faut maintenant définir la méthode en
questionvoid
private : onActiv2Ended(ActivityResult result) {
if ([Link]() == RESULT_CANCELED)return;
// TODO actions à faire au retour d'Activ2
}
Elle ressemble à onActivityResult mais ses paramètres sont
dans un objet ActivityResult et on utilise ses getters.
Pour finir, le lancement de Activ2 :
Intent intent = new Intent(this, [Link]);
[Link](intent);
Au retour de Activ2, la méthode onActiv2Ended sera
appelée automatiquement.
9 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Transport d’informations dans un Intent
Les Intent servent aussi à transporter des informations
d’une activité à l’autre : les extras.
Voici comment placer des données dans un Intent :
Intent intent =
new Intent(this, [Link]);
[Link]("idInfo", idInfo);
[Link]("hiddencopy", hiddencopy);
startActivity(intent);
putExtra(nom, valeur) rajoute un couple (nom, valeur)
dans l’intent. La valeur doit être sérialisable : nombres,
chaînes et structures simples.
10 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Extraction d’informations d’un Intent
Ces instructions récupèrent les données d’un
Intent intent
Intent : = getIntent();
Integer idInfo = [Link]("idInfo", -1);
bool hidden = [Link]("hiddencopy", false);
getIntent() retourne l’Intent qui a démarré cette
activité. getTypeExtra(nom, valeur par défaut) retourne
la valeur de ce nom si elle en fait partie, la valeur par
défaut sinon.
Il est très recommandé de placer les chaînes dans des
constantes,
public staticdans
finalla String
classe EXTRA_IDINFO
appelée : = "idInfo";
public static final String EXTRA_HIDDEN = "hiddencopy";
11 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Contexte d’application
Pour finir sur les applications, il faut savoir qu’il y a un objet
global vivant pendant tout le fonctionnement d’une
application : le contexte d’application. Voici comment le
récupérer
Application: context = [Link]();
Par défaut, c’est un objet neutre ne contenant que des
informations Android.
Il est possible de le sous-classer afin de stocker des variables
globales de l’application.
12 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Définition d’un contexte d’application
Pour commencer, dériver une sous-classe de
Application :
public class MonApplication extends Application
{
// variable globale de l'application
private int varglob;
public int getVarGlob() { return varglob; }
// initialisation du contexte
@Override public void onCreate() {
[Link]();
varglob = 3;
}}
13 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Définition d’un contexte d’application, suite
Ensuite, la déclarer dans [Link] , dans
l’attribut android:name de l’élément <application> , mettre
un point devant :
<manifest xmlns:android="..." ...>
<application android:name=".MonApplication"
android:icon="@drawable/icon"
android:label="@string/app_name">
...
14 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Définition d’un contexte d’application, fin
Enfin, l’utiliser dans n’importe laquelle des
activités :
// récupérer le contexte d'application
MonApplication context =
(MonApplication) [Link]();
// utiliser la variable globale
... [Link]() ...
Remarquez la conversion de type du
contexte.
15 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Exemple : Calculatrice
Dans ce qui suit nous proposons de programmer une calculatrice
tout en exploitant pour chaque opérateur
1. Le lancement d’un Intent avec attente de résultat
2. L’aller et retour d’information entre deux activités
16 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Ecrans Calculatrice et Résultat de notre Calculatrice
Activité 1 appelle Activité 2 fait le Activité 1 reçoit le
activité 2 en lui calcul affiche le résultat de l’activité
envoyant les deux résultat. 2 et l’affiche
valeurs de la Le bouton CALLBACK
multiplication et transporte le résultat
reste en attente à l’activité 1 en
attente
17 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Extrait d’[Link] (btnMultiplier)
18 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Extrait d’[Link] (réception calcul et transport résultat)
19 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Extrait d’[Link] (réception de résultat)
20 / 57 Pierre Nerzic
Android - Semaine 3
Vues et activités
Vues et activités
21 / 57 Pierre Nerzic
Android - Semaine 3
Vues et activités
Définition d’un écouteur
Il y a une autre manière de définir une réponse à un clic : un
écouteur (listener), comme un EventHandler dans JavaFX.
Un écouteur est une instance de classe implémentant
l’interface [Link] qui possède la méthode
public void onClick(View v) .
Cela peut être :
une classe privée anonyme,
une classe privée ou publique dans
l’activité, l’activité elle-même.
Dans tous les cas, on fournit cette instance en paramètre
à la méthode setOnClickListener du bouton :
Button btn = [Link];
[Link](ecouteur);
22 / 57 Pierre Nerzic
Android - Semaine 3
Vues et activités
Écouteur privé anonyme
Il s’agit d’une classe qui est définie à la volée, lors de
l’appel à
setOnClickListener . Elle ne contient qu’une seule
Button
méthode. btn = [Link];
[Link](
new [Link]() {
public void onClick(View btn) {
// faire quelque chose
}
});
Dans la méthode onClick, il faut employer la syntaxe
[Link] pour manipuler les variables et
méthodes de l’activité sous-jacente.
23 / 57 Pierre Nerzic
Android - Semaine 3
Vues et activités
Écouteur privé anonyme, suite
Il est intéressant de transformer cet écouteur en expression
lambda. C’est une écriture plus compacte qu’on retrouve
également en JavaScript, et très largement employée en
Kotlin.
Button btn = [Link];
[Link]((View btn) -> {
// faire quelque chose
});
Une lambda est une fonction sans nom écrite ainsi :
(paramètres avec ou sans types) -> expression
(paramètres avec ou sans types) -> { corps }
Cette transformation de l’écouteur est possible parce que
l’interface
24 / 57 [Link] ne possède qu’une seule méthode.
Pierre Nerzic
Android - Semaine 3
Vues et activités
Écouteur privé
Cela consiste à définir une classe privée dans l’activité ; cette
classe implémente l’interface OnClickListener ; et à en
fournir une instance en tant qu’écouteur.
private class EcBtnValider implements [Link] {
public void onClick(View btn) {
// faire quelque chose
}
};
public void onCreate(...) {
...
Button btn = [Link];
[Link](new EcBtnValider());
}
25 / 57 Pierre Nerzic
Android - Semaine 3
Vues et activités
L’activité elle-même en tant qu’écouteur
Il suffit de mentionner this comme écouteur et d’indiquer
qu’elle implémente l’interface OnClickListener .
public class EditActivity extends Activity
implements [Link] {
public void onCreate(...) {
...
Button btn = [Link];
[Link](this);
}
public void onClick(View btn) {
// faire quelque chose
}
26 / 57
Ici, par contre, tous les boutons appelleront la même
Pierre Nerzic
Android - Semaine 3
Vues et activités
Distinction des émetteurs
Dans le cas où le même écouteur est employé pour plusieurs
vues, il faut les distinguer en se basant sur leur identifiant
obtenu avec getId() :
public void onClick(View v) {
switch ([Link]()) {
case [Link].btn_valider:
...
break;
case [Link].btn_effacer:
...
break;
}
}
27 / 57 Pierre Nerzic
Android - Semaine 3
Vues et activités
Distinction des émetteurs, suite
Depuis peu, les identifiants de ressources ne sont plus des
constantes et ne peuvent plus être employés dans des
switch. On doit faire ainsi :
public void onClick(View v) {
int id = [Link]();
if (id == [Link].btn_valider) {
...
} else if (id == [Link].btn_effacer) {
...
}
}
28 / 57 Pierre Nerzic
Android - Semaine 3
Vues et activités
Écouteur référence de méthode
Il y a une dernière façon très pratique d’associer un écouteur,
avec une référence de méthode, c’est à dire son nom
précédé de l’objet qui la définit :
public void onCreate(...) {
...
Button btn = [Link];
[Link](this::onBtnClicked);
}
private void onBtnClicked(View btn) {
// faire quelque chose
}
La syntaxe this::nom_methode est une simplification
29 / 57 de l’expression lambda (params) -> Pierre Nerzic
Android - Semaine 3
Vues et activités
Événements des vues courantes
Vous devrez étudier la documentation. Voici quelques
exemples :
Button : onClick lorsqu’on appuie sur le bouton, voir sa
doc Spinner : OnItemSelected quand on choisit un
élément, voir sa doc
RatingBar : OnRatingBarChange quand on modifie la
note, voir sa doc
etc.
Heureusement, dans le cas de formulaires, les actions
sont majoritairement basées sur des boutons.
30 / 57 Pierre Nerzic
Android - Semaine 3
Vues et activités
Services
31 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Objectifs des Services
Un service ?
une composante essentielle d'une application.
Nous utilisons les service pour effectuer des opérations ou des
calculs en dehors de l'interaction utilisateur. Donc un service
ne dispose pas d'interface graphique.
Exemples lecteur de musique, diagnostic et analyse de données
(meta), recherche du meilleur chemin vers une destination (google
maps)…
Nous pouvons les programmer à l'aide des services.
Les services peuvent être lancés
1. depuis l’application à laquelle ils appartiennent
2. à distance depuis un programme tiers (le calcul peut se
faire par un ou plusieurs serveurs, une ou plusieurs super
32 / 57 machines). Pierre Nerzic
Android - Semaine 3
Applications
Définition Service
Un service est une activité sans écran.
Il est possible de programmer les services dans des processus
threads.
⇒ Plusieurs services peuvent être lancés en parallèle.
La notion de service est à la base de plusieurs architectures
logicielles.
1. L’architecture microservices
2. L’architecture orientée services
3. …
33 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Cycle de vie d’un Service
34 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Exemple : ServiceDemo
Dans ce qui suit nous proposons la démonstration d’un service
proposant des nombre aléatoire et un deuxième retourne des
notifications. Pour la programmation nous allons utiliser
1. La classe intentservice
2. la classe service
35 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Ecran ServiceDemo application
Activité 1 appelle Activité 1 reçoit le
activité 2 en lui résultat de l’activité
Ces quatre
envoyant les services
deux 2 et l’affiche
peuvent être
valeurs de la Démonstration de
lancés par ces
multiplication et l’exécution du
quatre
reste en boutons
attente service : quatre
nombres aléatoires
36 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Extrait de [Link] (lancement des 2 services)
37 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Extrait de [Link] (Créer la classe myService)
38 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Extrait de [Link] (onCreate, onStart, onDestroy)
39 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Exemple : BechEttaya7ni Service
Dans ce qui suit nous proposons une application BechEttaya7ni.
1. Notre application lancera automatiquement un service
sensor (MySensorService).
2. Notre service détecte si l’appareil est en mouvement
vertical.
3. Dans ce cas, BechEttaya7ni service lance une alerte
sonore (un enregistrement .mp3)
40 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Ecran de notre application BechEttaya7ni
41 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Extrait de [Link]
42 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Exemple : ManagerDeJobs
Dans ce qui suit nous proposons la démonstration de quatre Lobs
services: WorkerA, WorkerParameters, WorkerB et WorkerC
(extended from Worker service) tel que
1. WorkerA (durée 60 secondes) et WorkerB (durée 50
secondes) sont lancés en parallèle.
2. WorkerC démarre que lorsque A et B sont terminés tous
les deux (sa durée est de 10 secondes).
3. Le statut de chacun de ces trois services est récupéré et
affiché par MainActivity (En utilisant binding)
4. WorkerParameters calcule une valeur et la retourne à
MainActivity pour l’afficher (En utilisant binding)
Cette application sera mise à votre disposition pour la tester et la
modifier selon votre besoin
43 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Ecran de notre application ManagerDeJobs
44 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Extrait de [Link]
45 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Extrait de [Link]
46 / 57 Worker B et C sont de même en modifiant la durée de ces jobs
Pierre Nerzic
Android - Semaine 3
Applications
Exercice
1. Télécharger les applications BechEttaya7ni et
ManagerDeJobs
2. Exécuter ces deux applications sur votre mobile
3. Ajouter des commentaires explicatives pour le lancement de
chaque service.
4. Expliquer le retour de résultat d’un service
5. Modifier ces applications pour autres usages.
47 / 57 Pierre Nerzic
Android - Semaine 3
Vues et activités
Le Bus de messages (BroadcastReceiver)
48 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Objectifs de BroadcastReceiver
BroadcastReceiver ?
Un composant permettant de communiquer avec d’autres
composants déjà lancés par un signal (notification) qui est
envoyé à toutes les applications sur chaque changement de son
état. Il est lancé par une intention.
Exemples notification de batterie faible, de gps activé, de wifi
disponible.
49 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Notification de batterie par BroadcastReceiver
50 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Exemple de BroadcastReceiver: SignalStatiqueDynamique
Dans ce qui suit nous allons présenter l’application
SignalStatiqueDynamique.
Cette application vous présente deux démonstrations de
BroadcastReceiver :
1. Envoyer un signal statique (de l’application
SignalStatiqueDynamique)
2. Envoyer un signal dynamique (de l’application courante en
cours d'exécution)
51 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Exemple SignalStatiqueDynamique
52 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Extrait de MainActivity
53 / 57 Pierre Nerzic
Android - Semaine 3
Applications
Extrait de MyReceiver
54 / 57 Pierre Nerzic
Android - Semaine 3
Vues et activités
C’est fini pour aujourd’hui
C’est assez pour cette semaine, rendez-vous la semaine
prochaine pour un cours sur les applications de gestion de
données (listes d’items).
Plus tard, nous verrons comment Android raffine la notion
d’activité, en la séparant en fragments.
55 / 57 Pierre Nerzic