INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Table des matires
1
Environnement de dveloppement ....................................................................................14
1.1
Introduction ...............................................................................................................................14
1.1.1 Android .......................................................................................................................................14
1.1.2 Dfinition....................................................................................................................................14
1.1.3 Composants dAndroid ........................................................................................................16
1.1.4 Programmation dapplications ............................................................................................16
1.2
SDK Android et Android Studio ........................................................................................16
1.2.1 SDK Android.............................................................................................................................16
1.2.2 SDK Manager ............................................................................................................................16
1.2.3 Choix des lments du SDK .................................................................................................16
1.2.4 Dossiers du SDK ......................................................................................................................17
1.2.5 Android Studio .........................................................................................................................17
1.3
Premire application ..............................................................................................................28
1.3.1 Objectifs ......................................................................................................................................28
1.3.2 Assistant de cration dapplication ....................................................................................28
1.3.3 Choix de la version ..................................................................................................................28
1.3.4 Choix de la version ..............................................................................................................28
1.3.5 Choix du type dapplication .................................................................................................28
1.3.6 Points configurer ..................................................................................................................32
1.3.7 Noms des packages et classes ..............................................................................................32
1.3.8 Rsultat de lassistant .............................................................................................................32
1.3.9 Fentre du projet ......................................................................................................................32
1.3.10
diteurs spcifiques ..................................................................................................32
1.3.11
Exemple res/values/strings.xml ............................................................................32
1.3.12
Exemple res/layout/main.xml ................................................................................26
1.3.13
Source XML sous-jacent ...........................................................................................26
1.3.14
Reconstruction du projet..........................................................................................26
1.4
Premire excution ..................................................................................................................26
1.4.1 Excution de lapplication ..................................................................................................26
1.4.2 Assistant de cration dune tablette virtuelle .................................................................26
1.4.3 Caractristiques dun AVD ...................................................................................................26
1.4.4 Lancement dune application ............................................................................................28
1.4.5 Application sur lAVD ...........................................................................................................28
1.4.6 Contrle de lAVD ...................................................................................................................28
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 2
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
1.5
Communication AVD - Android Studio ..........................................................................28
1.5.1 Fentres Android .....................................................................................................................28
1.5.2 Fentre LogCat .........................................................................................................................28
1.5.3 Filtrage des messages .............................................................................................................30
1.5.4 mission dun message pour LogCat ................................................................................30
1.5.5 Logiciel ADB .............................................................................................................................30
1.5.6 Mode demploi de ADB .........................................................................................................30
1.5.7 Mode demploi, suite ..............................................................................................................31
1.5.8 Systme de fichiers Android ................................................................................................31
1.5.9 Mode demploi, suite ..............................................................................................................31
1.6
Cration dun paquet installable .........................................................................................32
1.6.1 Paquet 32
1.6.2 Signature dune application .................................................................................................32
1.6.3 Cration du keystore ..............................................................................................................32
1.6.4 Cration dune cl ....................................................................................................................32
1.6.5 Cration du paquet ...............................................................................................................32
2
Cration dinterfaces utilisateur ........................................................................................33
2.1
Interface et ressources ............................................................................................................35
2.1.1 Activits ......................................................................................................................................35
2.1.2 Cration dun cran .................................................................................................................35
2.1.3 Identifiant de ressource .........................................................................................................36
2.1.4 La classe R ..................................................................................................................................36
2.1.5 Rappel sur la structure dun fichier XML ........................................................................36
2.1.6 Espaces de nommage dans un fichier XML ....................................................................37
2.1.7 Cration dune interface par programme ........................................................................37
2.1.8 Programme et ressources ......................................................................................................37
2.1.9 Ressources de type chanes ...................................................................................................38
2.1.10
Rfrencement des ressources texte .....................................................................38
2.1.11
Identifiants et vues.....................................................................................................38
2.1.12
android:id = @id/nom ou @+id/nom ............................................................39
2.1.13
Images : R.drawable.nom ........................................................................................39
2.1.14
Tableau de chanes : R.array.nom .........................................................................39
2.1.15
Autres ............................................................................................................................40
2.2
Dispositions ...............................................................................................................................40
2.2.1 Structure dune interface Android .....................................................................................40
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 3
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
2.2.2 Arbre des vues ..........................................................................................................................40
2.2.3 Reprsentation en XML .........................................................................................................40
2.2.4 Paramtres de positionnement ..........................................................................................41
2.2.5 Paramtres gnraux ..............................................................................................................41
2.2.6 Autres paramtres gomtriques........................................................................................41
2.2.7 Marges et remplissage ............................................................................................................42
2.2.8 Groupe de vues LinearLayout .............................................................................................42
2.2.9 Pondration des tailles ...........................................................................................................42
2.2.10
Exemple de poids diffrents ...................................................................................43
2.2.11
Groupe de vues TableLayout .................................................................................43
2.2.12
Largeur des colonnes dun TableLayout ............................................................44
2.2.13
Groupe de vues RelativeLayout ............................................................................44
2.2.14
Utilisation dun RelativeLayout ............................................................................44
2.2.15
Autres groupements..................................................................................................45
2.3
Composants dinterface ........................................................................................................45
2.3.1 Vues 45
2.3.2 TextView .....................................................................................................................................45
2.3.3 Button 45
2.3.4 Bascules .......................................................................................................................................46
2.3.5 EditText .......................................................................................................................................46
2.3.6 Autres vues ................................................................................................................................46
2.4
Styles ............................................................................................................................................46
2.4.1 Styles et thmes ........................................................................................................................46
2.4.2 Dfinir un style .........................................................................................................................46
2.4.3 Utiliser un style ........................................................................................................................47
2.4.4 Utiliser un thme .....................................................................................................................47
3
Vie dune application .............................................................................................................48
3.1
Applications et activits .........................................................................................................48
3.1.1 Composition dune application ...........................................................................................48
3.1.2 Dclaration dune application ...........................................................................................48
3.1.3 Scurit des applications .......................................................................................................49
3.1.4 Autorisations dune application .......................................................................................49
3.1.5 Dmarrage dune application ............................................................................................49
3.1.6 Dmarrage dune activit et Intents ...................................................................................50
3.1.7 Lancement dune activit par programme ......................................................................50
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 4
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
3.1.8 Lancement dune application Android .............................................................................50
3.1.9 Lancement dune activit dune autre application ........................................................50
3.2
Applications ..............................................................................................................................51
3.2.1 Fonctionnement dune application ..................................................................................51
3.2.2 Navigation entre activits .....................................................................................................51
3.2.3 Lancement sans attente ..........................................................................................................51
3.2.4 Lancement avec attente de rsultat ....................................................................................51
3.2.5 Lancement avec attente, suite ..............................................................................................53
3.2.6 Terminaison dune activit ...................................................................................................53
3.2.7 Mthode onActivityResult ....................................................................................................53
3.2.8 Transport dinformations dans un Intent .........................................................................54
3.2.9 Extraction dinformations dun Intent ..............................................................................54
3.2.10
Contexte dapplication .............................................................................................54
3.2.11
Dfinition dun contexte dapplication ...............................................................54
3.2.12
Dfinition dun contexte dapplication, suite ....................................................55
3.2.13
Dfinition dun contexte dapplication, fin ........................................................55
3.3
Activits ......................................................................................................................................55
3.3.1 Prsentation ...............................................................................................................................55
3.3.2 Cycle de vie dune activit ....................................................................................................56
3.3.3 vnements de changement dtat .....................................................................................56
3.3.4 Squelette dactivit ..................................................................................................................56
3.3.5 Terminaison dune activit ...................................................................................................57
3.3.6 Pause dune activit ................................................................................................................57
3.3.7 Arrt dune activit .................................................................................................................57
3.3.8 Enregistrement de valeurs dune excution lautre ...................................................58
3.3.9 Restaurer ltat au lancement ...............................................................................................58
3.4
Vues et activits ........................................................................................................................58
3.4.1 Obtention des vues ..................................................................................................................58
3.4.2 Proprits des vues .................................................................................................................59
3.4.3 Actions de lutilisateur ...........................................................................................................59
3.4.4 Dfinition dun couteur .......................................................................................................59
3.4.5 couteur priv anonyme .......................................................................................................60
3.4.6 couteur priv ..........................................................................................................................60
3.4.7 Lactivit elle-mme en tant qucouteur .........................................................................60
3.4.8 Distinction des metteurs....................................................................................................61
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 5
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
3.4.9 vnements des vues courantes ..........................................................................................61
4
Application liste .......................................................................................................................62
4.1
Prsentation ...............................................................................................................................62
4.1.1 Principe gnral ........................................................................................................................62
4.1.2 Schma global ...........................................................................................................................63
4.1.3 Une classe pour reprsenter les items ...............................................................................63
4.1.4 Donnes initiales ......................................................................................................................63
4.1.5 Copie dans un ArrayList .......................................................................................................64
4.1.6 Le container Java ArrayList<type> .....................................................................................64
4.1.7 Donnes initiales dans les ressources ................................................................................65
4.1.8 Donnes dans les ressources, suite .....................................................................................65
4.1.9 Remarques .................................................................................................................................65
4.2
Affichage de la liste .................................................................................................................65
4.2.1 Activit spcialise ou layout...............................................................................................65
4.2.2 Mise en uvre ..........................................................................................................................67
4.2.3 Layout de lactivit pour affi her une liste .......................................................................67
4.2.4 Mise en place du layout dactivit ......................................................................................67
4.2.5 Layout pour un item ...............................................................................................................68
4.2.6 Autre layouts .............................................................................................................................68
4.2.7 Layouts prdfinis ...................................................................................................................68
4.3
Adaptateurs ...............................................................................................................................68
4.3.1 Relations entre la vue et les donnes .................................................................................68
4.3.2 Rle dun adaptateur ..............................................................................................................68
4.3.3 Adaptateurs prdfinis .........................................................................................................68
4.3.4 ArrayAdapter<Type> pour les listes .................................................................................68
4.3.5 Exemple demploi ...................................................................................................................69
4.3.6 Affichage avec une ListActivity ..........................................................................................69
4.3.7 Exemple avec les layouts standards ..................................................................................69
4.4
Adaptateur personnalis ......................................................................................................70
4.4.1 Classe Adapter personnalise ..............................................................................................70
4.4.2 Classe Adapter perso, suite ..................................................................................................70
4.4.3 Mthode getView personnalise .........................................................................................71
4.4.4 Mthode PlaneteView.create ................................................................................................71
4.4.5 Layout ditem res/layout/item_planete.xml ....................................................................71
4.4.6 Classe personnalise dans les ressources .........................................................................72
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 6
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
4.4.7 Classe PlaneteView pour affi her les items ......................................................................72
4.4.8 Dfinition de la classe PlaneteView ...................................................................................72
4.4.9 Crer des vues avec un layout XML ..................................................................................73
4.4.10
Mthode PlaneteView.create ..................................................................................73
4.4.11
Mthode findViews ...................................................................................................73
4.4.12
Pour finir, la mthode PlaneteView.display ......................................................74
4.4.13
Rcapitulatif .................................................................................................................74
4.4.14
Le rsultat .....................................................................................................................74
4.5
Actions utilisateur sur la liste ..............................................................................................74
4.5.1 Modification des donnes .....................................................................................................74
4.5.2 Clic sur un lment .................................................................................................................75
4.5.3 Clic sur un lment, suite ......................................................................................................75
4.5.4 Clic sur un lment, suite ......................................................................................................76
4.5.5 Clic sur un lment, fin ..........................................................................................................76
4.5.6 Liste dlments cochables ....................................................................................................76
4.5.7 Liste cochable simple ..............................................................................................................76
4.5.8 Liste choix multiples ............................................................................................................77
4.5.9 Liste cochable personnalise ................................................................................................77
5
Ergonomie ..................................................................................................................................79
5.1
Barre daction et menus .........................................................................................................79
5.1.1 Barre daction ............................................................................................................................79
5.1.2 Ralisation dun menu ...........................................................................................................79
5.1.3 Spcification dun menu ........................................................................................................80
5.1.4 Icnes pour les menus ............................................................................................................80
5.1.5 Thme pour une barre daction ...........................................................................................80
5.1.6 couteurs pour les menus .....................................................................................................81
5.1.7 Ractions aux slections ditems .........................................................................................81
5.1.8 Menus en cascade ....................................................................................................................81
5.1.9 Menus contextuels ...................................................................................................................82
5.1.10
Associer un menu contextuel une vue .............................................................82
5.1.11
Callback daffichage du menu ...............................................................................83
5.1.12
Callback des items du menu ...................................................................................83
5.2
Annonces et dialogues ...........................................................................................................83
5.2.1 Annonces : toasts .....................................................................................................................83
5.2.2 Annonces personnalises ......................................................................................................84
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 7
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
5.2.3 Dialogues ....................................................................................................................................84
5.2.4 Dialogue dalerte ......................................................................................................................85
5.2.5 Boutons et affichage dun dialogue dalerte ....................................................................85
5.2.6 Autres types de dialogues dalerte .....................................................................................85
5.2.7 Dialogues personnaliss ........................................................................................................86
5.2.8 Cration dun dialogue ..........................................................................................................86
5.2.9 Affichage du dialogue ............................................................................................................86
5.3
Fragments et activits .............................................................................................................87
5.3.1 Fragments ...................................................................................................................................87
5.3.2 Tablettes, smartphones. . . .....................................................................................................87
5.3.3 Structure dun fragment ........................................................................................................87
5.3.4 Diffrents types de fragments ..............................................................................................88
5.3.5 Cycle de vie des fragments ...................................................................................................88
5.3.6 ListFragment .............................................................................................................................88
5.3.7 ListFragment, suite ..................................................................................................................89
5.3.8 Menus de fragments ...............................................................................................................89
5.3.9 Intgrer un fragment dans une activit ............................................................................90
5.3.10
Fragments statiques dans une activit.................................................................90
5.3.11
FragmentManager .....................................................................................................90
5.3.12
Attribution dun fragment dynamiquement .....................................................90
5.3.13
Disposition selon la gomtrie de lcran ...........................................................91
5.3.14
Changer la disposition selon la gomtrie .........................................................91
5.3.15
Deux dispositions possibles ....................................................................................92
5.3.16
Communication entre Activit et Fragments ....................................................92
5.3.17
Interface pour un couteur ......................................................................................92
5.3.18
couteur du fragment ...............................................................................................93
5.3.19
couteur de lactivit ................................................................................................93
5.3.20
Relation entre deux classes mditer, partie 1 .................................................94
5.3.21
mditer, partie 2 .....................................................................................................94
5.4
Prfrences dapplication .....................................................................................................94
5.4.1 Illustration ..................................................................................................................................94
5.4.2 Prsentation ...............................................................................................................................94
5.4.3 Dfinition des prfrences ....................................................................................................95
5.4.4 Explications................................................................................................................................95
5.4.5 Accs aux prfrences ............................................................................................................96
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 8
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
5.4.6 Prfrences chanes et nombres ...........................................................................................96
5.4.7 Modification des prfrences par programme ...............................................................96
5.4.8 Affichage des prfrences .....................................................................................................97
5.4.9 Fragment pour les prfrences ............................................................................................97
6
Bases de donnes SQLite3 <> ................................................................................................98
6.1
SQLite3 ........................................................................................................................................98
6.1.1 Stockage dinformations ........................................................................................................98
6.1.2 SQLite3 ........................................................................................................................................98
6.1.3 Exemples SQL ...........................................................................................................................99
6.1.4 Autres usages de SQLite3 ......................................................................................................99
6.1.5 Lancement de sqlite3 en shell ...............................................................................................99
6.1.6 Commandes internes .............................................................................................................99
6.2
SQLite dans une application Android..............................................................................100
6.2.1 Bases de donnes Android ..................................................................................................100
6.2.2 Classes pour travailler avec SQLite ...................................................................................100
6.2.3 Principes....................................................................................................................................100
6.2.4 Base ouverte dans une activit ...........................................................................................101
6.2.5 Recommandations..................................................................................................................101
6.2.6 Noms des colonnes ................................................................................................................101
6.2.7 Classe pour une table ............................................................................................................102
6.2.8 Exemples de mthodes .........................................................................................................102
6.2.9 Mthodes SQLiteDatabase.execSQL .................................................................................102
6.2.10
Mthodes spcialises .............................................................................................103
6.2.11
Mthode insert ...........................................................................................................103
6.2.12
Mthodes update et delete .....................................................................................103
6.2.13
Mthode rawQuery ..................................................................................................104
6.2.14
rawQuery pour un seul n-uplet............................................................................104
6.2.15
Classe Cursor .............................................................................................................104
6.2.16
Exemple de requte, classe TablePlanetes .........................................................105
6.2.17
Autre type de requte ..............................................................................................105
6.2.18
Mthodes query ........................................................................................................105
6.2.19
Ouverture dune base ..............................................................................................105
6.2.20
Premire ouverture et ouvertures suivantes.....................................................106
6.2.21
Un helper pour grer louverture/cration/mj ...............................................106
6.2.22
Exemple de helper ....................................................................................................106
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 9
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
6.2.23
Exemple de helper, suite.........................................................................................107
6.2.24
mthode onUpgrade ................................................................................................107
6.2.25
mthode onUpgrade, suite ....................................................................................108
6.2.26
Retour lapplication ..............................................................................................108
6.3
CursorAdapter et Loaders ...................................................................................................108
6.3.1 Lien entre une BDD et un ListView ..................................................................................108
6.3.2 tapes suivre ........................................................................................................................109
6.3.3 Activit ou fragment daffichage dune liste ..................................................................109
6.3.4 Cration dun adaptateur de curseur ...............................................................................109
6.3.5 Ouverture de la base et cration dun chargeur ............................................................110
6.3.6 Callback onCreateLoader de lactivit .............................................................................110
6.3.7 classe MonCursorLoader .....................................................................................................110
6.3.8 Callback onLoadFinished de lactivit .............................................................................111
6.3.9 Mise jour de la liste .............................................................................................................111
6.4
ContentProviders ...................................................................................................................111
6.4.1 Prsentation rapide ................................................................................................................111
6.5
WebServices .............................................................................................................................112
6.5.1 Echange entre un serveur SQL et une application Android ......................................112
6.5.2 Principe gnral ......................................................................................................................112
6.5.3 Exemple de script PHP Post ................................................................................................112
6.5.4 Exemple de script PHP Get .................................................................................................113
6.5.5 Format JSON JavaScript Object Notation ........................................................................113
6.5.6 JSON en Java ............................................................................................................................113
6.5.7 Dans lapplication Android .................................................................................................114
6.5.8 Affichage dune liste ..............................................................................................................114
6.5.9 La classe RemoteDatabase ...................................................................................................114
6.5.10
Modification dun n-uplet ......................................................................................114
6.5.11
Script update_planete.php .....................................................................................115
6.5.12
Mthode post(couteur, script, params) ............................................................115
Affichage de donnes golocalises ..................................................................................116
7.1
AsyncTasks ..............................................................................................................................116
7.1.1 Prsentation .............................................................................................................................116
7.1.2 Tches asynchrones ...............................................................................................................116
7.1.3 Principe dutilisation dune AsyncTask ...........................................................................117
7.1.4 Structure dune AsyncTask .................................................................................................117
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 10
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
7.1.5 Paramtres dune AsyncTask .............................................................................................117
7.1.6 Exemple de paramtrage .....................................................................................................117
7.1.7 Paramtres variables .............................................................................................................118
7.1.8 Dfinition dune AsyncTask................................................................................................118
7.1.9 AsyncTask, suite .....................................................................................................................118
7.1.10
Lancement dune AsyncTask ................................................................................119
7.1.11
Schma rcapitulatif.................................................................................................119
7.1.12
execute ne retourne rien .........................................................................................119
7.1.13
Rcupration du rsultat dun AsyncTask ........................................................120
7.1.14
Simplification .............................................................................................................120
7.1.15
Recommandations ....................................................................................................121
7.1.16
Autres tches asynchrones .....................................................................................121
7.2
Requtes HTTP .......................................................................................................................121
7.2.1 Prsentation .............................................................................................................................121
7.2.2 Principe de programmation pour un GET ......................................................................122
7.2.3 Exemple de requte GET ......................................................................................................122
7.2.4 Encodage de paramtres pour une requte ....................................................................122
7.2.5 Principe de programmation pour un POST....................................................................123
7.2.6 Exemple de requte POST ...................................................................................................123
7.2.7 Requtes asynchones............................................................................................................123
7.2.8 Permissions pour lapplication ...........................................................................................124
7.3
OpenStreetMap .......................................................................................................................124
7.3.1 Prsentation .............................................................................................................................124
7.3.2 Documentation........................................................................................................................124
7.3.3 Pour commencer .....................................................................................................................124
7.3.4 Layout pour une carte OSM ................................................................................................124
7.3.5 Activit pour une carte OSM ..............................................................................................126
7.3.6 Positionnement de la vue .....................................................................................................126
7.3.7 Calques ......................................................................................................................................127
7.3.8 Mise jour de la carte ...........................................................................................................127
7.3.9 Marqueurs ................................................................................................................................127
7.3.10
Marqueur personnaliss .........................................................................................127
7.3.11
Raction un clic ......................................................................................................128
7.3.12
Itinraires ....................................................................................................................128
7.3.13
Position GPS ...............................................................................................................128
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 11
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
7.3.14
Autorisations ..............................................................................................................129
7.3.15
Mise jour en temps rel de la position .............................................................129
7.3.16
Positions simules ....................................................................................................130
7.3.17
Clics sur la carte ........................................................................................................130
7.3.18
Traitement des clics ..................................................................................................130
Dessin 2D interactif ................................................................................................................131
8.1
Dessin en 2D ............................................................................................................................131
8.1.1 Principes....................................................................................................................................131
8.1.2 Layout pour le dessin ............................................................................................................132
8.1.3 Mthode onDraw ...................................................................................................................132
8.1.4 Mthodes de la classe Canvas.............................................................................................132
8.1.5 Peinture Paint ..........................................................................................................................133
8.1.6 Quelques accesseurs de Paint ..........................................................................................133
8.1.7 Motifs 133
8.1.8 Shaders ......................................................................................................................................134
8.1.9 Shaders, suite et fin ................................................................................................................134
8.1.10
Quelques remarques ................................................................................................134
8.1.11
Dessinables ...........................................................................................................134
8.1.12
Images PNG tirables 9patch ................................................................................135
8.1.13
Drawable, suite ..........................................................................................................135
8.1.14
Variantes .....................................................................................................................136
8.1.15
Utilisation dun Drawable ......................................................................................136
8.1.16
Enregistrer un dessin dans un fichier .................................................................136
8.1.17
Coordonnes dans un canvas................................................................................137
8.2
Interactions avec lutilisateur ..............................................................................................137
8.2.1 couteurs pour les touchers de lcran ............................................................................137
8.2.2 Modle de gestion des actions ............................................................................................137
8.2.3 Automate pour grer les actions ........................................................................................138
8.3
Botes de dialogue spcifiques.........................................................................................138
8.3.1 Slecteur de couleur...............................................................................................................138
8.3.2 Version simple.........................................................................................................................138
8.3.3 Concepts....................................................................................................................................139
8.3.4 Fragment de dialogue ...........................................................................................................139
8.3.5 Mthode onCreateDialog .....................................................................................................139
8.3.6 Vue personnalise dans le dialogue ..................................................................................140
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 12
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
8.3.7 Layout de cette vue ................................................................................................................140
8.3.8 Utilisation du dialogue .........................................................................................................141
8.3.9 Slecteur de fichier .................................................................................................................141
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 13
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Environnement de dveloppement
Cette partie prsente lenvironnement de dveloppement Android :
Le SDK Android et Android Studio
Cration dune application simple
Communication avec une tablette.
1.1
Introduction
1.1.1 Android
n en 2004,
rachet par Google en 2005,
publi en 2007, version 1.5,
de nombreuses versions depuis, on en est la 6.
1.1.2
Dfinition
Systme complet pour smartphones et tablettes
Gestion matrielle : systme dexploitation Linux sous-jacent
API de programmation : interfaces utilisateur, outils. . .
Applications : navigateur, courrier. . .
volution et obsolescence trs rapides (cest voulu)
Ce que vous allez apprendre sera rapidement dpass (1 an)
syntaxiquement (mthodes, paramtres, classes, ressources. . . )
mais pas les concepts (principes, organisation. . . )
Vous tes condamn(e) une autoformation permanente, mais cest le lot des informaticiens.
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 14
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 1: Constituants dAndroid
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 15
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
1.1.3
Composants dAndroid
Voir la figure 1 ci dessus
1.1.4
Programmation dapplications
Application Android :
Sources Java compils pour une machine virtuelle Dalvik (versions 4.4) ou ART depuis
la version 5
Fichiers XML appels ressources : interface, textes. . .
Fichiers de donnes supplmentaires
Manifeste = description du contenu du logiciel
fichiers prsents dans larchive
demandes dautorisations
signature des fichiers, dure de validit, etc.
Tout cet ensemble est gr laide dun IDE (environnement de dveloppement) appel Android
Studio. Avant, on pouvait utiliser Eclipse, mais son plugin Android nest plus dvelopp.
1.2
SDK Android et Android Studio
1.2.1 SDK Android
Le SDK contient :
les librairies Java pour crer des logiciels
les outils de mise en bote des logiciels
un mulateur de tablettes pour tester les applications AVD
un outil de communication avec les vraies tablettes ADB
Android Studio offre :
un diteur de sources
des outils de compilation et de lancement dAVD
1.2.2
SDK Manager
Le SDK est livr avec un gestionnaire. Cest une application qui permet de choisir les composants
installer.
Voir la figure 2.
1.2.3
Choix des lments du SDK
Tlcharger le SDK correspondant au systme dexploitation. Ce SDK contient un gestionnaire (SDK
Manager ).
Le gestionnaire permet de choisir quelles versions dAndroid installer parmi 2 :
1Certaines images de ce cours sont de http://developer.android.com
2versions
existantes la date de rdaction de ce cours
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 16
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 2: Gestionnaire de paquets Android
Android 6 (API 23)
Android 5.1.1 (API 22)
Android 5.0.1 (API 21)
Android 4.4W.2 (API 20)
...
Android 1.5 (API 3)
Choisir celles qui correspondent aux tablettes quon vise.
1.2.4
Dossiers du SDK
Le gestionnaire tlcharge environ 800Mo de fichiers :
SDK Tools : indispensable, contient le gestionnaire,
SDK Platform-tools : indispensable, contient adb,
SDK Platform : indispensable, contient les librairies,
System images : pour crer des AVD,
Android Support : divers outils pour crer des applications,
Exemples et sources.
1.2.5
Android Studio
Pour finir, il faut installer Android Studio selon la procdure explique ci aprs.
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 17
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 18
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 19
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 20
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 21
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 22
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 23
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 24
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 25
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 26
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 27
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Aprs cette installation, il faut indiquer lemplacement du SDK dans Android Studio.
Une autre manire est dinstaller Android Studio en premier, lui-mme installant tous les composants
manquants.
1.3
Premire application
1.3.1 Objectifs
Dans cette partie, ce sera seulement un aperu rapide des possibilits :
Cration dune application HelloWorld avec un assistant,
Tour du propritaire,
Excution de lapplication,
Mise sous forme dun paquet.
1.3.2
Assistant de cration dapplication
Android Studio contient un assistant de cration dapplications :
Voir la figure 3.
1.3.3
Choix de la version
Chaque version dAndroid, dnote par son API level, apporte des amliorations et supprime des
dispositifs obsoltes.
Toute application exige un certain niveau dAPI :
Minimum SDK : il faut au moins cette API car on utilise certaines classes et mthodes absentes
des prcdentes APIs,
Avec Eclipse, on devait aussi spcifier :
Target SDK : lapplication sera teste et marchera correctement jusqu ce niveau dAPI,
Compile With : cest le niveau maximal de fonctionnalits quon se limite employer. Si on
fait appel quelque chose de plus rcent que ce niveau, le logiciel ne se compilera pas.
1.3.4
Choix de la version
Voici comment choisir le Minimum SDK :
Voir la figure 4.
1.3.5
Choix du type dapplication
Ensuite, on choisit le type de projet. Pour un premier essai, on se limite au plus simple, Blank
Activity :
Voir la figure 5.
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 28
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 3: Assistant de cration de projet
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 29
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 4: Choix de la version
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 30
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 5: Choix du type dactivit
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 31
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
1.3.6
Points configurer
Lassistant demande ensuite plusieurs informations :
Nom de lapplication, ex : HellorHorde,
Nom de la classe principale : MainActivity,
Nom du layout de la classe principale : activity_main,
Nom du layout du menu principal : menu_main.
Tout peut tre renomm ultrieurement, voir refactor/rename.
Le package du logiciel a t dfini dans le premier cran.
1.3.7
Noms des packages et classes
Voici o on indique ces informations :
1.3.8
Rsultat de lassistant
Lassistant a cr de nombreux lments visibles dans la colonne de gauche de lIDE :
manifests : description de lapplication,
java : les sources, rangs par paquetage,
res : ressources = fichiers XML et images de linterface, il y a des sous-dossiers
drawable : images, icnes utiliss dans linterface
layout : interfaces (disposition des vues sur les crans)
menu : menus contextuels ou dapplication
mipmap : images, icnes utiliss dans linterface
values : valeurs de configuration, textes. . .
Gradle scripts : cest loutil de compilation du projet.
1.3.9
Fentre du projet
Voir la figure 7.
1.3.10 diteurs
spcifiques
Studio fournit des diteurs spcialiss pour les fichiers XML, par exemple :
Formulaires pour :
res/values/strings.xml : textes de linterface.
diteurs graphiques pour :
res/layout/*.xml : disposition des contrles sur linterface.
1.3.11 Exemple
res/values/strings.xml
Voir la figure 8.
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 32
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 6: Choix du type dactivit
INNOV MAROC
MOBILE ANDROID DESIGN DEVELOPPEMENT
MOBILE ANDROID DESIGN DEVELOPPEMENT
Page 33
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 7: lments2d
4un projet Android
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 8: diteur du manifeste
Figure 9: diteur graphique
25
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
1.3.12 Exemple
res/layout/main.xml
Voir la figure 9.
1.3.13 Source
XML sous-jacent
Ces diteurs sont plus confortables que le XML brut, mais ne permettent pas de tout faire.
Dans certains cas, il faut diter le source XML directement :
<RelativeLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
</RelativeLayout>
1.3.14 Reconstruction
du projet
Automatique :
Ex: modifier le fichier res/values/strings.xml ou un source Java,
Gradle compile automatiquement le projet.
Manuelle, parfois ncessaire quand on modifie certaines ressources :
Slectionner le projet et choisir menu Build/Clean...
1.4
Premire excution
1.4.1 Excution de lapplication
Le SDK Android permet de :
Installer lapplication sur une vraie tablette connecte par USB
Simuler lapplication sur une tablette virtuelle AVD
AVD = Android Virtual Device
Cest une machine virtuelle comme celles de VirtualBox et VMware, mais base sur QEMU.
QEMU est en licence GPL, il permet dmuler toutes sortes de CPU dont des ARM7, ceux qui
font tourner la plupart des tablettes Android.
Assistant de cration dune tablette virtuelle
1.4.3 Caractristiques dun AVD
1.4.2
Lassistant de cration de tablette demande :
26
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 10: Cration dun AVD
27
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Modle de tablette ou tlphone simuler,
Version du systme quil doit contenir,
Orientation et densit de lcran
Options de simulation :
Snapshot : mmorise ltat de la machine dun lancement lautre, mais exclut Use
Host GPU,
Use Host GPU : acclre les dessins 2D et 3D laide de la carte graphique du PC.
Options avances :
RAM : mmoire allouer, mais est limite par votre PC,
Internal storage : capacit de la flash interne,
SD Card : capacit de la carte SD simule supplmentaire (optionnelle).
1.4.4
Lancement dune application
Bouton vert pour excuter, bleu pour dboguer :
Figure 11: Barre doutils pour lancer une application
Application sur lAVD
1.4.6 Contrle de lAVD
1.4.5
Pour simuler les boutons dune vraie tablette :
F2 affiche le menu de lapplication
esc retour en arrire
home retour lcran daccueil
ctrl-F11 rotation paysage/portrait.
NB : la touche 7 du pav numrique fait aussi basculer lcran.
1.5
Communication AVD - Android Studio
1.5.1 Fentres Android
Android Studio affiche plusieurs fentres utiles indiques dans longlet tout en bas :
Android Monitor Affiche tous les messages mis par la tablette courante
Console Messages du compilateur et du studio
1.5.2
Fentre LogCat
Des messages dtaills sont affichs dans la fentre LogCat :
28
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 12: Rsultat sur lAVD
Figure 13: Fentre LogCat
29
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Voir la figure 13.
Ils sont mis par les applications : debug, infos, erreurs. . .
1.5.3
Filtrage des messages
Il est commode de dfinir des filtres pour ne pas voir la totalit des messages de toutes les applications
de la tablette :
sur le niveau de gravit : verbose, debug, info, warn, error et assert,
sur ltiquette TAG associe chaque message,
sur le package de lapplication qui met le message.
1.5.4
mission dun message pour LogCat
Une application met un message par ces instructions :
import android.util.Log;
public class MainActivity extends Activity {
public static final String TAG = "hello";
void maMethode() {
Log.i(TAG, "Salut !");
Fonctions Log.* :
Log.i(String tag, String message) affiche une info,
Log.w(String tag, String message) affiche un avertissement,
Log.e(String tag, String message) affiche une erreur.
1.5.5
Logiciel ADB
Android Debug Bridge est une passerelle entre une tablette (relle ou virtuelle) et votre PC
Serveur de connexion des tablettes
Commande de communication
ADB emprunte FTP (transfert de fichiers) et SSH (connexion un shell).
1.5.6
Mode demploi de ADB
En ligne de commande : adb commande paramtres...
Gestion du serveur
adb start-server : dmarre le serveur,
adb kill-server : arrte le serveur,
adb devices : liste les tablettes connectes.
Exemple :
~/CoursAndroid/$ adb devices
List of devices attached
emulator-5554
device
c1608df1b170d4f device
~/CoursAndroid/$
30
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
1.5.7
Mode demploi, suite
Chaque tablette (device) possde un identifiant, ex: c1608df1b170d4f ou emulator-5554 quil faut
fournir aux commandes adb laide de loption -s.
Par dfaut, cest la seule tablette active qui est concerne.
Connexion un shell
adb -s identifiant shell commande_unix. . .
excute la commande sur la tablette
adb -s identifiant shell
ouvre une connexion de type shell sur la tablette.
Ce shell est un interprteur sh simplifi (type busybox) lintrieur du systme Unix de la tablette. Il
connat les commandes standard Unix de base : ls, cd, cp, mv, ps. . .
1.5.8
Systme de fichiers Android
On retrouve larchitecture des dossiers Unix, avec des variantes :
Dossiers Unix classiques : /usr, /dev, /etc, /lib, /sbin. . .
Les volumes sont monts dans /mnt, par exemple /mnt/sdcard (mmoire flash interne) et
/mnt/extSdCard (SDcard amovible)
Les applications sont dans :
/system/app pour les pr-installes
/data/app pour les applications normales
Les donnes des applications sont dans /data/data/nom.du.paquetage.java
Ex: /data/data/fr.iutlan.helloworld/. . .
NB : il y a des restrictions daccs sur une vraie tablette, car vous ny tes pas root
principe.
1.5.9
Mode demploi, suite
Pour changer des fichiers avec une tablette :
adb push nom_du_fichier_local /nom/complet/dest
envoi du fichier local sur la tablette
adb pull /nom/complet/fichier
rcupre ce fichier de la tablette
Pour grer les logiciels installs :
adb install paquet.apk
adb uninstall nom.du.paquetage.java
Pour archiver les donnes de logiciels :
adb backup -f fichier_local nom.du.paquetage.java . . .
enregistre les donnes du/des logiciels dans le fichier local
adb restore fichier_local
restaure les donnes du/des logiciels daprs le fichier.
31
. . . enfin en
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
1.6
Cration dun paquet installable
1.6.1 Paquet
Un paquet Android est un fichier .apk. Cest une archive signe (authentifie) contenant les binaires,
ressources compresses et autres fichiers de donnes.
La cration est relativement simple avec Studio :
1. Menu contextuel du projet Build..., choisir Generate Signed APK,
2. Signer le paquet laide dune cl prive,
3. Dfinir lemplacement du fichier .apk.
Le rsultat est un fichier .apk dans le dossier spcifi.
1.6.2
Signature dune application
Lors de la mise au point, Studio gnre une cl qui ne permet pas dinstaller lapplication ailleurs.
Pour distribuer une application, il faut une cl prive.
Les cls sont stockes dans un keystore = trousseau de cls. Il faut le crer la premire fois. Cest un
fichier crypt, protg par un mot de passe, ranger soigneusement.
Ensuite crer une cl prive :
alias = nom de la cl, mot de passe de la cl
informations personnelles compltes : prnom, nom, organisation, adresse, etc.
Les mots de passe du trousseau et de la cl seront demands chaque cration dun .apk.
Cration du keystore
1.6.4 Cration dune cl
1.6.5 Cration du paquet
1.6.3
Ensuite, Studio demande o placer le .apk :
Voir la figure 16.
32
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 14: Cration dun trousseau de cls
Cration dinterfaces utilisateur
Cette partie explique la cration dinterfaces utilisateur :
Relations entre un source Java et des ressources
Layouts et vues
Styles
On ne sintresse qu la mise en page. Lactivit des interfaces sera tudie ultrieuremernt. NB:
les textes fuchsia sont des liens cliquables.
33
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 15: Cration dune cl
34
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 16: Cration du paquet
2.1
Interface et ressources
2.1.1 Activits
Linterface utilisateur dune application Android est compose dcrans. Un cran correspond une
activit, ex :
afficher une liste ditems
diter un item laide dun formulaire.
Les dialogues et les pop-up ne sont pas des activits, ils se superposent temporairement lcran
dune activit.
Android permet de naviguer dune activit lautre :
une action de lutilisateur, bouton, menu ou lapplication fait aller sur lcran suivant
le bouton back ramne sur lcran prcdent.
2.1.2
Cration dun cran
Chaque cran est gr par une instance dune sous-classe perso de Activity. Sa mthode onCreate
dfinit, entre autres, ce qui doit tre affich sur lcran :
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
35
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
setContentView(R.layout.main);
}
@Override signifie que onCreate surcharge cette mthode de la superclasse et il faut aussi lappeler
sur super
2.1.3
Identifiant de ressource
La mthode setContentView spcifie lidentifiant de linterface afficher dans lcran :
R.layout.main. Cest un entier, identifiant dune disposition de vues : un layout.
Le SDK Android (aapt) gre un dossier gen contenant une classe statique appele R. Elle ne contient
que des constantes entires :
package fr.iutlan.helloworld;
public final class R {
public static final class id {
public static final int texte=0x7f080000;
}
public static final class layout {
public static final int main=0x7f030000;
}
2.1.4
La classe R
Cette classe R est gnre automatiquement par ce que vous mettez dans le dossier res : dispositions,
identifiants, chanes. . . Les dispositions et autres sont dfinies par des fichiers XML.
Par exemple, res/values/strings.xml :
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Exemple</string>
<string name="message">Bonjour !</string>
<resources>
2.1.5
Rappel sur la structure dun fichier XML
Un fichier XML : nuds racine, lments, attributs, valeurs, texte.
<?xml version="1.0" encoding="utf-8"?>
<racine>
<!-- commentaire -->
<element attribut1="valeur1"
attribut2="valeur2">
<feuille1 attribut3="valeur3"/>
<feuille2>texte</feuille2>
36
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
</element>
texte en vrac
</racine>
2.1.6
Espaces de nommage dans un fichier XML
Dans le cas dAndroid, il y a un grand nombre dlments et dattributs normaliss. Les attributs ont
t regroups dans un namespace (xmlns). Leur nom est android:nomattribut.
Vous pouvez lire cette page sur les namespaces.
<menu
xmlns:android=
"http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="Configuration"/>
</menu>
2.1.7
Cration dune interface par programme
Il est possible de crer une interface par programme, mais cest assez compliqu :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context ctx = getApplicationContext();
TextView tv = new TextView(ctx);
tv.setText("Demat\ !");
RelativeLayout rl = new RelativeLayout(ctx);
LayoutParams lp = new LayoutParams();
lp.width = LayoutParams.MATCH_PARENT;
lp.height = LayoutParams.MATCH_PARENT;
rl.addView(tv, lp);
setContentView(rl);
}
2.1.8
Programme et ressources
Il est donc prfrable de stocker linterface dans un fichier res/layout/main.xml :
<RelativeLayout ...>
<TextView android:text="Demat !" ... />
</RelativeLayout>
qui est rfrenc par son identifiant R.layout.nom_du_fichier dans le programme Java :
37
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.main);
}
2.1.9
Ressources de type chanes
Dans res/values/strings.xml, on place les chanes de lapplication, au lieu de les mettre en
constantes dans le source :
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">HelloWorld</string>
<string name="main_menu">Menu principal</string>
<string
name="action_settings">Configuration</string>
<string name="bonjour">Demat !</string>
</resources>
Intrt : pouvoir traduire une application sans la recompiler.
2.1.10 Rfrencement
des ressources texte
Voici comment affecter une ressource chane une vue en Java :
TextView tv = new TextView(ctx);
tv.setText(R.string.bonjour);
Voici comment spcifier un titre de label dans un layout.xml :
<RelativeLayout>
<TextView android:text="@string/bonjour" />
</RelativeLayout>
@string/nom signifie la chane de res/values/strings.xml ayant ce nom.
2.1.11 Identifiants
et vues
La mthode setContentView fait afficher le formulaire dfini par lidentifiant R.layout indiqu.
Lorsque lapplication veut manipuler lune de ses vues, elle doit faire utiliser R.id.symbole, ex :
TextView tv = (TextView) findViewById(R.id.message);
(remarquez la conversion de type), avec la dfinition suivante :
38
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
<RelativeLayout>
<TextView android:id="@+id/message"
android:text="@string/bonjour"
/>
</RelativeLayout>
La notation @+id/nom fait crer ou utiliser R.id.nom.
2.1.12 android:id
= @id/nom ou @+id/nom
Il y a les deux notations :
@id/nom pour rfrencer un identifiant dfini ailleurs
@+id/nom pour crer cet identifiant
Exemple :
<RelativeLayout xmlns:android="..." ... >
<TextView ...
android:id="@+id/titre"
android:text="@string/titre" />
<Button ...
android:id="@+id/btn"
android:layout_below="@id/titre"
android:text="@string/ok" />
</RelativeLayout>
2.1.13 Images
: R.drawable.nom
De la mme faon, les images places dans res/drawable sont rfrenables :
<ImageView
android:src="@drawable/velo"
android:contentDescription="@string/mon_velo"
/>
La notation @drawable/nom rfrence limage res/drawable/nom.
2.1.14 Tableau
de chanes : R.array.nom
Voici un extrait du fichier res/strings/arrays.xml :
<resources>
<string-array name="planetes">
<item>Mercure</item>
<item>Venus</item>
<item>Terre</item>
<item>Mars</item>
</string-array>
</resources>
39
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Dans le programme Java, il est possible de faire :
Resources res = getResources();
String[] planetes = res.getStringArray(R.array.planetes);
2.1.15 Autres
Dautres notations existent :
@style/nom pour des dfinitions de res/style
@menu/nom pour des dfinitions de res/menu
Certaines notations, @package:type/nom font rfrence des donnes prdfinies, comme :
@android:style/TextAppearance.Large
@android:color/black
Il y a aussi une notation en ?type/nom pour rfrencer la valeur de lattribut nom, ex :
?android:attr/textColorSecondary.
2.2
Dispositions
2.2.1 Structure dune interface Android
Un cran Android de type formulaire est gnralement compos de plusieurs vues. Entre autres :
TextView, ImageView titre, image
EditText texte saisir
Button, CheckBox bouton cliquer, case cocher
Ces vues sont alignes laide de groupes sous-classes de ViewGroup, ventuellement imbriqus :
LinearLayout positionne ses vues en ligne ou colonne
RelativeLayout positionne ses vues lune par rapport lautre
TableLayout positionne ses vues sous forme dun tableau
2.2.2
Arbre des vues
Les groupes et vues forment un arbre :
2.2.3
Reprsentation en XML
Cet arbre scrit en XML :
<LinearLayout android:id="@+id/groupe1" ...>
<TextView android:id="@+id/titre" .../>
<EditText android:id="@+id/saisie" .../>
<LinearLayout android:id="@+id/groupe2" ...>
<Button android:id="@+id/ok" .../>
<Button android:id="@+id/raz" .../>
<Button android:id="@+id/annuler" .../>
40
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 17: Arbre de vues
</LinearLayout>
</LinearLayout>
2.2.4
Paramtres de positionnement
La plupart des groupes utilisent des paramtres de placement sous forme dattributs XML. Par
exemple, telle vue droite de telle autre, telle vue la plus grande possible, telle autre la plus petite.
Ces paramtres sont de deux sortes :
ceux qui sont demands pour toutes les vues, par exemple android:layout_width,
android:layout_height et android:layout_weight
ceux qui sont demands par le groupe englobant et qui en sont spcifiques, comme
android:layout_alignParentBottom, android:layout_centerInParent. . .
2.2.5
Paramtres gnraux
Toutes les vues doivent spcifier ces deux attributs :
android:layout_width largeur de la vue
android:layout_height hauteur de la vue
Ils peuvent valoir :
"wrap_content" : la vue est la plus petite possible
"match_parent" : la vue est la plus grande possible
"valeur dp" : une taille fixe, ex : "100dp" mais cest peu recommand
Les dp sont une unit de taille indpendante de lcran. 100dp font 100 pixels sur un cran de 100 dpi
(100 dots per inch) tandis quils font 200 pixels sur un cran 200dpi. a fait la mme taille apparente.
2.2.6
Autres paramtres gomtriques
Il est possible de modifier lespacement des vues :
41
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Padding espace entre le texte et les bords, gr par chaque vue
Margin espace autour des bords, gr par les groupes
Figure 18: Bords et marges
2.2.7
Marges et remplissage
On peut dfinir les marges et les remplissages sparment sur chaque bord (Top, Bottom, Left, Right),
ou identiquement sur tous :
<Button
android:layout_margin="10dp"
android:layout_marginTop="15dp"
android:padding="10dp"
android:paddingLeft="20dp" />
2.2.8
Groupe de vues LinearLayout
Il range ses vues soit horizontalement, soit verticalement
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button android:text="Ok" android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button android:text="Annuler" android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Il faut seulement dfinir lattribut android:orientation "horizontal" ou "vertical". Lire la
doc Android.
2.2.9
Pondration des tailles
Une faon intressante de spcifier les tailles des vues dans un LinearLayout consiste leur affecter
un poids avec lattribut android:layout_weight.
42
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Un layout_weight gal 0 rend la vue la plus petite possible
Un layout_weight non nul donne une taille correspondant au rapport entre ce poids et la
somme des poids des autres vues
Pour cela, il faut aussi fixer la taille de ces vues (ex : android:layout_width) soit "wrap_content",
soit "0dp". Si la taille vaut "wrap_content", alors le poids agit seulement sur lespace supplmentaire
allou aux vues. Mettre 0dp pour que a agisse sur la taille entire.
2.2.10 Exemple
de poids diffrents
Voici 4 LinearLayout horizontaux de 3 boutons ayant des poids gaux leurs titres. En 3e ligne, les
boutons ont une largeur de 0dp
Figure 19: Influence des poids sur la largeur
2.2.11 Groupe
de vues TableLayout
Cest une variante du LinearLayout : les vues sont ranges en lignes de colonnes bien tabules. Il
faut construire une structure XML comme celle-ci. Voir sa doc Android.
<TableLayout ...>
<TableRow>
<item 1.1
<item 1.2
</TableRow>
<TableRow>
<item 2.1
<item 2.2
</TableRow>
<TableLayout>
.../>
.../>
.../>
.../>
43
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
NB : les <TableRow> nont aucun attribut.
2.2.12 Largeur
des colonnes dun TableLayout
Ne pas spcifier android:layout_width dans les vues dun TableLayout, car cest obligatoirement
toute la largeur du tableau. Seul la balise <TableLayout> exige cet attribut.
Deux proprits intressantes permettent de rendre certaines colonnes tirables. Fournir les numros
(premire = 0).
android:stretchColumns : numros des colonnes tirables
android:shrinkColumns : numros des colonnes reductibles
<TableLayout
android:stretchColumns="1,2"
android:shrinkColumns="0,3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
2.2.13 Groupe
>
de vues RelativeLayout
Cest le plus complexe utiliser mais il donne de bons rsultats. Il permet de spcifier la position
relative de chaque vue laide de paramtres complexes : (LayoutParams)
Tel bord align sur le bord du parent ou centr dans son parent :
android:layout_alignParentTop, android:layout_centerVertical. . .
Tel bord align sur le bord oppos dune autre vue :
android:layout_toRightOf, android:layout_above, android:layout_below. . .
Tel bord align sur le mme bord dune autre vue :
android:layout_alignLeft, android:layout_alignTop. . .
2.2.14 Utilisation
dun RelativeLayout
Pour bien utiliser un RelativeLayout, il faut commencer par dfinir les vues qui ne dpendent que
des bords du Layout : celles qui sont colles aux bords ou centres.
<TextView android:id="@+id/titre"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentLeft="true" .../>
Puis crer les vues qui dpendent des vues prcdentes.
<EditText android:layout_below="@id/titre"
android:layout_alignParentRight="true"
android:layout_alignParentLeft="true" .../>
Et ainsi de suite.
44
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
2.2.15 Autres
groupements
Ce sont les sous-classes de ViewGroup galement prsentes dans cette page. Impossible de faire
linventaire dans ce cours. Cest vous daller explorer en fonction de vos besoins.
2.3
Composants dinterface
2.3.1 Vues
Android propose un grand nombre de vues, dcouvrir en TP :
Textes : titres, saisies
Boutons, cases cocher
Curseurs
Beaucoup ont des variantes. Ex: saisie de texte = no de tlphone ou adresse ou texte avec suggestion
ou . . .
Consulter la doc en ligne de toutes ces vues. On les trouve dans le package android.widget.
noter que les vues voluent avec les versions dAndroid, certaines changent, dautres disparaissent.
2.3.2
TextView
Le plus simple, il affiche un texte statique, comme un titre.
android:text.
Son libell est dans lattribut
<TextView
android:id="@+id/tvtitre"
android:text="@string/titre"
... />
On peut le changer dynamiquement :
TextView tvTitre = (TextView) findViewById(R.id.tvtitre);
tvTitre.setText("blablabla");
2.3.3
Button
Lune des vues les plus utiles est le Button :
<Button
android:id="@+id/btn_ok"
android:text="@string/ok"
... />
En gnral, on dfinit un identifiant pour chaque vue active, ici : android:id="@+id/btn_ok"
Son titre est dans lattribut android:text.
Voir partie suivante , pour son activit : raction un clic.
45
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
2.3.4
Bascules
Les CheckBox sont des cases cocher :
<CheckBox
android:id="@+id/cbx_abonnement_nl"
android:text="@string/abonnement_newsletter"
... />
Les ToggleButton sont une variante :
. On peut dfinir le texte actif et le texte inactif avec
android:textOn et android:textOff.
2.3.5
EditText
Un EditText permet de saisir un texte
<EditText
android:id="@+id/email_address"
android:inputType="textEmailAddress"
... />
Lattribut android:inputType spcifie le type de texte : adresse, tlphone, etc. a dfinit le clavier
qui est propos pour la saisie.
Lire la rfrence Android pour connatre toutes les possibilits.
2.3.6
Autres vues
On reviendra sur toutes ces vues ultrieurement, pour prciser les attributs utiles pour une
application. Dautres vues pourront aussi tre employes loccasion.
2.4
Styles
2.4.1 Styles et thmes
Un style permet de modifier lapparence dune vue :
Police de caractres et tailles pour les textes
Couleurs, images. . .
Gomtrie par dfaut des vues : taille, espacement, remplissage. . .
Un thme est un style appliqu toute une activit ou application.
Consulter la documentation Android.
2.4.2
Dfinir un style
Il faut crer un fichier XML dans res/value :
46
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Elegant"
parent="@android:style/TextAppearance.Medium">
<item name="android:textColor">#010101</item>
<item name="android:typeface">serif</item>
</style>
</resources>
Lattribut name identifie le style, et parent le rattache un autre pour hritage des proprits non
dfinies ici. Voir les styles et les thmes prdfinis.
2.4.3
Utiliser un style
Il suffit de le prciser dans la dfinition de la vue :
<TextView
style="@style/Elegant"
android:text="@string/titre"
2.4.4
/>
Utiliser un thme
Un thme est simplement un style appliqu partout dans lapplication. Cela se spcifie dans le fichier
AndroidManifest.xml :
<application
android:theme="@style/Elegant"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
...>
...
</application>
Attention, si votre style nest pas complet, vous aurez une erreur.
.
47
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Vie dune application
Applications et activits, manifeste : bibliographie
Cycles de vie : voir cette page
Vues, vnements et couteurs : voir ce lien et celui-ci
3.1
Applications et activits
3.1.1 Composition dune application
Une application est compose de plusieurs activits. Chacune gre un cran dinteraction avec
lutilisateur et est dfinie par une classe Java.
Une application complexe peut aussi contenir :
des services : ce sont des processus qui tournent en arrire-plan,
des fournisseurs de contenu : ils reprsentent une sorte de base de donnes, ,
des rcepteurs dannonces : pour grer des vnements globaux envoys par le systme toutes
les applications.
3.1.2
Dclaration dune application
Le fichier AndroidManifest.xml dclare les lments dune application, avec un . devant le nom des activits
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<application android:icon="@drawable/app_icon.png" ...>
<activity android:name=".MainActivity"
... />
<activity android:name=".EditActivity"
... />
...
</application>
</manifest>
<application> est la seule branche sous la racine <manifest> et ses filles sont des <activity>.
48
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
3.1.3
Scurit des applications
Chaque application est associe un UID (compte utilisateur Unix) unique dans le systme. Ce
compte les protge les unes des autres. Cet UID peut tre dfini dans le fichier AndroidManifest.xml :
<?xml version="1.0" encoding="utf-8"?>
<manifest ...
android:sharedUserId="fr.iutlan.demos">
...
</manifest>
Dfinir lattribut android:sharedUserId avec une chane identique une autre application, et signer
les deux applications avec le mme certificat, permet lune daccder lautre.
3.1.4
Autorisations dune application
Une application doit dclarer les autorisations dont elle a besoin : accs internet, camra, carnet
dadresse, GPS, etc.
Cela se fait en rajoutant des lements dans le manifeste :
<manifest ... >
<uses-permission
android:name="android.permission.INTERNET" />
...
</manifest>
Consulter cette page pour la liste des permissions existantes.
3.1.5
Dmarrage dune application
Lune des activits est marque comme dmarrable de lextrieur :
<activity android:name=".MainActivity" ...>
<intent-filter>
<action android:name=
"android.intent.action.MAIN" />
<category android:name=
"android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Un <intent-filter> dclare les conditions de dmarrage dune activit, ici il dit que cest lactivit
principale.
49
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
3.1.6
Dmarrage dune activit et Intents
Les activits sont dmarres laide dIntents. Un Intent contient une demande destine une
activit, par exemple, composer un numro de tlphone ou lancer lapplication.
action : spcifie ce que lIntent demande. Il y en a de trs nombreuses :
VIEW pour afficher quelque chose, EDIT pour modifier une information, SEARCH. . .
donnes : selon laction, a peut tre un numro de tlphone, lidentifiant dune information. . .
catgorie : information supplmentaire sur laction, par exemple, ...LAUNCHER pour lancer une
application.
Une application a la possibilit de lancer certaines activits dune autre application, celles qui ont un
intent-filter.
3.1.7
Lancement dune activit par programme
Soit une application contenant deux activits : Activ1 et Activ2. La premire lance la seconde par :
Intent intent = new Intent(this, Activ2.class);
startActivity(intent);
Linstruction startActivity dmarre Activ2. Celle-ci se met devant Activ1 qui se met alors en
sommeil.
Ce bout de code est employ par exemple lorsquun bouton, un menu, etc. est cliqu. Seule contrainte :
que ces deux activits soient dclares dans AndroidManifest.xml.
3.1.8
Lancement dune application Android
Il nest pas possible de montrer toutes les possibilits, mais par exemple, voici comment ouvrir le
navigateur sur un URL spcifique :
String url =
"https://perso.univ-rennes1.fr/pierre.nerzic/Android";
intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
Laction VIEW avec un URI (gnralisation dun URL) est interprte par Android, cela fait ouvrir
automatiquement le navigateur.
3.1.9
Lancement dune activit dune autre application
Soit une seconde application dans le package fr.iutlan.appli2. Une activit peut la lancer ainsi :
intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setClassName(
"fr.iutlan.appli2",
50
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
"fr.iutlan.appli2.MainActivity");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Cela consiste crer un Intent daction MAIN et de catgorie LAUNCHER pour la classe MainActivity
de lautre application.
3.2
Applications
3.2.1 Fonctionnement dune application
Au dbut, le systme Android lance lactivit qui est marque action=MAIN et catgorie=LAUNCHER
dans AndroidManifest.xml.
Ensuite, dautres activits peuvent tre dmarres. Chacune se met devant les autres comme sur
une pile. Deux cas sont possibles :
La prcdente activit se termine, on ne revient pas dedans.
Par exemple, une activit o on tape son login et son mot de passe lance lactivit principale et
se termine.
La prcdente activit attend la fin de la nouvelle car elle lui demande un rsultat en retour.
Exemple : une activit de type liste ditems lance une activit pour diter un item quand on
clique longuement dessus, mais attend la fin de ldition pour rafrachir la liste.
3.2.2
Navigation entre activits
Voici un schma illustrant les possibilits de navigation parmi plusieurs activits.
3.2.3
Lancement sans attente
Rappel, pour lancer Activ2 partir de Activ1 :
Intent intent = new Intent(this, Activ2.class);
startActivity(intent);
On peut demander la terminaison de this aprs lancement de Activ2 ainsi :
Intent intent = new Intent(this, Activ2.class);
startActivity(intent);
finish();
finish() fait terminer lactivit courante. Lutilisateur ne pourra pas faire back dessus, car elle
disparat de la pile.
3.2.4
Lancement avec attente de rsultat
Le lancement dune activit avec attente de rsultat est plus complexe. Il faut dfinir un code dappel
RequestCode fourni au lancement.
51
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 20: Navigation parmi les activits dune application
52
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
private static final int APPEL_ACTIV2 = 1;
Intent intent = new Intent(this, Activ2.class);
startActivityForResult(intent, APPEL_ACTIV2);
Ce code identifie lactivit lance, afin de savoir plus tard que cest delle quon revient. Par exemple,
on pourrait lancer au choix plusieurs activits : dition, copie, suppression dinformations. Il faut
pouvoir les distinguer au retour.
Consulter cette page.
3.2.5
Lancement avec attente, suite
Ensuite, il faut dfinir une mthode callback qui est appele lorsquon 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
...
}
}
3.2.6
Terminaison dune activit
Lactivit lance par la premire peut se terminer pour deux raisons :
Volontairement, en appelant la mthode finish() :
setResult(RESULT_OK);
finish();
cause du bouton back du tlphone, son action revient faire ceci :
setResult(RESULT_CANCELED);
finish();
Dans ces deux cas, on revient dans lactivit appelante (sauf si elle-mme avait fait finish().
3.2.7
Mthode onActivityResult
Quand on revient dans lactivit appelante, Android lui fait excuter cette mthode :
onActivityResult(int requestCode, int resultCode, Intent data)
requestCode est le code dappel de startActivityForResult
53
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
resultCode vaut soit RESULT_CANCELED soit RESULT_OK, voir le transparent prcdent
data est fourni par lactivit appele et qui vient de se terminer.
Ces deux dernires viennent dun appel setResult(resultCode, data)
3.2.8
Transport dinformations dans un Intent
Les Intent servent aussi transporter des informations dune activit lautre : les extras.
Voici comment placer des donnes dans un Intent :
Intent intent =
new Intent(this, DeleteInfoActivity.class);
intent.putExtra("idInfo",
idInfo);
intent.putExtra("hiddencopy", hiddencopy);
startActivity(intent);
putExtra(nom, valeur) rajoute un couple (nom, valeur) dans lintent. La valeur doit tre srialisable : nombres, chanes et structures simples.
3.2.9
Extraction dinformations dun Intent
Ces instructions rcuprent les donnes dun Intent :
Intent intent = getIntent();
Integer idInfo = intent.getIntExtra("idInfo", -1);
bool hidden = intent.getBooleanExtra("hiddencopy", false);
getIntent() retourne lIntent qui a dmarr cette activit.
getTypeExtra(nom, valeur par dfaut) retourne la valeur de ce nom si elle en fait partie, la
valeur par dfaut sinon.
3.2.10 Contexte
dapplication
Pour finir sur les applications, il faut savoir quil y a un objet global vivant pendant tout le
fonctionnement dune application : le contexte dapplication. Voici comment le rcuprer :
Application context = this.getApplicationContext();
Par dfaut, cest un objet neutre ne contenant que des informations Android.
Il est possible de le sous-classer afin de stocker des variables globales de lapplication.
3.2.11 Dfinition
dun contexte dapplication
Pour commencer, driver une sous-classe de Application :
54
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
public class MonApplication extends Application
{
// variable globale de l'application
public int varglob;
// initialisation du contexte
@Override
public void onCreate()
{
super.onCreate();
varglob = 3;
}
}
3.2.12 Dfinition
dun contexte dapplication, suite
Ensuite, la dclarer dans AndroidManifest.xml, dans lattribut android:name de llment
<application> :
<manifest xmlns:android="..." ...>
<application android:name="MonApplication"
android:icon="@drawable/icon"
android:label="@string/app_name">
...
3.2.13 Dfinition
dun contexte dapplication, fin
Enfin, lutiliser dans nimporte laquelle des activits :
// rcuprer le contexte d'application
MonApplication context =
(MonApplication) this.getApplicationContext();
// utiliser la variable globale
... context.varglob ...
Remarquez la conversion de type.
Il est recommand de dfinir des setters et getters. Dautre part, attention aux variables globales : ne
les utiliser qu bon escient.
3.3
Activits
3.3.1 Prsentation
Voyons maintenant comment fonctionnent les activits.
Dmarrage ( cause dun Intent)
55
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Apparition/masquage sur cran
Terminaison
Une activit se trouve dans lun de ces tats :
active (resumed) : elle est sur le devant, lutilisateur peut jouer avec,
en pause (paused) : partiellement cache et inactive, car une autre activit est venue devant,
stoppe (stopped) : totalement invisible et inactive, ses variables sont prserves mais elle ne
tourne plus.
3.3.2
Cycle de vie dune activit
Ce diagramme rsume les changement dtats dune activit :
Figure 21: Cycle de vie
3.3.3
vnements de changement dtat
La classe Activity reoit des vnements de la part du systme Android, a appelle des fonctions
appeles callbacks.
Exemples :
onCreate Un Intent arrive dans lapplication, il dclenche la cration dune activit, dont linterface.
onPause Le systme prvient lactivit quune autre activit est passe devant, il faut enregistrer les
informations au cas o lutilisateur ne revienne pas.
3.3.4
Squelette dactivit
public class EditActivity extends Activity
{
56
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// met en place les vues de cette activit
setContentView(R.layout.edit_activity);
}
@Override signifie que cette mthode remplace celle hrite de la superclasse. Il faut quand mme
lappeler sur super en premier.
3.3.5
Terminaison dune activit
Voici la prise en compte de la terminaison dfinitive dune activit, avec la fermeture dune base de
donnes :
@Override
public void onDestroy() {
super.onDestroy();
// fermer la base
db.close();
}
En fait, il se peut que cette mthode ne soit jamais appele. Voir onStop plutt.
3.3.6
Pause dune activit
Cela arrive quand une nouvelle activit passe devant, exemple : un appel tlphonique. Il faut librer
les ressources qui consomment de lnergie (animations, GPS. . . ).
@Override public void onPause() {
super.onPause();
// arrter les animations sur l'cran
...
}
@Override public void onResume() {
super.onResume();
// dmarrer les animations
...
}
3.3.7
Arrt dune activit
Cela se produit quand lutilisateur change dapplication dans le slecteur dapplications, ou quil
change dactivit dans votre application. Cette activit nest plus visible et doit enregistrer ses
donnes.
Il y a deux mthodes concernes :
57
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
protected void onStop() : lapplication est arrte, librer les ressources,
protected void onStart() : lapplication dmarre, allouer les ressources.
Il faut comprendre que les utilisateurs peuvent changer dapplication tout moment. La votre doit
tre capable de rsister a.
3.3.8
Enregistrement de valeurs dune excution
lautre
Il est possible de sauver des informations dun lancement lautre de lapplication (certains cas
comme la rotation de lcran ou une interruption par une autre activit), dans un Bundle. Cest un
container de donnes quelconques, sous forme de couples (nom, valeur).
static final String ETAT_SCORE = "ScoreJoueur"; // nom
private int mScoreJoueur = 0;
// valeur
@Override
public void onSaveInstanceState(Bundle etat) {
// enregistrer l'tat courant
etat.putInt(ETAT_SCORE, mScoreJoueur);
super.onSaveInstanceState(etat);
}
3.3.9
Restaurer ltat au lancement
La mthode onRestoreInstanceState reoit un paramtre de type Bundle (comme la mthode
onCreate, mais dans cette dernire, il peut tre null). Il contient ltat prcdemment sauv.
@Override
protected void onRestoreInstanceState(Bundle etat) {
super.onRestoreInstanceState(etat);
// restaurer l'tat prcdent
mScoreJoueur = etat.getInt(ETAT_SCORE);
}
Ces deux mthodes sont appeles automatiquement (sorte dcouteurs), sauf si lutilisateur tue
lapplication. Cela permet de reprendre lactivit l o elle en tait.
3.4
Vues et activits
3.4.1 Obtention des vues
La mthode setContentView charge une disposition sur lcran. Ensuite lactivit peut avoir besoin
daccder aux vues, par exemple lire la chane saisie dans un texte. Pour cela, il faut obtenir lobjet
Java correspondant.
EditText nom = (EditText) findViewById(R.id.edt_nom);
Cette mthode cherche la vue qui possde cet identifiant dans le layout de lactivit. Si cette vue
nexiste pas (mauvais identifiant, ou pas cre), la fonction retourne null.
Un mauvais identifiant peut tre la raison dun bug.
58
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
3.4.2
Proprits des vues
La plupart des vues ont des setters et getters Java pour leurs proprits XML. Par exemple TextView.
En XML :
<TextView android:id="@+id/titre"
android:lines="2"
android:text="@string/debut" />
En Java :
TextView tvTitre = (TextView) findViewById(R.id.titre);
tvTitre.setLines(2);
tvTitre.setText(R.string.debut);
Consulter leur documentation pour les proprits, qui sont extrmement nombreuses.
3.4.3
Actions de lutilisateur
Prenons lexemple de ce Button. Lorsque lutilisateur appuie dessus, cela dclenche un vnement
onClick , et appelle automatiquement la mthode Valider de lactivit.
<Button
android:id="@+id/btn_valider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/valider"
android:onClick="Valider" />
Il faut dfinir la mthode Valider dans lactivit :
public void Valider(View btn) {
...
}
3.4.4
Dfinition dun couteur
Il y a une autre manire de dfinir une rponse un clic : un couteur (listener ). Cest une instance
de classe qui possde la mthode public void onClick(View v) ainsi que spcifi par linterface
View.OnClickListener.
Cela peut tre :
une classe prive anonyme,
une classe prive ou public dans lactivit,
lactivit elle-mme.
Dans tous les cas, on fournit cette instance en paramtre la mthode setOnClickListener du
bouton :
59
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
btn.setOnClickListener(ecouteur);
3.4.5
couteur priv anonyme
Il sagit dune classe qui est dfinie la vole, lors de lappel setOnClickListener. Elle ne contient
quune seule mthode.
Button btn = (Button) findViewById(R.id.btn_valider);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View btn) {
// faire quelque chose
}
});
Employer la syntaxe MonActivity.this pour manipuler les variables et mthodes de lactivit
sous-jacente.
3.4.6
couteur priv
Cela consiste dfinir une classe prive dans lactivit ; cette classe implmente linterface
OnClickListener ; et en fournir une instance en tant qucouteur.
private class EcBtnValider implements OnClickListener {
public void onClick(View btn) {
// faire quelque chose
}
};
public void onCreate(...) {
...
Button btn=(Button)findViewById(R.id.btn_valider);
btn.setOnClickListener(new EcBtnValider());
}
3.4.7
Lactivit elle-mme en tant qucouteur
Il suffit de mentionner this comme couteur et dindiquer quelle implmente linterface
OnClickListener.
implements OnClickListener
Ici, par contre, tous les boutons appelleront la mme mthode.
60
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
3.4.8
Distinction des metteurs
Dans le cas o le mme couteur est employ pour plusieurs vues, il faut les distinguer en se basant
sur leur identitifiant obtenu avec getId() :
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_valider:
...
break;
case R.id.btn_effacer:
...
break;
}
}
3.4.9
vnements des vues courantes
Vous devrez tudier la documentation. Voici quelques exemples :
Button : onClick lorsquon appuie sur le bouton, voir sa doc
Spinner : OnItemSelected quand on choisit un lment, voir sa doc
RatingBar : OnRatingBarChange quand on modifie la note, voir sa doc
etc.
Heureusement, dans le cas de formulaires, les actions sont majoritairement bases sur des boutons.
.
61
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Application liste
Durant les prochaines parties, nous allons nous intresser aux applications de gestion dune liste
ditems.
Stockage dune liste
Affichage dune liste, adaptateurs
Consultation et dition dun item
Figure 22: Liste ditems
4.1
Prsentation
4.1.1 Principe gnral
On veut programmer une application pour afficher et diter une liste ditems.
Dans cette partie, la liste est stocke dans un tableau dynamique appel ArrayList ;
Ultrieurement, a sera dans une base de donnes SQL locale ou sur un serveur distant.
62
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Lcran est occup par un ListView. Cest une vue spcialise dans laffichage de listes
quelconques.
Consulter cette documentation sur les ListView.
4.1.2
Schma global
Lintermdiaire entre la liste et la vue est gr par un adaptateur, objet qui sait comment afficher un
item dans le ListView.
Figure 23: Vue, adaptateur et donnes
4.1.3
Une classe pour reprsenter les items
Pour commencer, une classe pour reprsenter les items :
public class Planete {
public String mNom;
public int mDistance;
Planete(String nom, int distance) {
mNom = nom;
// nom de la plante
mDistance = distance; // distance au soleil en Gm
}
public String toString() {
return mNom;
}
};
4.1.4
Donnes initiales
Deux solutions pour initialiser la liste avec des items prdfinis :
Un tableau dans les ressources, voir page 64,
63
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Un tableau Java comme ceci :
final Planete[] initdata = {
new Planete("Mercure", 58),
new Planete("Vnus", 108),
new Planete("Terre", 150),
...
};
final signifie constant, sa valeur ne changera plus.
4.1.5
Copie dans un ArrayList
Ltape suivante consiste recopier les valeurs initiales dans un tableau dynamique de type
ArrayList<Planete> :
protected ArrayList<Planete> mliste;
void onCreate(...)
{
...
// cration du tableau dynamique
mListe = new ArrayList<Planete>();
// boucle amliore Java7
for (Planete planete: initdata) {
mListe.add(planete);
}
}
4.1.6
Le container Java ArrayList<type>
Cest un type de donnes gnrique, cest dire paramtr par le type des lments mis entre <. . . > ;
ce type doit tre un objet.
import java.util.ArrayList;
ArrayList<TYPE> liste = new ArrayList<TYPE>();
Quelques mthodes utiles :
liste.size() : retourne le nombre dlments prsents,
liste.clear() : supprime tous les lments,
liste.add(elem) : ajoute cet lment la liste,
liste.remove(elem ou indice) : retire cet lment
liste.get(indice) : retourne llment prsent cet indice,
liste.contains(elem) : true si elle contient cet lment,
liste.indexOf(elem) : indice de llment, sil y est.
64
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
4.1.7
Donnes initiales dans les ressources
On cre deux tableaux dans le fichier res/values/arrays.xml :
<resources>
<string-array name="noms">
<item>Mercure</item>
<item>Venus</item>
...
</string-array>
<integer-array name="distances">
<item>58</item>
<item>108</item>
...
</integer-array>
</resources>
4.1.8
Donnes dans les ressources, suite
Ensuite, on rcupre ces tableaux pour remplir le ArrayList :
// accs aux ressources
Resources res = getResources();
final String[] noms = res.getStringArray(R.array.noms);
final int[] distances = res.getIntArray(R.array.distances);
// recopie dans le ArrayList
mListe = new ArrayList<Planete>();
for (int i=0; i<noms.length; ++i) {
mListe.add(new Planete(noms[i], distances[i]));
}
4.1.9
Remarques
Dans cette partie, les donnes sont reprsentes dans un tableau. Dans les exemples prcdents,
cest une variable membre de lactivit. Pour faire mieux que cela, il faut dfinir une Application
comme auparavant et mettre ce tableau ainsi que son initialisation dedans. Ainsi, le tableau devient
disponible dans toutes les activits de lapplication. Voir le TP4.
Ultrieurement, nous verrons comment utiliser une base de donnes SQL locale ou un WebService,
ce qui rsoud proprement le problme.
4.2
Affichage de la liste
4.2.1 Activit spcialise ou layout
Deux possibilits :
65
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
employer la classe ListActivity,
66
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
employer la classe Activity de base.
Ces deux possibilits sont trs similaires : un layout contenant un ListView pour lactivit, un layout
pour les items de la liste et un adaptateur pour accder aux donnes.
La ListActivity prpare un peu plus de choses pour grer les slections ditems, tandis quavec une
simple Activity, cest nous de tout faire, voir page 73. Par exemple, si on rajoute un TextView
particulier, on peut avoir un message La liste est vide .
4.2.2
Mise en uvre
Que ce soit avec une ListActivity ou avec une Activity de base, deux choses sont faire :
1. Crer un layout pour lcran ; il doit contenir un ListView identifi par @android:id/list,
2. Crer un layout pour un item ; il doit contenir un TextView identifi par @android:id/text1,
Consulter la documentation.
4.2.3
Layout de lactivit pour affi her une liste
Voici dabord le layout dcran. Jai rajout le TextView qui affiche Liste vide . Notez les identifiants
spciaux.
<LinearLayout xmlns:android="..."
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView android:id="@android:id/empty"
android:text="Liste vide"
... />
</LinearLayout>
On peut rajouter dautres vues : boutons. . .
4.2.4
Mise en place du layout dactivit
Classiquement :
@Override
protected void onCreate(Bundle savedInstanceState)
{
// appeler la mthode surcharge dans la superclasse
super.onCreate(savedInstanceState);
// mettre en place le layout contenant le ListView
setContentView(R.layout.main);
67
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
// initialisation de la liste
mListe = new ArrayList<Planete>();
...
4.2.5
Layout pour un item
Ensuite, le layout res/layout/item.xml pour afficher un item. Lidentifiant du TextView devient
android.R.id.text1 en Java.
<LinearLayout xmlns:android="..."
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="@android:id/text1"
android:textStyle="bold"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
4.2.6
Autre layouts
Il est possible de crer des dispositions plus complexes pour les items mais alors il faudra programmer
un adaptateur spcifique.
Figure 24: Layout complexe
<RelativeLayout xmlns:android="..." ...>
<ImageView android:id="@+id/item_planete_image" .../>
<TextView android:id="@+id/item_planete_nom" .../>
<TextView android:id="@+id/item_planete_distance" .../>
</RelativeLayout>
Voir les adaptateurs personnaliss, page 69.
4.2.7
Layouts prdfinis
Android dfinit des layouts pour des lments de listes simples :
android.R.layout.simple_list_item_1
Cest un layout qui affiche un seul TextView. Son identifiant est android.R.id.text1,
android.R.layout.simple_list_item_2
Cest un layout qui affiche deux TextView : un titre en grand et un sous-titre. Ses identifiants
sont android.R.id.text1 et android.R.id.text2.
Il suffit de les fournir ladaptateur. Il ny a pas besoin de crer des fichiers XML, ni pour lcran, ni
pour les items.
68
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
4.3
Adaptateurs
4.3.1 Relations entre la vue et les donnes
Un ListView affiche les items laide dun adaptateur (adapter ).
Figure 25: Adaptateur entre les donnes et la vue
4.3.2
Rle dun adaptateur
Ladaptateur rpond la question que pose le ListView : que dois-je afficher tel endroit dans la
liste ? . Il va chercher les donnes et instancie le layout ditem avec les valeurs.
Cest une classe qui :
accde aux donnes laide de mthodes telles que getItem(int position), getCount(),
isEmpty() quelque soit le type de stockage des lments : tableau, BDD. . .
cre les vues daffichage des items : getView(...) laide du layout des items. Cela consiste
instancier le layout on dit expanser le layout, inflate en anglais.
4.3.3
Adaptateurs prdfinis
Android propose quelques classes dadaptateurs prdfinis, dont :
ArrayAdapter pour un tableau simple (liste dynamique),
SimpleCursorAdapter pour accder une base de donnes, quon verra ultrieurement.
En gnral, dans une application innovante, il faut dfinir son propre adaptateur, voir page 69, mais
commenons par un ArrayAdapter standard.
4.3.4
ArrayAdapter<Type> pour les listes
Il permet dafficher les donnes dun ArrayList, mais il est limit une seule chane par item, par
exemple le nom dune plante, fournie par sa mthode toString(). Son constructeur :
ArrayAdapter(Context context, int item_layout_id, int textview_id, List<T> donnes)
68
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
context cest lactivit qui cre cet adaptateur, mettre this
item_layout_id identifiant du layout des items, p. ex. android.R.layout.simple_list_item_1
ou R.layout.item_planete
textview_id identifiant du TextView dans ce layout, p. ex.
android.R.id.text1
ou
R.id.item_planete_nom
donnes cest la liste contenant les donnes (List est une surclasse de ArrayList)
4.3.5
Exemple demploi
Suite de la mthode onCreate de lactivit, on fournit la ArrayList<Planete> mListe au constructeur dadaptateur :
// crer un adaptateur standard pour mListe
ArrayAdapter<Planete> adapter =
new ArrayAdapter<Planete>(this,
R.layout.item_planete,
R.id.item_planete_nom,
mListe);
// associer la liste affiche et l'adaptateur
ListView lv = (ListView) findViewById(android.R.id.list);
lv.setAdapter(adapter);
La classe Planete doit avoir une mthode toString(), cf page 62. Cet adaptateur naffiche que le
nom de la plante, rien dautre.
4.3.6
Affichage avec une ListActivity
Si lactivit est une ListActivity, la fin est peu plus simple :
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mListe = new ArrayList<Planete>();
...
ArrayAdapter<Planete> adapter = new ArrayAdapter...
// association liste - adaptateur
setListAdapter(adapter);
}
4.3.7
Exemple avec les layouts standards
Avec les layouts ditems standards Android, cela donne :
69
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
// crer un adaptateur standard pour mListe
ArrayAdapter<Planete> adapter =
new ArrayAdapter<Planete>(this,
android.R.layout.simple_list_item_1,
android.R.id.text1,
mListe);
// associer la liste affiche et l'adaptateur
setListAdapter(adapter);
Le style daffichage est minimaliste, seulement la liste des noms. On ne peut pas afficher deux
informations avec un ArrayAdapter.
4.4
Adaptateur personnalis
4.4.1 Classe Adapter personnalise
Parce que ArrayAdapter naffiche quun seul texte, nous allons dfinir notre propre adaptateur :
PlaneteAdapter.
Il faut le faire hriter de ArrayAdapter<Planete> pour ne pas tout reprogrammer :
public class PlaneteAdapter extends ArrayAdapter<Planete>
{
public PlaneteAdapter(Context context,
List<Planete> planetes)
{
super(context, 0, planetes);
}
Source biblio : http://www.bignerdranch.com/blog/customizing-android-listview-rows-subclassing
4.4.2
Classe Adapter perso, suite
Sa principale mthode est getView qui cre les vues pour le ListView. Elle retourne une disposition,
p. ex. un RelativeLayout contenant des TextView et ImageView.
public
View getView(int position, View recup, ViewGroup parent);
position est le numro, dans le ListView, de litem afficher.
recup est une ancienne vue devenue invisible dans le ListView. Cest une technique pour
diminuer les allocations mmoire, on rcupre une vue inutile au lieu den allouer une nouvelle.
NB: elle sappelle convertView dans les docs.
parent : le ListView auquel sera rattach cette vue.
70
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
4.4.3
Mthode getView personnalise
Voici la surcharge de cette mthode :
@Override
public View
getView(int position, View recup, ViewGroup parent)
{
// crer ou rcuprer un PlaneteView
PlaneteView vueItem = (PlaneteView) recup;
if (vueItem == null)
vueItem = PlaneteView.create(parent); // <==(!!)
// afficher les valeurs
vueItem.display(super.getItem(position));
return vueItem;
}
4.4.4
Mthode PlaneteView.create
Cette mthode cre une instance de PlaneteView. Cest un groupe de vues qui affiche un seul item
des donnes.
Le PlaneteAdapter cre des PlaneteView la demande du ListView,
Un PlaneteView est une sorte de RelativeLayout contenant des TextView et ImageView
Figure 26:
Cette disposition est dfinie par un fichier layout XML res/layout/item_planete.xml.
Lensemble des donnes est affich par plusieurs instances de PlaneteView dans le ListView.
4.4.5
Layout ditem res/layout/item_planete.xml
Cest subtil : on va remplacer la racine du layout des items, un RelativeLayout par une classe
personnalise :
<?xml version="1.0" encoding="utf-8"?>
<fr.iutlan.planetes.PlaneteView
xmlns:android="..."
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
Et cette classe PlaneteView hrite de RelativeLayout :
71
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
package fr.iutlan.planetes;
public class PlaneteView extends RelativeLayout
{
...
4.4.6
Classe personnalise dans les ressources
Android permet dutiliser les classes de notre application lintrieur dun layout. Il suffit de les
prfixer par le package.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="..."
android:layout_width="match_parent"
android:layout_height="wrap_content">
<fr.iutlan.customviews.MaVuePerso
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
La classe MaVuePerso doit hriter de View et implmenter certaines mthodes.
4.4.7
Classe PlaneteView pour affi her les items
Cette classe a pour but de grer les vues dans lesquelles il y a les informations des plantes : nom,
distance, image.
On la met la place du RelativeLayout dans res/layout/item_planete.xml :
<?xml version="1.0" encoding="utf-8"?>
<fr.iutlan.planetes.PlaneteView .../>
<ImageView android:id="@+id/item_planete_image" .../>
<TextView android:id="@+id/item_planete_nom" .../>
<TextView android:id="@+id/item_planete_distance" .../>
</fr.iutlan.planetes.PlaneteView>
Les proprits de placement restent les mmes.
4.4.8
Dfinition de la classe PlaneteView
Le constructeur de PlaneteView est ncessaire, mais quasi-vide :
public class PlaneteView extends RelativeLayout
{
public PlaneteView(Context context, ...) {
super(context, attrs);
}
Tout se passe dans la mthode de classe PlaneteView.create appele par ladaptateur. Rappel de
la page 70 :
72
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
// crer ou rcuprer un PlaneteView
PlaneteView vueItem = (PlaneteView) recup;
if (vueItem == null) vueItem = PlaneteView.create(parent);
...
Cette mthode create gnre les vues du layout item.xml.
4.4.9
Crer des vues avec un layout XML
La gnration de vues pour afficher les items repose sur un mcanisme appel LayoutInflater qui
fabrique des vues Android partir dun layout XML :
LayoutInflater li = LayoutInflater.from(context);
View vueItem = li.inflate(R.layout.item_planete, parent);
On lui fournit lidentifiant du layout, p. ex. celui des items. Elle cre les vues spcifies dans
res/layout/item_planete.xml.
context est lactivit qui affiche toutes ces vues,
parent est la vue qui doit contenir ces vues, null si aucune.
4.4.10 Mthode
PlaneteView.create
La mthode de classe PlaneteView.create expanse le layout des items laide dun LayoutInflater :
public static PlaneteView create(ViewGroup parent)
{
LayoutInflater li =
LayoutInflater.from(parent.getContext());
PlaneteView itemView = (PlaneteView)
li.inflate(R.layout.item_planete,
parent,
false);
itemView.findViews();
return itemView;
}
static signifie quon appelle cette mthode sur la classe elle-mme et non pas sur une instance. Cest
une mthode de classe.
4.4.11 Mthode
findViews
Cette mthode a pour but de rcuprer les objets Java des TextView et ImageView de litem. Elle les
recherche avec leurs proprits android:id.
private void findViews()
{
tvNom = (TextView) findViewById(R.id.item_planete_nom);
tvDistance = (TextView) findViewById(
73
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
R.id.item_planete_distance);
ivImage = (ImageView) findViewById(
R.id.item_planete_image);
}
Ces trois variables sont des membres dinstance du PlaneteView.
4.4.12 Pour
finir, la mthode PlaneteView.display
Son rle est dafficher les informations dune plante dans les TextView et ImageView de litem.
public void display(final Planete planete)
{
tvNom.setText(planete.getNom());
tvDistance.setText(
Integer.toString(planete.getDistance())
+ " millions de km");
ivImage.setImageResource(planete.getIdImage());
}
Elle utilise les getters de la classe Planete : getNom. . .
4.4.13 Rcapitulatif
Voici la squence qui amne laffichage dun item dans la liste :
1. Le ListView appelle la mthode getView(position, ...) de ladaptateur, position est le
no de llment concern,
2. Ladaptateur appelle ventuellement PlaneteView.create :
a. PlaneteView.create fait instancier item.xml = une sous-classe de RelativeLayout
appele PlaneteView.
b. Cela cre les vues nom, distance et image dont PlaneteView.findViews rcupre les
objets Java.
3. Ladaptateur appelle la mthode display du PlaneteView avec les donnes afficher.
a. PlaneteView.display appelle setText des vues pour afficher les valeurs.
4.4.14 Le
rsultat
4.5 Actions utilisateur sur la liste
4.5.1 Modification des donnes
Les modifications sur les donnes doivent se faire par les mthodes add, insert, remove et clear de
ladaptateur. Voir la doc.
Si ce nest pas possible, par exemple parce quon a chang dactivit et modifi les donnes sans
adaptateur, alors au retour, par exemple dans onActivityResult, il faut prvenir ladaptateur par
la mthode suivante :
74
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 27: Liste ditems
adapter.notifyDataSetChanged();
4.5.2
Clic sur un lment
Voyons le traitement des slections utilisateur sur une liste. La classe ListActivity dfinit dj un
couteur pour les clics. Il suffit de le surcharger :
@Override
public void onListItemClick (
ListView l, View v, int position, long id)
{
// grer un clic sur l'item identifi par id
...
}
Par exemple, crer un Intent pour afficher ou diter litem.
adapter.notifyDataSetChanged(); au retour.
4.5.3
Ne pas oublier dappeler
Clic sur un lment, suite
Si votre activit est une simple Activity (parce quil y a autre chose quune liste, ou plusieurs listes),
alors cest plus complexe :
Votre activit doit implmenter linterface AdapterView.OnItemClickListener,
75
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Vous devez dfinir this en tant qucouteur du ListView,
Votre activit doit surcharger la mthode onItemClick.
4.5.4
Clic sur un lment, suite
public class MainActivity extends Activity
implements OnItemClickListener
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
// appeler la mthode surcharge dans la superclasse
super.onCreate(savedInstanceState);
// mettre en place le layout contenant le ListView
setContentView(R.layout.main);
ListView lv=(ListView)findViewById(android.R.id.list);
lv.setOnItemClickListener(this);
}
4.5.5
Clic sur un lment, fin
Et voici sa mthode onItemClick :
@Override
public void onItemClick(
AdapterView<?> parent, View v, int position, long id)
{
// grer un clic sur l'item identifi par id
...
}
Il existe aussi la mthode boolean onItemLongClick ayant les mmes paramtres, installe par
setOnItemLongClickListener.
4.5.6
Liste dlments cochables
Android offre des listes cochables comme celles-ci :
Le style de la case cocher dpend du choix unique ou multiple.
4.5.7
Liste cochable simple
Android propose un layout prdfini pour items cochables :
76
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 28: lments cochables
@Override
protected void onCreate(Bundle savedInstanceState)
{
...
setListAdapter(
new ArrayAdapter<Planete>(this
android.R.layout.simple_list_item_checked,
android.R.id.text1,
mListe));
ListView
lv=(ListView)findViewById(android.R.id.list);
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}
4.5.8
Liste choix multiples
Toujours avec des listes prdfinies, cest une simple variante :
mettre simple_list_item_multiple_choice la place de simple_list_item_checked,
mettre ListView.CHOICE_MODE_MULTIPLE au lieu de ListView.CHOICE_MODE_SINGLE.
La mthode onListItemClick est appele sur chaque lment cliqu.
4.5.9
Liste cochable personnalise
Si on veut un layout personnalis comme PlaneteView, il faut que sa classe implmente linterface
Checkable cd 3 mthodes :
public boolean isChecked() indique si litem est coch
public void setChecked(boolean etat) doit changer ltat interne de litem
public void toggle() doit inverser ltat interne de litem
Il faut rajouter un boolen dans chaque item, celui que jai appel tat interne.
Dautre part, dans le layout ditem, il faut employer un CheckedTextView mme vide, plutt quun
CheckBox qui ne ragit pas aux clics (bug Android).
77
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
78
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Ergonomie
Ergonomie dune application Android.
Menus et barre daction
Popup-up : messages et dialogues
Activits et fragments
Prfrences
5.1
Barre daction et menus
5.1.1 Barre daction
La barre daction contient licne dapplication (1), quelques items de menu (2) et un bouton pour
avoir les autres (3).
Figure 29: Barre daction
5.1.2
Ralisation dun menu
Avant Android 3.0 (API 11), les actions dune application taient lances avec un bouton de menu,
mcanique. Depuis, elles sont dclenches par la barre daction. Cest presque la mme chose.
Le principe gnral : un menu est une liste ditems qui apparat soit quand on appuie sur le bouton
menu, soit sur la barre daction. Certains de ces items sont prsents en permanence dans la barre
daction. La slection dun item dclenche une callback. Doc Android sur la barre daction et sur les
menus
Il faut dfinir :
un fichier res/menu/nom_du_menu.xml,
des thmes pour afficher soit la barre daction, soit des menus,
deux callbacks pour grer les menus : cration et activation.
79
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
5.1.3
Spcification dun menu
Crer res/menu/nom_du_menu.xml :
<menu xmlns:android="..." >
<item android:id="@+id/menu_creer"
android:icon="@drawable/ic_menu_creer"
android:showAsAction="ifRoom"
android:title="@string/menu_creer"/>
<item android:id="@+id/menu_chercher" ... />
...
</menu>
Chaque <item> : identifiant, icne et titre, ainsi que lattribut showAsAction valant "always",
"ifRoom" ou "never" selon la visibilit quon souhaite dans la barre daction.
5.1.4
Icnes pour les menus
Android distribue gratuitement un grand jeu dicnes pour les menus, dans les deux styles : HoloDark
et HoloLight.
Figure 30: Icnes de menus
Consulter la page Downloads pour des tlchargements gratuits de toutes sortes de modles et feuilles
de styles.
Tlchargez Action Bar Icon Pack pour amliorer vos applications.
5.1.5
Thme pour une barre daction
Les thmes permettent dafficher soit une barre daction, soit un menu ancien style. Ils sont dfinis
dans trois dossiers :
res\values\styles.xml
res\values-v11\styles.xml
res\values-v14\styles.xml
En rsum, il faut indiquer que votre application gre les barres daction. Voici par exemple pour la
V11 :
80
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
<resources>
<style name="AppBaseTheme"
parent="android:Theme.Holo.Light"
</resources>
/>
Utiliser lassistant pour avoir les thmes adquats.
5.1.6
couteurs pour les menus
Il faut programmer deux mthodes. Lune affiche le menu, lautre ragit quand lutilisateur slectionne
un item. Voici la premire :
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.nom_du_menu, menu);
return true;
}
Cette mthode rajoute les items du menu dfini dans le XML.
Un MenuInflater est un lecteur/traducteur de fichier XML en vues ; sa mthode inflate cre les
vues.
5.1.7
Ractions aux slections ditems
Voici la seconde callback, cest un aiguillage selon litem choisi :
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_creer:
...
return true;
case R.id.menu_chercher:
...
return true;
...
default: return super.onOptionsItemSelected(item);
}
}
5.1.8
Menus en cascade
Dfinir deux niveaux quand la barre daction est trop petite :
81
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
<menu xmlns:android="..." >
<item android:id="@+id/menu_item1" ... />
<item android:id="@+id/menu_item2" ... />
<item android:id="@+id/menu_more"
android:icon="@drawable/ic_action_overflow"
android:showAsAction="always"
android:title="@string/menu_more">
<menu>
<item android:id="@+id/menu_item3" ... />
<item android:id="@+id/menu_item4" ... />
</menu>
</item>
</menu>
5.1.9
Menus contextuels
Figure 31: MenuContextuel
Ces menus apparaissent lors un clic long sur un lment de liste. Le principe est le mme que pour
les menus normaux :
Attribuer un couteur lvnement onCreateContextMenu. Cet vnement correspond un
clic long et au lieu dappeler la callback du clic long, a fait apparatre le menu.
Dfinir la callback de lcouteur : elle expanse un layout de menu.
Dfinir la callback des items du menu.
5.1.10 Associer
un menu contextuel une vue
Cela se passe par exemple dans la mthode onCreate dune activit :
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView lv = (ListView)findViewById(android.R.id.list);
registerForContextMenu(lv);
...
Au lieu de registerForContextMenu(lv); on peut aussi faire :
82
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
lv.setOnCreateContextMenuListener(this);
5.1.11 Callback
daffichage du menu
Quand lutilisateur fait un clic long, cela dclenche cette mthode :
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo)
{
super.onCreateContextMenu(menu, v, menuInfo);
getMenuInflater().inflate(R.menu.main_context, menu);
}
Son rle est dexpanser (inflate) le menu res/menu/main_context.
5.1.12 Callback
des items du menu
Pour finir, si lutilisateur choisit un item du menu :
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info =
(AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case R.id.editer:
onMenuEditer(info.id); // identifiant de l'lment
return true;
case R.id.supprimer:
onMenuSupprimer(info.id);
return true;
}
return false;
}
Lobjet AdapterContextMenuInfo info permet davoir lidentifiant de ce qui est slectionn, qui a
fait apparatre le menu contextuel.
5.2
Annonces et dialogues
5.2.1 Annonces : toasts
Un toast est un message apparaissant en bas dcran pendant un instant, par exemple pour
confirmer la ralisation dune action. Un toast naffiche aucun bouton et nest pas actif.
Voici comment lafficher avec une ressource chane :
83
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 32: Toast
Toast.makeText(getApplicationContext(),
R.string.item_supprime, Toast.LENGTH_SHORT).show();
La dure daffichage peut tre allonge avec LENGTH_LONG.
5.2.2
Annonces personnalises
Il est possible de personnaliser une annonce.
Il faut seulement dfinir un layout dans
res/layout/toast_perso.xml. La racine de ce layout doit avoir un identifiant, ex : toast_perso_id
qui est mentionn dans la cration :
// expanser le layout du toast
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.toast_perso,
(ViewGroup)
findViewById(R.id.toast_perso_id));
// crer le toast et l'afficher
Toast toast = new Toast(getApplicationContext());
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
toast.show();
5.2.3
Dialogues
Un dialogue est une petite fentre qui apparat au dessus dun cran pour afficher ou demander
quelque chose durgent lutilisateur, par exemple une confirmation.
Figure 33: Dialogue dalerte
Il existe plusieurs sortes de dialogues :
Dialogues dalerte
Dialogues gnraux
84
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
5.2.4
Dialogue dalerte
Un dialogue dalerte AlertDialog affiche un texte et un trois boutons au choix : ok, annuler, oui,
non, aide. . .
Un dialogue dalerte est construit laide dune classe nomme AlertDialog.Builder. Le principe
est de crer un builder et cest lui qui cre le dialogue. Voici le dbut :
Builder confirm = new AlertDialog.Builder(this);
confirm.setTitle("Suppression");
confirm.setIcon(android.R.drawable.ic_dialog_alert);
confirm.setMessage("Vous confirmez la suppression ?");
Ensuite, on rajoute les boutons et leurs couteurs.
5.2.5
Boutons et affichage dun dialogue dalerte
Le builder permet de rajouter toutes sortes de boutons : oui/non, ok/annuler. . . Cela se fait avec des
fonctions comme celle-ci. On peut associer un couteur (anonyme priv ou . . . ) ou aucun.
// rajouter un bouton "oui" qui supprime vraiment
confirm.setPositiveButton(android.R.string.yes,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int idBtn) {
SupprimerElement(idElement);
}
});
// rajouter un bouton "non" qui ne fait rien
confirm.setNegativeButton(android.R.string.no, null);
// affichage du dialogue
confirm.show();
5.2.6
Autres types de dialogues dalerte
Dans un dialogue dalerte, au lieu de boutons, il est possible dafficher une liste de propositions
prdfinies. Pour cela :
Dfinir une ressource de type tableau de chanes res/values/arrays.xml :
<resources>
<string-array name="notes">
<item>Nul</item>
<item>a le fait</item>
<item>Trop cool</item>
</string-array>
</resources>
Appeler la mthode confirm.setItems(R.array.notes, couteur). Lcouteur est le mme
que pour un clic. Il reoit le numro du choix en 2e paramtre idBtn.
Dans ce cas, ne pas appeler confirm.setMessage car ils sont exclusifs. Cest soit une liste, soit un
message.
85
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
5.2.7
Dialogues personnaliss
Lorsquil faut demander une information plus complexe lutilisateur, mais sans que a ncessite une
activit part entire, il faut faire appel un dialogue personnalis.
Figure 34: Dialogue perso
5.2.8
Cration dun dialogue
Il faut dfinir le layout du dialogue incluant tous les textes, sauf le titre, et au moins un bouton pour
valider, sachant quon peut fermer le dialogue avec le bouton back.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="..." ...>
<TextView android:id="@+id/dialog_titre" .../>
<EditText android:id="@+id/dialog_libelle" .../>
<Button android:id="@+id/dialog_btn_valider" ... />
</LinearLayout>
Ensuite cela ressemble ce quon fait dans onCreate dune activit : setContentView avec le layout
et des setOnClickListener pour attribuer une action aux boutons.
5.2.9
Affichage du dialogue
// crer le dialogue
final Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.edit_dialog);
dialog.setTitle("Cration d'un type");
// bouton valider
Button btnValider =
(Button) dialog.findViewById(R.id.dialog_btn_valider);
btnValider.setOnClickListener(new OnClickListener() {
@Override public void onClick(View v) {
dialog.dismiss();
// fermer le dialogue
...
}
});
// afficher le dialogue
dialog.show();
86
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
5.3
Fragments et activits
5.3.1 Fragments
Depuis Android 4, les dialogues doivent tre grs par des instances de DialogFragment qui sont
des sortes de fragments, voir cette page. Cela va plus loin que les dialogues. Toutes les parties des
interfaces dune application sont susceptibles de devenir des fragments :
liste ditems
affichage des infos dun item
dition dun item
Un fragment est une sorte de mini-activit. Dans le cas dun dialogue, elle gre laffichage et la vie du
dialogue. Dans le cas dune liste, elle gre laffichage et les slections des lments.
5.3.2
Tablettes, smartphones. . .
Une interface devient plus souple avec des fragments. Selon la taille dcran, on peut afficher une liste
et les dtails, ou sparer les deux.
Figure 35: Diffrentes apparences
5.3.3
Structure dun fragment
Un fragment est une activit trs simplifie. Cest seulement un arbre de vue dfini par un layout, et
des couteurs. Un fragment minimal est :
87
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
public class InfosFragment extends Fragment
{
public InfosFragment() {}
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(
R.layout.infos_fragment, container, false);
}
}
5.3.4
Diffrents types de fragments
Il existe diffrents types de fragments, voici quelques uns :
ListFragment pour afficher une liste ditems, comme le ferait une ListActivity.
DialogFragment pour afficher un fragment dans une fentre flottante au dessus dune activit.
PreferenceFragment pour grer les prfrences.
En commun : il faut surcharger la mthode onCreateView qui dfinit leur contenu.
5.3.5
Cycle de vie des fragments
Les fragments ont un cycle de vie similaire celui des activits, avec quelques mthodes de plus
correspondant leur intgration dans une activit.
Figure 36: Cycle de vie dun fragment
5.3.6
ListFragment
Par exemple, voici lattribution dun layout standard pour la liste :
88
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
@Override
setHasOptionsMenu(true);
5.3.7
ListFragment, suite
Voici la suite, le remplissage de la liste et lattribution dun couteur pour les clics sur les lments :
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
// adaptateur standard pour la liste
ArrayAdapter<Item> adapter = new ArrayAdapter<Item>(
getActivity(),
android.R.layout.simple_list_item_1,
listeItems);
setListAdapter(adapter);
// attribuer un couteur pour les clics sur les items
ListView lv = getListView();
lv.setOnItemClickListener(this);
}
5.3.8
Menus de fragments
Un fragment peut dfinir un menu. Ses lments sont intgrs la barre daction de lactivit. Seule
la mthode de cration du menu diffre, linflater arrive en paramtre :
@Override
public void onCreateOptionsMenu(
Menu menu, MenuInflater menuInflater)
{
super.onCreateOptionsMenu(menu, menuInflater);
menuInflater.inflate(R.menu.edit_fragment,
menu);
}
NB: dans la mthode onCreateView du fragment, il faut rajouter setHasOptionsMenu(true);
89
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
5.3.9
Intgrer un fragment dans une activit
De lui-mme, un fragment nest pas capable de safficher. Il ne peut apparatre que dans le cadre
dune activit, comme une sorte de vue interne. On peut le faire de deux manires :
statiquement : les fragments afficher sont prvus dans le layout de lactivit. Cest le plus
simple faire et comprendre.
dynamiquement : les fragments sont ajouts, enlevs ou remplacs en cours de route selon les
besoins.
5.3.10 Fragments
statiques dans une activit
Dans ce cas, cest le layout de lactivit qui inclut les fragments, p. ex. res/layout-land/main_activity.xml.
Ils ne peuvent pas tre modifis ultrieurement.
<LinearLayout ... android:orientation="horizontal" ... >
<fragment
android:id="@+id/frag_liste"
android:name="fr.iutlan.fragments.ListeFragment"
... />
<fragment
android:id="@+id/frag_infos"
android:name="fr.iutlan.fragments.InfosFragment"
... />
</LinearLayout>
Chaque fragment doit avoir un identifiant et un nom complet.
5.3.11 FragmentManager
Pour dfinir des fragments dynamiquement, on fait appel au FragmentManager de lactivit. Il gre
laffichage des fragments. Lajout et la suppression de fragments se fait laide de transactions. Cest
simplement lassociation entre un rceptacle (un FrameLayout vide) et un fragment.
Soit un layout contenant deux FrameLayout vides :
<LinearLayout xmlns:android="..."
android:orientation="horizontal" ... >
<FrameLayout android:id="@+id/frag_liste" ... />
<FrameLayout android:id="@+id/frag_infos" ... />
</LinearLayout>
On peut dynamiquement attribuer un fragment chacun.
5.3.12 Attribution
dun fragment dynamiquement
En trois temps : obtention du manager, cration dune transaction et attribution des fragments aux
rceptacles .
90
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
// gestionnaire
FragmentManager manager = getFragmentManager();
// transaction
FragmentTransaction trans = manager.beginTransaction();
// mettre les fragments dans les rceptacles
trans.add(R.id.frag_liste, new ListeFragment());
trans.add(R.id.frag_infos, new InfosFragment());
trans.commit();
Les FrameLayout sont remplacs par les fragments.
5.3.13 Disposition
selon la gomtrie de lcran
Le plus intressant est de faire apparatre les fragments en fonction de la taille et lorientation de
lcran (application liste + infos ).
Figure 37: Un ou deux fragments affichs
5.3.14 Changer
la disposition selon la gomtrie
Pour cela, il suffit de dfinir deux layouts (dfinition statique) :
res/layout-port/main_activity.xml en portrait :
<LinearLayout xmlns:android="..."
android:orientation="horizontal" ... >
<fragment android:id="@+id/frag_liste" ... />
</LinearLayout>
res/layout-land/main_activity.xml en paysage :
91
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
<LinearLayout xmlns:android="..."
android:orientation="horizontal" ... >
<fragment android:id="@+id/frag_liste" ... />
<fragment android:id="@+id/frag_infos" ... />
</LinearLayout>
5.3.15 Deux
dispositions possibles
Lorsque la tablette est verticale, le layout de layout-port est affich et lorsquelle est horizontale,
cest celui de layout-land.
Lactivit peut alors faire un test pour savoir si le fragment frag_infos est affich :
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
FragmentManager manager = getFragmentManager();
InfosFragment frag_infos = (InfosFragment)
manager.findFragmentById(R.id.frag_infos);
if (frag_infos != null) {
// le fragment des informations est prsent
...
}
5.3.16 Communication
entre Activit et Fragments
Lorsque lutilisateur clique sur un lment de la liste du fragment frag_liste, cela doit afficher ses
informations :
dans le fragment frag_infos sil est prsent,
ou lancer une activit daffichage spare si le fragment nest pas prsent (layout vertical).
Cela implique plusieurs petites choses :
Lcouteur des clics sur la liste est le fragment frag_liste. Il doit transmettre litem cliqu
lactivit.
Lactivit doit dterminer si le fragment frag_infos est affich :
sil est visible, elle lui transmet litem cliqu
sinon, elle lance une activit spcifique, InfosActivity.
Voici les tapes.
5.3.17 Interface
pour un couteur
Dabord la classe ListeFragment : dfinir une interface pour grer les slections ditems et un
couteur :
92
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
public interface OnItemSelectedListener {
public void onItemSelected(Item item);
}
private OnItemSelectedListener listener;
Ce sera lactivit principale qui sera cet couteur, grce :
@Override public void onAttach(Activity activity)
{
super.onAttach(activity);
listener = (OnItemSelectedListener) activity;
}
5.3.18 couteur
du fragment
Toujours dans la classe ListeFragment, voici la callback pour les slections dans la liste :
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
{
Item item = listeItems.get((int)id);
listener.onItemSelected(item);
}
Elle va chercher litem slectionn et le fournit lcouteur, cest dire lactivit principale.
5.3.19 couteur
de lactivit
Voici maintenant lcouteur de lactivit principale :
@Override public void onItemSelected(Item item)
{
FragmentManager manager = getFragmentManager();
InfosFragment frag_infos = (InfosFragment)
manager.findFragmentById(R.id.frag_infos);
if (frgInfos != null && frgInfos.isVisible()) {
// le fragment est prsent, alors lui fournir l'item
frgInfos.setItem(item);
} else {
// lancer InfosActivity pour afficher l'item
Intent intent = new Intent(this, InfosActivity.class);
intent.putExtra("item", item);
startActivity(intent);
}
}
93
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
5.3.20 Relation
entre deux classes mditer, partie 1
Une classe active capable davertir un couteur dun vnement. Elle dclare une interface que
doit implmenter lcouteur.
public class Classe1 {
public interface OnEvenementListener {
public void onEvenement(int param);
}
private OnEvenementListener ecouteur = null;
public void setOnEvenementListener(
OnEvenementListener objet) {
ecouteur = objet;
}
private void traitementInterne() {
...
if (ecouteur!=null) ecouteur.onEvenement(argument);
}
}
5.3.21
mditer, partie 2
Une 2e classe en tant qucouteur des vnements dun objet de Classe1, elle implmente linterface
et se dclare auprs de lobjet.
public class Classe2 implements Classe1.OnEvenementListener
{
private Classe1 objet1;
public Classe2() {
...
objet1.setOnEvenementListener(this);
}
public void onEvenement(int param) {
...
}
}
5.4
Prfrences dapplication
5.4.1 Illustration
Les prfrences mmorisent des choix de lutilisateur entre deux excutions de lapplication.
5.4.2
Prsentation
Il y a deux concepts mis en jeu :
94
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 38: Prfrences de lapplication
Une activit pour afficher et modifier les prfrences.
Une sorte de base de donnes qui stocke les prfrences,
boolens,
nombres : entiers, rels. . . ,
chanes et ensembles de chanes.
Chaque prfrence possde un identifiant. Cest une chane comme "prefs_nbmax". La base de
donnes stocke une liste de couples (identifiant, valeur ).
Voir la documentation Android
5.4.3
Dfinition des prfrences
Dabord, construire le fichier res/xml/preferences.xml :
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="...">
<CheckBoxPreference android:key="prefs_online"
android:title="En
ligne"
android:summary="Connexion permanente au serveur"
android:defaultValue="true"
/>
<EditTextPreference android:key="prefs_nbmax"
android:title="Nombre Max"
android:summary="Nombre maximal d'lments lists"
android:inputType="number"
android:numeric="integer"
android:defaultValue="100" />
...
</PreferenceScreen>
5.4.4
Explications
Ce fichier xml dfinit la fois :
Les prfrences :
lidentifiant : android:key
le titre rsum : android:title
le sous-titre dtaill : android:summary
la valeur initiale : android:defaultValue
95
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
La mise en page. Cest une sorte de layout contenant des cases cocher, des zones de saisie. . .
Il est possible de crer des pages de prfrences en cascade comme par exemple, les prfrences
systme.
Consulter la doc pour connatre tous les types de prfrences.
NB: le rsum naffiche malheureusement pas la valeur courante. Consulter stackoverflow pour une
proposition.
5.4.5
Accs aux prfrences
Les prfrences sont gres par une classe statique appele PreferenceManager. On doit lui demander
une instance de SharedPreferences qui reprsente la base et qui possde des getters pour chaque
type de donnes.
// rcuprer la base de donnes des prfrences
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(getBaseContext());
// rcuprer une prfrence boolenne
boolean online = prefs.getBoolean("prefs_online", true);
Les getters ont deux paramtres : lidentifiant de la prfrence et la valeur par dfaut.
5.4.6
Prfrences chanes et nombres
Pour les chanes, cest getString(identifiant, dfaut).
String
hostname
prefs.getString("prefs_hostname","localhost");
Pour les entiers, il y a bug important (fvrier 2015). La mthode getInt plante. Voir stackoverflow
pour une solution. Sinon, il faut passer par une conversion de chane en entier :
// PLANTE
nbmax =
5.4.7
Modification des prfrences par programme
Il est possible de modifier des prfrences par programme, dans la base SharedPreferences, laide
dun objet appel editor qui possde des setters. Les modifications font partie dune transaction
comme avec une base de donnes.
Voici un exemple :
// dbut d'une transaction
SharedPreferences.Editor editor = prefs.edit();
// modifications
editor.putBoolean("prefs_online", false);
96
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
editor.putInt("prefs_nbmax", 20);
// fin de la transaction
editor.commit();
5.4.8
Affichage des prfrences
Il faut crer une activit toute simple :
public class PrefsActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.prefs_activity);
}
}
Le layout prefs_activity.xml contient seulement un fragment :
<fragment xmlns:android="..."
android:id="@+id/frag_prefs"
android:name="LE.PACKAGE.COMPLET.PrefsFragment"
... />
Mettre le nom du package complet devant le nom du fragment.
5.4.9
Fragment pour les prfrences
Le fragment PrefsFragment hrite de PreferenceFragment :
public class PrefsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// charger les prfrences
addPreferencesFromResource(R.xml.preferences);
// mettre jour les valeurs par dfaut
PreferenceManager.setDefaultValues(
getActivity(), R.xml.preferences, false);
}
}
Cest tout. Le reste est gr automatiquement par Android.
97
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Bases de donnes SQLite3 <>
Aprs avoir reprsent une liste ditems sous forme dun tableau, nous allons la stocker dans un
SGBD SQL.
Figure 39: Logo de SQLite3
SQLite3
Requtes et curseurs
WebServices
6.1
SQLite3
6.1.1 Stockage dinformations
Il nest pas pertinent denregistrer des informations dans un tableau stock en mmoire vive, cest
dire sur un support volatile.
Android contient un SGBD SQL appel SQLite3, parfait pour stocker des informations. On peut le
lancer partir de bash :
bash$ sqlite3 test.db
sqlite> CREATE TABLE Planetes (
_id INTEGER PRIMARY KEY AUTOINCREMENT,
nom TEXT NOT NULL,
distance REAL,
idType INTEGER NOT NULL,
FOREIGN KEY(idType) REFERENCES Types(_id));
sqlite> INSERT INTO Planetes VALUES (1, "Sedna", 3.5, 1);
6.1.2
SQLite3
SQLite3 est un vrai SGBD relationnel SQL, mais simplifi pour tenir sur une tablette.
Ce qui lui manque :
98
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Aucune gestion des utilisateurs (autorisations), pas de scurit.
Pas de rglages pour amliorer les performances car
Peu de types de donnes, ex: date = entier ou chane, un seul type dentiers. . .
SQLite3 fonctionne sans serveur. Il stocke ses donnes dans un seul fichier. Ce fichier est portable,
cest dire copiable sur nimporte quelle autre machine.
6.1.3
Exemples SQL
Toutes les requtes SQL que vous connaissez fonctionnent, p. ex. :
SELECT COUNT(*) FROM Planetes WHERE nom LIKE 'Ter%';
SELECT * FROM Planete WHERE distance > 200.0 ORDER BY distance;
SELECT AVG(distance) AS moyenne FROM Planetes GROUP BY idType;
DELETE FROM Planetes WHERE distance IS NULL;
ALTER TABLE Planetes ADD COLUMN date INTEGER;
UPDATE Planetes SET date=strftime('%s','now');
DROP TABLE Planetes;
Jointures, groupements, requtes imbriques, transactions, index, triggers. . . tout cela existe.
Consulter la documentation.
6.1.4
Autres usages de SQLite3
Ce SGBD est utilis dans de nombreuses applications ailleurs que dans Android, p. ex. dans Firefox
pour stocker les marque-pages, lhistorique de navigation, etc.
SQLite3 est aussi une API pour diffrents langages de programmation : C, Python, PHP, Java. . . On
peut excuter des requtes SQL en appelant des fonctions.
Android le propose aux programmeurs pour stocker des informations structures, plutt que bricoler
avec des fichiers. Il est assez facile utiliser une fois le cadre mis en place.
6.1.5
Lancement de sqlite3 en shell
sqlite3 est une commande qui ouvre un shell SQL, pour saisir directement des requtes, sans
connexion. On peut fournir un paramtre, le nom dun fichier qui contient la base, soit aucun et dans
ce cas, la base nest quen mmoire, perdue quand on quitte.
bash$ sqlite3 test.db
sqlite>
Cette commande est dans le dossier du SDK, sous-dossier platform-tools (Linux et Windows). Elle
nest pas forcment incluse dans le systme Linux de la tablette.
6.1.6
Commandes internes
Le shell de SQLite3 possde des commandes internes, p. ex. :
.help affiche la liste des commandes internes
99
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
.dump table affiche le contenu de la table ou de toute la base si la table est omise
.schema table affiche la structure de la table
.headers mettre on ou off pour crire les noms des colonnes en tte de tous les select
.exit sort du shell sqlite3
6.2
SQLite dans une application Android
6.2.1 Bases de donnes Android
Chaque application peut crer une base de donnes. Cest un fichier *.db plac dans le dossier
/data/data/PAQUETAGE /databases/NOM_BDD
Vous pourrez changer ce fichier avec le PC (adb push ou pull). Consulter cette page pour des
dtails sur la marche suivre.
Dans une application Android, ces fichiers sont manipuls laide de classes de lAPI.
NB: ce cours commence par une grande simplification (louverture dune BDD). Lisez la totalit pour
savoir comment on procde en ralit.
6.2.2
Classes pour travailler avec SQLite
Il faut connatre au moins deux classes :
SQLiteDatabase : elle reprsente une BDD. Ses mthodes permettent dexcuter une requte,
par exemple :
void execSQL(String sql) pour CREATE, ALTER, DROP. . . qui ne retournent pas de
donnes.
Cursor rawQuery(String sql, ...) pour des SELECT qui retournent des n-uplets.
Dautres mthodes pour des requtes spcialises.
Cursor : reprsente un n-uplet. Il y a des mthodes pour rcuprer les colonnes.
Voyons les dtails.
6.2.3
Principes
Voici les tapes du travail avec une BDD en Java :
1. Ouverture de la base, cration du fichier si besoin :
SQLiteDatabase bdd;
bdd = SQLiteDatabase.openOrCreateDatabase(...);
2. Excution de requtes :
1. Obtention dun Curseur sur le rsultat des select
Cursor cursor = bdd.rawQuery(requete, ...);
2. Parcours des n-uplets du curseur laide dune boucle for
3. Fermeture du curseur (indispensable, prvoir les exceptions, voir plus loin)
cursor.close()
3. Fermeture de la base (indispensable, prvoir les exceptions) :
bdd.close()
100
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
6.2.4
Base ouverte dans une activit
Si vous ouvrez la base pour toute la vie de lactivit dans onCreate, alors vous devez la fermer dans
la mthode onDestroy.
class MonActivite extends Activity
{
private SQLiteDatabase bdd;
void onCreate(...) {
...
bdd = SQLiteDatabase.openOrCreateDatabase(...);
}
void onDestroy() {
...
bdd.close();
}
}
6.2.5
Recommandations
Il est prfrable de dfinir une classe associe chaque table (et mme chaque jointure). a permet de
faire voluer le logiciel assez facilement. Cette classe regroupe toutes les requtes SQL la concernant :
cration, suppression, mise jour, parcours, insertions. . . sous forme de mthodes de classe. La base
de donnes est passe en premier paramtre de toutes les mthodes.
Cette dmarche sinspire du patron de conception Active Record qui reprsente une table par une
classe. Ses instances sont les n-uplets de la table. Les attributs de la table sont grs par des accesseurs.
Des mthodes comme find permettent de rcuprer des n-uplets et des mthodes permettent la mise
jour de la base : new, save et delete.
Voir le projet ActiveAndroid pour une implantation Android.
6.2.6
Noms des colonnes
Dans ce cours, on va mettre en uvre une simplification de ce patron de conception.
On dfinit une classe ne contenant que des mthodes statiques.
public class TablePlanetes
{
// mthodes statiques pour grer les donnes
public static create(...) ...
public static drop(...) ...
public static insert(...) ...
...
}
101
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
6.2.7
Classe pour une table
Par exemple, pour crer et supprimer la table :
bdd.execSQL( "CREATE TABLE Planetes
bdd.execSQL("DROP TABLE IF EXISTS Planetes");
Gare la syntaxe, a doit crer du SQL correct !
6.2.8
Exemples de mthodes
Voici des mthodes pour crer ou supprimer des n-uplets :
public static void insert(SQLiteDatabase bdd, Planete pl)
{
bdd.execSQL(
"INSERT INTO Planetes VALUES (null, ?, ?)",
new Object[] { pl.getNom(), pl.getDistance() });
}
public static void delete(SQLiteDatabase bdd, long id)
{
bdd.execSQL(
"DELETE FROM Planetes WHERE _id=?",
new Object[] {id});
}
On va aussi rajouter des mthodes de consultation des donnes. Voyons dabord la mthode execSQL.
6.2.9
Mthodes SQLiteDatabase.execSQL
Cette mthode excute une requte SQL qui ne retourne pas dinformations : CREATE, INSERT. . .
void execSQL (String sql) : on doit juste fournir la requte sous forme dune chane. Cest
une requte constante. Ne pas mettre de ; la fin. Par exemple :
bdd.execSQL("DROP TABLE Planetes");
void execSQL (String sql, Object[] bindArgs) : cest pour le mme type de requte mais
contenant des jokers ? affecter avec les objets fournis en paramtre.
102
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
bdd.execSQL("DELETE FROM Planetes WHERE _id BETWEEN ? AND ?",
new Object[] { 3, 8 });
6.2.10 Mthodes
spcialises
Android propose des mthodes spcifiques pour insrer, modifier, supprimer des n-uplets :
int insert(String table, null, ContentValues valeurs)
int update(String table, ContentValues valeurs, String whereClause, String[]
whereArgs)
int delete(String table, String whereClause, String[] whereArgs)
La diffrence avec execSQL, cest quelles demandent un tableau de String. Il faut donc convertir
toutes les donnes en chanes.
6.2.11 Mthode
insert
insert(table, null, valeurs) effectue une requte du type :
INSERT INTO table (col1, col2...) VALUES (val1, val2...);
Elle retourne lidentifiant du nouveau n-uplet. Ses paramtres sont :
table : fournir le nom de la table
null (a correspond une bidouille)
valeurs : cest une structure du type ContentValues qui associe des noms et des valeurs
quelconques :
ContentValues valeurs = new ContentValues();
valeurs.putNull("_id");
valeurs.put("nom", "Sedna");
int id = bdd.insert("Planetes", null, valeurs);
6.2.12 Mthodes
update et delete
update(table, valeurs, whereClause, whereArgs) fait UPDATE table SET col1=val1,
col2=val2 WHERE ...; et delete(table, whereClause, whereArgs) effectue DELETE FROM
table WHERE ...; Elles retournent le nombre de n-uplets altrs. Les paramtres sont :
table : fournir le nom de la table
valeurs : ce sont les couples (colonne, valeur mettre)
whereClause : une condition contenant des jokers ?
whereArgs : chanes mettre la place des ?
ContentValues valeurs = new ContentValues();
valeurs.put("nom",
"Sedna");
bdd.update("Planetes", valeurs, "_id=?", new String[] { "4" });
bdd.delete("Planetes", "_id BETWEEN ? AND ?",new String[]{"5","8"});
103
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
6.2.13 Mthode
rawQuery
Cette mthode, rawQuery permet dexcuter des requtes de type SELECT (pas de ; la fin). Elle
retourne un objet Java de type Cursor qui permet de parcourir les n-uplets un un :
Cursor cursor = bdd.rawQuery("SELECT * FROM table WHERE...");
Remarquez le finally obligatoire qui permet de fermer le curseur.
6.2.14 rawQuery
pour un seul n-uplet
Sil ny a quun seul n-uplet dans la rponse, il nest pas ncessaire de faire une boucle, mais il faut
quand mme initialiser puis fermer le curseur :
Cursor cursor = bdd.rawQuery("SELECT * FROM table WHERE...");
try {
if (cursor.moveToFirst()) {
// obligatoire
/** utiliser le curseur... **/
}
} finally {
if (cursor != null) cursor.close();
}
6.2.15 Classe
Cursor
La classe Cursor propose deux types de mthodes :
celles qui permettent de parcourir les n-uplets :
getCount() : retourne le nombre de n-uplets,
getColumnCount() : retourne le nombre de colonnes,
moveToFirst() : met le curseur sur le premier ( faire !),
isAfterLast() : retourne vrai si le parcours est fini,
moveToNext() : passe au n-uplet suivant.
celles qui permettent dobtenir la valeur de la colonne nc (0..getColumnCount()-1 ) du n-uplet
courant :
getColumnName(nc) : retourne le nom de la colonne nc,
isNull(nc) : vrai si la colonne nc est nulle,
getInt(nc), getLong(nc), getFloat(nc), getString(nc), etc. : valeur de la colonne nc.
104
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
6.2.16 Exemple
de requte, classe TablePlanetes
public static String getNom(... bdd, long id)
{
Cursor cursor = bdd.rawQuery(
"SELECT nom FROM Planetes WHERE _id=?",
new String[] {Long.toString(id)});
try {
if (cursor.moveToFirst() && !cursor.isNull(0)) {
return cursor.getString(0);
} else
return null;
} finally {
if (cursor != null) cursor.close();
}
}
6.2.17 Autre
type de requte
Cette autre mthode retourne non pas une valeur, mais directement un curseur. Elle est utilise pour
afficher tous les lments de la table dans une liste, voir page 109.
public static Cursor getAll(SQLiteDatabase bdd)
{
return bdd.rawQuery("SELECT * FROM Planetes", null);
}
Attention, votre application doit prendre soin de fermer ce curseur ds quil ne sert plus, ou alors de
le fournir un objet (ex: un adaptateur) qui sait le fermer automatiquement.
6.2.18 Mthodes
query
Android propose galement des mthodes pratiques pour effectuer des requtes, telles que :
query(String table, String[] columns, String selection,
String[] selectionArgs, String groupBy, String having,
String orderBy, String limit)
mais je ne vois pas lintrt de recoder en Java ce qui se fait parfaitement en SQL, sans compter les
risques derreur si on permute involontairement les paramtres de ces mthodes.
6.2.19 Ouverture
dune base
Revenons vers les aspects gestion interne de la base de donnes. Louverture dune base se fait ainsi :
105
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
String dbpath =
this.getFilesDir().getPath().concat("/test.db");
SQLiteDatabase bdd =
SQLiteDatabase.openOrCreateDatabase(dbpath,
null);
NB: cela ne cre pas les tables, seulement le fichier qui contient la base.
Il faut fournir le chemin daccs la base. Mais en faisant ainsi, la base est cre dans
/data/data/*package*/files et non pas .../databases. Voir page 105 pour la vritable faon de
faire.
6.2.20 Premire
ouverture et ouvertures suivantes
Ensuite, aprs avoir ouvert la base, si cest la premire fois, il faut crer les tables. Cependant, a
cause une erreur de crer une table qui existe dj et il serait coteux de tester lexistence des tables.
Une possibilit consiste rajouter IF NOT EXISTS la requte de cration. Par exemple :
bdd.execSQL(
"CREATE TABLE IF NOT EXISTS Planetes
Un autre problme, cest la mise jour de lapplication. Quallez-vous proposer vos clients si vous
changez le schma de la base entre la V1 et la V2, la V2 et la V3. . . ?
6.2.21 Un
helper pour grer louverture/cration/mj
Android propose la classe supplmentaire SQLiteOpenHelper qui facilite la gestion des bases de
donnes. Cette classe est une sorte dcouteur avec deux mthodes surcharger :
onCreate(bdd) : cette mthode est appele quand la base de donnes nexiste pas encore. Son
rle est de crer les tables. Cest l que vous mettez les CREATE TABLE...
onUpgrade(bdd, int oldV, int newV) : cette mthode est appele quand la version de
lapplication est suprieure celle de la base. Son rle peut tre de faire des ALTER TABLE...,
UPDATE... ou carrment DROP TABLE... suivis de onCreate.
Les mthodes getReadableDatabase et getWritableDatabase de SQLiteOpenHelper ouvrent la
base et appellent automatiquement onCreate et onUpgrade si ncessaire.
6.2.22 Exemple
de helper
public class MySQLiteHelper extends SQLiteOpenHelper
{
// nom du fichier contenant la base de donnes
private static final String DB_NAME = "test.db";
// version du schma de la base de donnes
106
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
private static final int DB_VERSION = 1;
// constructeur du helper = ouvre et cre/mj la base
public MySQLiteHelper(Context context)
{
super(context, DB_NAME, null, DB_VERSION);
}
...
6.2.23 Exemple
de helper, suite
@Override
public void onCreate(SQLiteDatabase bdd)
{
// cration avec la mthode de la classe TablePlanetes
TablePlanetes.create(bdd);
}
@Override
public void onUpgrade(SQLiteDatabase bdd,
int oldVersion, int newVersion)
{
// suppression de toutes les donnes !
TablePlanetes.drop(bdd);
// re-cration de la base
onCreate(bdd);
}
}
6.2.24 mthode
onUpgrade
public void onUpgrade(SQLiteDatabase bdd,
int oldVersion, int newVersion)
Dans le cas dune application srieuse, on ne dtruit pas toutes les donnes utilisateur quand on change
le schma. Cest vous de dterminer les modifications minimales qui permettent de transformer les
donnes prsentes, de leur version actuelle oldVersion la version newVersion.
Il est indiqu de procder par tapes :
passer de la version oldVersion la oldVersion+1
passer de la version oldVersion+1 la oldVersion+2
ainsi de suite, jusqu arriver la newVersion.
107
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
6.2.25 mthode
onUpgrade, suite
Cela donne quelque chose comme a :
@Override
public void onUpgrade(..., int oldVersion, int newVersion){
while (oldVersion < newVersion) {
oldVersion++;
switch (oldVersion) {
case 2: // amener la base de la V1 la V2
bdd.execSQL("ALTER TABLE Planetes ADD COLUMN taille REAL");
break;
case 3: // amener la base de la V2 la V3
...
break;
}
}
}
6.2.26 Retour
lapplication
Avec un helper, cela devient trs simple douvrir une base, en consultation seule ou en modification :
MySQLiteHelper helper = new MySQLiteHelper(this);
SQLiteDatabase bdd = helper.getReadableDatabase();
/* ou bien */
SQLiteDatabase bdd = helper.getWritableDatabase();
// requtes SQL sur l'objet bdd
...
A la terminaison de lapplication, cest le helper quil faut fermer, et cest lui qui ferme la base :
helper.close();
6.3
CursorAdapter et Loaders
6.3.1 Lien entre une BDD et un ListView
On revient vers lapplication qui affiche une liste. Cette fois, la liste doit tre le rsultat dune requte
SELECT. Comment faire ?
Les choses sont devenues relativement complexes depuis Android 3. Afin dviter que lapplication se
bloque lors du calcul de la requte et voir le message lapplication ne rpond pas , Android emploie
un mcanisme appel chargeur, loader en anglais.
Le principe est de rendre le calcul de la requte SQL asynchrone, dsynchronis de linterface. On
lance la requte SELECT et en mme temps, on affiche une liste vide. Lorsque la requte sera finie, la
liste sera mise jour, mais en attendant, linterface ne reste pas bloque.
108
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
6.3.2
tapes suivre
Mthode onCreate de lactivit qui affiche la liste :
1. Dfinir un adaptateur de curseur pour la liste
2. Ouvrir la base de donnes
3. Crer un chargeur de curseur et lassocier this
4. Dmarrer le chargeur
Dfinir la classe MonCursorLoader, sous-classe de CursorLoader qui effectue la requte SQL
Dfinir trois callbacks :
onCreateLoader : retourne un MonCursorLoader
onLoadFinished et onLoaderReset : reoivent un curseur jour et mettent jour
ladaptateur
Voici le dtail.
6.3.3
Activit ou fragment daffichage dune liste
Cette activit hrite de ListActivity (ou ListFragment) et elle implmente les mthodes dun
chargeur de curseur :
public class MainActivity extends ListActivity
implements LoaderManager.LoaderCallbacks<Cursor>
{
private MySQLiteHelper helper;
private SQLiteDatabase bdd;
private SimpleCursorAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
...
6.3.4
Cration dun adaptateur de curseur
a ressemble ladaptateur dun tableau, mais on fournit deux listes : les noms des colonnes et les
identifiants des vues dans lesquelles il faut mettre les valeurs.
// crer un adaptateur curseur-liste
adapter = new SimpleCursorAdapter(this,
// layout des lments de la liste
android.R.layout.simple_list_item_2,
// le curseur sera charg par le loader
null,
// noms des colonnes afficher
new String[]{"_id", "nom"},
// identifiants des TextView qui affichent les colonnes
109
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
new int[]{android.R.id.text1, android.R.id.text2},
0); // options, toujours mettre 0
setListAdapter(adapter);
6.3.5
Ouverture de la base et cration dun chargeur
Ensuite, toujours dans la mthode onCreate de lactivit, on ouvre la base, ici en consultation car
cette activit ne modifie pas les donnes, puis on cre un chargeur associ this.
// identifiant du chargeur (utile s'il y en a plusieurs)
private static final int LOADER_ID = 1;
// ouvrir la base de donnes SQLite
helper = new MySQLiteHelper(this);
bdd = helper.getReadableDatabase();
// cre et dmarre un chargeur pour cette liste
getLoaderManager().initLoader(LOADER_ID, null, this);
Cette dernire instruction exige de dfinir trois callbacks dans lactivit :
onLoadFinished et onLoaderReset. Voyons dabord la premire.
6.3.6
onCreateLoader,
Callback onCreateLoader de lactivit
Toujours dans la classe dactivit qui affiche la liste :
@Override
public Loader<Cursor> onCreateLoader(int loaderID,
Bundle bundle)
{
return new MonCursorLoader(getApplicationContext(), bdd);
}
Cette callback fait instancier un MonCursorLoader qui est une sous-classe de CursorLoader, dfinie
dans notre application. Son rle est de lancer la requte qui retourne le curseur contenant les donnes
afficher.
6.3.7
classe MonCursorLoader
static private class MonCursorLoader extends CursorLoader
{
private SQLiteDatabase bdd;
public MonCursorLoader(Context context, SQLiteDatabase bdd) {
super(context);
this.bdd = bdd;
}
110
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
@Override
protected Cursor onLoadInBackground() {
return TablePlanetes.getAll(bdd);
}
Voir page 104 pour la mthode getAll, elle fait seulement return bdd.rawQuery("SELECT * FROM
Planetes", null);
6.3.8
Callback onLoadFinished de lactivit
Pour finir, la callback qui est appele lorsque les donnes sont devenues disponibles ; elle met jour
ladaptateur, ce qui affiche les n-uplets dans la liste. Lautre callback est appele si le chargeur doit
tre supprim. On met donc toujours ceci :
@Override
public void onLoadFinished(Loader<Cursor> loader,
Cursor cursor) {
adapter.changeCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
adapter.changeCursor(null);
}
6.3.9
Mise jour de la liste
Quand il faut mettre jour la liste, si les donnes ont chang, il faut relancer le chargeur de curseur
et non pas ladaptateur. Cela se fait de la manire suivante :
// le chargeur doit recommencer son travail
getLoaderManager().restartLoader(LOADER_ID, null, this);
6.4
ContentProviders
6.4.1 Prsentation rapide
Les Fournisseurs de contenu sont des sortes de tables de donnes disponibles dune application
lautre et accessibles laide dun URI (gnralisation dun URL). Un exemple est le carnet dadresse
de votre tlphone. Dautres applications que la tlphonie peuvent y avoir accs.
Un ContentProvider possde diffrentes mthodes ressemblant celles des bases de donnes :
query : retourne un Cursor comme le fait un SELECT,
insert, update, delete : modifient les donnes,
Dautres mthodes permettent de consulter le type MIME des donnes.
Comme cest trs compliqu mettre en uvre et que a ressemble une simple table SQL sans
jointure, on nen parlera pas plus ici.
111
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
6.5
WebServices
6.5.1 Echange entre un serveur SQL et une application
Android
On arrive au plus intressant, faire en sorte quune application Android stocke ses donnes sur un
serveur distant. Pour commencer, rvisez vos cours de Web Design, PHP, PDO. . .
Soit un serveur HTTP connect une base de donnes (PostgreSQL en TP). Ce serveur possde des
scripts PHP qui vont rpondre aux demandes de lapplication Android laide dau moins deux types
dchanges HTTP3 :
Les SELECT vont tre traites par des GET,
Les INSERT, UPDATE, DELETE. . . vont tre envoys par des POST.
Chaque requte sera associe un script spcifique.
6.5.2
Principe gnral
Soit la requte SELECT * FROM Planetes WHERE _id=3. On va envoyer lidentifiant 3 sur le rseau
et cest un script PHP qui va effectuer la requte. Il y a un script par sorte de requte, donc chacun
sait exactement quels paramtres il va recevoir.
1. Lapplication construit une requte HTTP, p. ex. de type GET
URL = http://serveur /script?paramtres
paramtres = conditions du select, p. ex. identifiant=3.
2. Lapplication (cliente) envoie cette requte au serveur puis attend la rponse,
3. Le script PHP excute la requte puis retourne le rsultat encod en JSON lapplication,
4. Lapplication dcode le rsultat et laffiche.
Les autres requtes suivent le mme principe client-serveur.
6.5.3
Exemple de script PHP Post
Voici un script qui modifie un n-uplet. Il est lanc par un POST.
// connexion au serveur SQL par PDO
$db = new PDO("pgsql:host=$hostname;dbname=$dbname",
$login, $passwd);
// paramtres de la requte (TODO: tester la prsence)
$id = $_POST['_id'];
$nom = $_POST['nom'];
// prparation et excution
$query = $db->prepare(
"UPDATE Planetes SET nom=? WHERE _id=?");
$query->execute(array($nom, $id));
NB: ici, on se ne proccupe pas de scurit.
3En
fait, un vrai WebService Restful est plus complexe, voir wikipedia
112
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
6.5.4
Exemple de script PHP Get
Voici get_all_planetes.php qui retourne tous les n-uplets :
// connexion au serveur SQL par PDO
$db = new PDO("pgsql:host=$hostname;dbname=$dbname",
$login, $passwd);
// liste de tous les types
$query = $db->prepare("SELECT * FROM Planetes ORDER BY _id;");
$query->execute();
// encodage JSON de toutes les rponses
echo json_encode($query->fetchAll(PDO::FETCH_NUM));
6.5.5
Format JSON JavaScript Object Notation
Cest un format pour transporter des tableaux et des objets travers le rseau. Ils sont crits sous
forme dun texte. JSON est une alternative au XML.
Par exemple la liste des n-uplets prsents dans la table Planetes :
[[1,"Mercure",58],[2,"Venus",108],[3,"Terre",150],...
En PHP, cest trs simple :
// encodage : tableau -> jsondata
$jsondata = json_encode($tableau);
// dcodage : jsondata -> tableau
$tableau = json_decode($jsondata);
Le tableau peut venir dun fetchAll(PDO::FETCH_NUM).
6.5.6
JSON en Java
En Java, cest plus compliqu. Il faut employer une instance de JSONArray. Elle possde des setters
et des getters pour chaque type de donnes.
// encodage : tableau -> jsondata
int[] tableau = ...;
JSONArray ja = new JSONArray();
for (int v: tableau) ja.put(v);
String jsondata = ja.toString();
// dcodage : jsondata -> tableau
JSONArray ja = new JSONArray(jsondata);
final int nb = ja.length();
int[] tableau = new int[nb];
for (int i=0; i<nb; i++) tableau[i] = ja.getInt(i);
Cest adapter aux donnes changer : entiers, chanes. . .
113
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
6.5.7
Dans lapplication Android
Tout le problme est de construire une requte HTTP, dattendre la rponse, de la dcoder et de
lafficher.
Pour commencer, il faut que lapplication soit autorise accder internet. Rajouter cette ligne
dans le manifeste :
<uses-permission
android:name="android.permission.INTERNET"/>
Ensuite, il faut transformer tout ce qui est requte SQL :
Affichage des donnes : changer le chargeur de curseur,
Modifications des donnes.
Voyons cela dans lordre.
6.5.8
Affichage dune liste
Il suffit de reprogrammer la mthode getAll de la classe TablePlanetes, voir page 104 et 112 :
public static Cursor getAll(RemoteDatabase bdd) {
// requte Get l'aide de la classe RemoteDatabase
String jsondata = bdd.get("get_all_planetes.php", null);
// dcoder les n-uplets et en faire un curseur
return bdd.cursorFromJSON(jsondata,
new String[] { "_id", "nom", "distance" });
}
Jai retir les tests derreur et traitements dexceptions.
6.5.9
La classe RemoteDatabase
Cest une classe que je vous propose. Elle fait un peu tout : le caf, les croissants. . . Cest elle qui
organise la communication avec le serveur, dont ces mthodes :
get("script.php", params) appelle le script PHP par un GET en lui passant les paramtres
indiqus et retourne un String contenant la rponse du serveur sous forme de donnes JSON.
cursorFromJSON(jsondata, noms_des_colonnes) construit un curseur avec la rponse JSON
du serveur. On est oblig de fournir les noms des colonnes car ils ne sont pas prsents dans les
donnes JSON.
Cette classe est assez complexe. Une partie des explications viendra ultrieurement.
6.5.10 Modification
dun n-uplet
Voici maintenant une requte POST pour modifier un n-uplet :
114
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
public static void update(RemoteDatabase bdd,
RemoteDatabaseListener listener, Planete pl)
{
// paramtres de la requte
ContentValues params = new ContentValues();
params.put("_id",
pl.getId());
params.put("nom", pl.getNom());
// requte Post asynchrone
bdd.post(listener, "update_planete.php", params);
}
Elle appelle le script update_planete.php suivant.
6.5.11 Script
update_planete.php
Avant dexpliquer la mthode post de la classe RemoteDatabase, voici le script update_planete.php
qui est dclench par la requte du transparent prcdent :
// connexion la base de donnes
$db = new PDO("pgsql:host=".$hostname.";dbname=".$dbname,
$login, $passwd);
// paramtres de la requte
$id = $_POST['_id'];
$nom = $_POST['libelle'];
// prparation et excution
$query = $db->prepare("UPDATE Planetes SET nom=? WHERE _id=?");
$query->execute(array($nom, $id));
6.5.12 Mthode
post(couteur, script, params)
Cette mthode appelle un script PHP en lui fournissant des paramtres. Par exemple, cest le script
update_type.php avec les paramtres _id et libelle.
Elle a une particularit : cette mthode est asynchrone. Cest dire quelle lance un change rseau
en arrire-plan, et nattend pas quil se termine. Cest obligatoire, sinon Android affiche une erreur :
lapplication ne rpond pas, dialogue ANR .
Le principe pour cela est de crer une AsyncTask. Elle gre une action qui est excute dans un autre
thread que celui de linterface..
Du coup, il faut un couteur prvenir quand laction est termine. Cest le premier paramtre pass
la mthode post. Par exemple, cest lactivit daffichage de liste qui peut alors mettre jour la
liste affiche.
.
115
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Affichage de donnes golocalises
Cette partie est consacre lAPI de cartographie OpenStreetMap mais auparavant quelques
concepts importants connatre : les tches asynchrones et les requtes rseau.
7.1
AsyncTasks
7.1.1 Prsentation
Une activit Android repose sur une classe, ex MainActivity qui possde diffrentes mthodes comme
onCreate, les couteurs des vues, des menus et des chargeurs.
Ces fonctions sont excutes par un seul processus lger, un thread appel Main thread . Il dort la
plupart du temps, et ce sont les vnements qui le rveillent.
Ce thread ne doit jamais travailler plus de quelques fractions de secondes sinon linterface parat
bloque et Android peut mme dcider que lapplication est morte (App Not Responding).
Figure 40: Application bloque
7.1.2
Tches asynchrones
Pourtant dans certains cas, une callback peut durer longtemps :
gros calcul
requte SQL un peu complexe
requte rseau
La solution passe par une sparation des threads, par exemple laide dune tche asynchrone
AsyncTask. Cest un autre thread, indpendant de linterface utilisateur, comme un job Unix.
Lancer un AsyncTask ressemble faire commande & en shell.
Linterface utilisateur peut tre mise jour de temps en temps par la AsyncTask. Il est galement
possible de rcuprer des rsultats la fin de lAsyncTask.
116
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
7.1.3
Principe dutilisation dune AsyncTask
Ce qui est mauvais :
1. Android appelle la callback de lactivit, ex: onClick,
2. La callback a besoin de 20 secondes pour faire son travail,
3. Mais au bout de 5 secondes, Android propose de tuer lapplication.
Ce qui est correct :
1. Android appelle la callback de lactivit,
2. La callback cre une AsyncTask puis sort immdiatement,
3. Le thread de lAsyncTask travaille pendant 20 secondes,
4. Pendant ce temps, linterface est vide, mais reste ractive,
5. LAsyncTask affiche les rsultats sur linterface ou appelle un couteur.
7.1.4
Structure dune AsyncTask
Une tche asynchrone est dfinie par plusieurs mthodes :
Constructeur permet de passer des paramtres la tche.
onPreExecute Initialisation effectue par le thread principal, p. ex. elle initialise une barre
davancement (ProgressBar).
doInBackground Cest le corps du traitement. Cette mthode est lance dans son propre thread.
Elle peut durer autant quon veut.
onProgressUpdate Cette mthode permet de mettre jour linterface, p. ex. la barre davancement.
Pour a, doInBackground doit appeler publishProgress.
onPostExecute Elle est appele quand lAsyncTask a fini, par exemple pour masquer la barre
davancement et mettre jour les donnes sur linterface.
7.1.5
Paramtres dune AsyncTask
Ce qui est difficile comprendre, cest que AsyncTask est une classe gnrique (comme ArrayList).
Elle est paramtre par trois types de donnes :
AsyncTask<Params, Progress, Result>
Params est le type des paramtres de doInBackground,
Progress est le type des paramtres de onProgressUpdate,
Result est le type du paramtre de onPostExecute qui est aussi le type du rsultat de
doInBackground.
NB: a ne peut tre que des classes, donc Integer et non pas int, et Void au lieu de void (dans ce
dernier cas, faire return null;).
7.1.6
Exemple de paramtrage
Soit une AsyncTask qui doit interroger un serveur mto pour savoir quel temps il va faire. Elle va
retourner un rel indiquant de 0 1 sil va pleuvoir. La tche reoit un String en paramtre (lURL
du serveur), publie rgulirement le pourcentage davancement (un entier) et retourne un Float. Cela
donne cette instanciation du modle gnrique :
117
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
class MyTask extends AsyncTask<String, Integer, Float>
et ses mthodes sont paramtres ainsi :
Float doInBackground(String urlserveur)
void onProgressUpdate(Integer pourcentage)
void onPostExecute(Float pluie)
7.1.7
Paramtres variables
Alors en fait, cest encore plus complexe, car doInBackground reoit non pas un seul, mais un nombre
quelconque de paramtres tous du mme type. La syntaxe Java utilise la notation ... pour
signifier quen fait, cest un tableau de paramtres.
Float doInBackground(String... urlserveur)
a veut dire quon peut appeler la mme mthode de toutes ces manires, le nombre de paramtres
est variable :
doInBackground();
doInBackground("www.meteo.fr");
doInBackground("www.meteo.fr", "www.weather.fr","www.bericht.fr");
Le paramtre urlserveur est quivalent un String[] qui contiendra les paramtres.
7.1.8
Dfinition dune AsyncTask
Il faut driver et instancier la classe gnrique. Pour lexemple, jai dfini un constructeur qui permet
de spcifier une ProgressBar mettre jour pendant le travail.
Par exemple :
private class PrevisionPluie
extends AsyncTask<String, Integer, Float>
{
// ProgressBar mettre jour
private ProgressBar mBarre;
// constructeur, fournir la ProgressBar concerne
PrevisionPluie(ProgressBar barre) {
this.mBarre = barre;
}
7.1.9
AsyncTask, suite
Voici la suite avec la tche de fond et lavancement :
118
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
protected Float doInBackground(String... urlserveur) {
float pluie = 0.0f;
int nbre = urlserveur.length;
for (int i=0; i<nbre; i++) {
... interrogation de urlserveur[i] ...
// faire appeler onProgressUpdate avec le %
publishProgress((int)(i*100.0f/nbre));
}
// a va appeler onPostExecute(pluie)
return pluie;
}
protected void onProgressUpdate(Integer... progress) {
mBarre.setProgress( progress[0] );
}
7.1.10 Lancement
dune AsyncTask
Cest trs simple, on cre une instance de cet AsyncTask et on appelle sa mthode execute. Ses
paramtres sont directement fournis doInBackground :
ProgressBar mProgressBar =
(ProgressBar) findViewById(R.id.pourcent);
new PrevisionPluie(mProgressBar)
.execute("www.meteo.fr","www.weather.fr","www.bericht.fr");
execute va crer un thread spar pour effectuer doInBackground, mais les autres mthodes du
AsyncTask restent dans le thread principal.
7.1.11 Schma
rcapitulatif
7.1.12 execute ne retourne rien
En revanche, il manque quelque chose pour rcuprer le rsultat une fois le travail termin. Pourquoi
nest-il pas possible de faire ceci ?
float pluie =
new
PrevisionPluie(mProgressBar).execute("www.meteo.fr");
Ce nest pas possible car :
1. execute retourne void, donc rien,
2. lexcution de doInBackground nest pas dans le mme thread, or un thread ne peut pas faire
return dans un autre,
3. execute prend du temps et cest justement a quon veut pas.
Solutions : dfinir le thread appelant en tant qucouteur de cet AsyncTask ou faire les traitements
du rsultat dans la mthode onPostExecute.
119
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 41: Mthodes dun AsyncTask
7.1.13 Rcupration
du rsultat dun AsyncTask
Pour recevoir le rsultat dun AsyncTask, il faut gnralement mettre en place un couteur qui est
dclench dans la mthode onPostExecute. Exemple :
public interface PrevisionPluieListener {
public void onPrevisionPluieConnue(Float pluie);
}
// couteur = l'activit qui lance l'AsyncTask
private PrevisionPluieListener ecouteur;
// appele quand c'est fini, rveille l'couteur
protected void onPostExecute(Float pluie) {
ecouteur.onPrevisionPluieConnue(pluie);
}
Lcouteur est fourni en paramtre du constructeur, par exemple :
new PrevisionPluie(this, ...).execute(...);
7.1.14 Simplification
On peut simplifier un peu sil ny a pas besoin de ProgressBar et si le rsultat est directement utilis
dans onPostExecute :
private class PrevisionPluie
extends AsyncTask<String, Void, Float> {
protected Float doInBackground(String... urlserveur) {
float pluie = 0.0f;
// interrogation des serveurs
...
return pluie;
120
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
}
protected void onPostExecute(Float pluie) {
// utiliser pluie, ex: l'afficher dans un TextView
...
}
}
7.1.15 Recommandations
Il faut faire extrmement attention :
ne pas bloquer le thread principal dans une callback plus de quelques fractions de secondes,
ne pas manipuler une vue ailleurs que dans le thread principal.
Ce dernier point est trs difficile respecter dans certains cas. Si on cre un thread, il ne doit jamais
accder aux vues de linterface. Un thread na donc aucun moyen direct dinteragir avec lutilisateur.
Si vous tentez quand mme, lexception qui se produit est :
Only the original thread that created a view hierarchy can touch its views
Les solutions dpassent largement le cadre de ce cours et passent par exemple par la mthode
Activity.runOnUiThread
7.1.16 Autres
tches asynchrones
Il existe une autre manire de lancer une tche asynchrone :
Handler handler = new Handler();
final Runnable tache = new Runnable() {
@Override
public void run() {
... faire quelque chose ...
// optionnel : relancer cette tche dans 5 secondes
handler.postDelayed(this, 5000);
}
};
// lancer la tche tout de suite
handler.post(tache);
Le handler gre le lancement immdiat (post) ou retard (postDelayed) de la tche. Elle peut
elle-mme se relancer.
7.2
Requtes HTTP
7.2.1 Prsentation
Voici quelques explications sur la manire de faire une requte HTTP dune tablette vers un serveur.
Android propose plusieurs mcanismes :
121
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
un client HTTP Apache DefaultHttpClient bien pratique, mais il est obsolte depuis lAPI
22,
une classe appele HttpURLConnection maintenant recommande,
une API appele Volley un peu trop complexe pour ce cours.
Vous savez que le protocole HTTP a plusieurs mthodes , dont GET, POST, PUT et DELETE qui sont
employes pour grer un WebService. On va voir les deux premires.
7.2.2
Principe de programmation pour un GET
Voici les tapes :
1. Crer une instance de URL qui indique lurl de la page voulue, avec ses paramtres,
2. Crer une instance de HttpURLConnection en appelant openConnection() sur lURL,
3. (optionnel) Configurer la requte : agent, authentification, type mime, session, cookies. . .
4. Lire la rponse avec getInputStream(), intercepter les exceptions IOException sil y a un
problme,
5. Dconnecter afin de librer la connexion.
Noter que le serveur peut mettre du temps rpondre, il faut donc placer cela dans une AsyncTask.
7.2.3
Exemple de requte GET
URL url = new URL("http://SERVEUR/get_avis.php?_id=2");
HttpURLConnection connexion =
(HttpURLConnection) url.openConnection();
connexion.setReadTimeout(10000);
connexion.setRequestProperty("User-Agent", "Mozilla/5.0");
try {
InputStream reponse = connexion.getInputStream();
int code = connexion.getResponseCode();
... utiliser new BufferedInputStream(reponse) ...
} catch (IOException e) {
... mauvais URL, pb rseau ou serveur inactif ...
} finally {
connexion.disconnect();
}
7.2.4
Encodage de paramtres pour une requte
Les paramtres dune requte GET ou POST doivent tre encods (cf wikipedia). Les couples
(nom1,val1), (nom2,val2) deviennent ?nom1=val1&nom2=val2. Dedans, les espaces sont remplacs
par + et les caractres bizarres par leur code UTF8, ex: devient %C3%A9.
Utiliser la mthode URLEncoder.encode(chane, charset) :
122
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
String params =
"?libelle=" + URLEncoder.encode(libelle, "UTF-8") +
"&auteur=" + URLEncoder.encode(auteur, "UTF-8");
Voir le TP7 pour une implantation plus polyvalente (boucle sur un ContentValues).
7.2.5
Principe de programmation pour un POST
Un POST est un peu plus complexe car il faut encoder un corps de requte. Le dbut est similaire
une requte GET, mais ensuite :
1.
2.
3.
4.
Configurer en mode POST
Fournir un contenu avec getOutputStream(),
(optionnel) Lire la rponse avec getInputStream(),
Dconnecter afin de librer la connexion.
Le contenu est placer dans le flux dsign par getOutputStream(), mais avant :
soit on connat la taille du contenu ds le dbut :
appeler setFixedLengthStreamingMode(taille);
soit on ne la connat pas (ex: streaming) :
appeler setChunkedStreamingMode(0);
7.2.6
Exemple de requte POST
URL url = new URL("http://SERVEUR/insert_avis.php");
HttpURLConnection connexion = (HUC..) url.openConnection();
try {
connexion.setDoOutput(true);
connexion.setRequestMethod("POST");
String params = "libelle=ok¬e=3.5&...";
connexion.setFixedLengthStreamingMode(params.length());
DataOutputStream contenu =
new DataOutputStream(connexion.getOutputStream());
contenu.writeBytes(params);
contenu.close();
... ventuellement utiliser getInputStream ...
} finally {
connexion.disconnect();
}
7.2.7
Requtes asynchones
Comme le serveur peut rpondre avec beaucoup de retard, il faut employer une sous-classe dAsyncTask.
Par exemple ceci :
Constructeur : on lui fournit lURL contacter ainsi que tous les paramtres ncessaires, ils
sont simplement mmoriss dans la classe,
123
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
String doInBackground() : ouvre la connexion, construit et lance la requte, retourne la
rponse du serveur et ferme la connexion,
void onPostExecute(String reponse) : traite la rponse du serveur ou rveille un couteur.
7.2.8
Permissions pour lapplication
Pour finir, il faut rajouter ceci dans le manifeste au mme niveau que lapplication :
<uses-permission
android:name="android.permission.INTERNET"/>
Sans cela, les connexions rseau seront systmatiquement refuses.
7.3
OpenStreetMap
7.3.1 Prsentation
Au contraire de Google Maps, OSM est vraiment libre et OpenSource, et il se programme extrmement
facilement.
7.3.2
Documentation
Nous allons utiliser deux librairies :
OSMdroid : cest la librarie de base, super mal documente. Attention ne pas confondre avec
un site de piraterie.
OSMbonusPack, un ajout remarquable cette base. Son auteur sappelle Mathieu Kergall. Il
a ajout de trs nombreuses fonctionalits permettant entre autres dutiliser OpenStreetMap
pour grer des itinraires comme les GPS de voiture et aussi afficher des fichiers KML venant
de Google Earth.
Lire cette suite de tutoriels pour dcouvrir les possibilits de osmbonuspack.
7.3.3
Pour commencer
Il faut dabord installer plusieurs archives jar :
OSMbonusPack. Il est indiqu comment inclure cette librairie et ses dpendances dans votre
projet AndroidStudio. Voir le TP8 partie 2 pour voir comment faire sans connexion rseau.
OSMdroid. Cest la librairie de base pour avoir des cartes OSM.
GSON : cest une librairie pour lire et crire du JSON,
OkHTTP et OKio : deux librairies pour gnrer des requtes HTTP.
Linclusion de librairies est la fois simple et compliqu. La complexit vient de lintgration des
librairies et de leurs dpendances dans un serveur central, maven .
7.3.4
Layout pour une carte OSM
Ce nest pas un fragment, mais une vue personnalise :
124
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 42: 1G
25oogle Maps
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="..."
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<org.osmdroid.views.MapView
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
tilesource="Mapnik"/>
</LinearLayout>
Vous pouvez rajouter ce que vous voulez autour.
7.3.5
Activit pour une carte OSM
Voici la mthode onCreate minimale :
private MapView mMap;
@Override
protected void onCreate(Bundle savedInstanceState)
{
// mise en place de l'interface
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
// rajouter les contrles utilisateur
mMap = (MapView) findViewById(R.id.map);
mMap.setMultiTouchControls(true);
mMap.setBuiltInZoomControls(true);
}
7.3.6
Positionnement de la vue
Pour modifier la vue initiale de la carte, il faut faire appel au IMapController associ la carte :
// rcuprer le gestionnaire de carte (= camra)
IMapController mapController = mMap.getController();
// dfinir la vue initiale
mapController.setZoom(14);
mapController.setCenter(new GeoPoint(48.745, -3.455));
Un GeoPoint est un couple (latitude, longitude) reprsentant un point sur Terre. Il y a aussi laltitude
si on veut. Cest quivalent un LatLng de GoogleMaps.
126
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
7.3.7
Calques
Les ajouts sur la carte sont faits sur des overlays. Ce sont comme des calques. Pour ajouter quelque
chose, il faut crer un Overlay, lui rajouter des lments et insrer cet overlay sur la carte.
Il existe diffrents types doverlays, p. ex. :
ScaleBarOverlay : rajoute une chelle
ItemizedIconOverlay : rajoute des marqueurs
RoadOverlay, Polyline : rajoute des lignes
Par exemple, pour rajouter un indicateur dchelle de la carte :
// ajouter l'chelle des distances
ScaleBarOverlay echelle = new ScaleBarOverlay(mMap);
mMap.getOverlays().add(echelle);
7.3.8
Mise jour de la carte
Chaque fois quon rajoute quelque chose sur la carte, il est recommand de rafrachir la vue :
// redessiner la carte
mMap.invalidate();
a marche sans cela dans la plupart des cas, mais y penser sil y a un problme.
7.3.9
Marqueurs
Un marqueur est reprsent par un Marker :
Marker mrkIUT = new Marker(mMap);
GeoPoint gpIUT = new GeoPoint(48.75792, -3.4520072);
mrkIUT.setPosition(gpIUT); mrkIUT.setSnippet("Dpartement
INFO, IUT de Lannion"); mrkIUT.setAlpha(0.75f);
mrkIUT.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
mMap.getOverlays().add(mrkIUT);
snippet est une description succincte du marqueur,
alpha est la transparence : 1.0=opaque, 0.0=invisible,
anchor dsigne le hot point de limage, le pixel aligner avec la position.
7.3.10 Marqueur
personnaliss
Pour changer limage par dfaut (une main dans une poire), il vous suffit de placer une image png
dans res/drawable. Puis charger cette image et lattribuer au marqueur :
Drawable fleche = getResources().getDrawable(R.drawable.fleche);
mrkIUT.setIcon(fleche); mrkIUT.setAnchor(Marker.ANCHOR_RIGHT,
Marker.ANCHOR_BOTTOM);
127
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 43: Marqueur personnalis
7.3.11 Raction
un clic
On peut dfinir un couteur pour les clics sur le marqueur :
mrkIUT.setOnMarkerClickListener(new OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker, MapView map)
{
Toast.makeText(MainActivity.this,
marker.getSnippet(),
Toast.LENGTH_LONG).show();
return false;
}
});
Ici, je fais afficher le snippet du marqueur dans un Toast.
7.3.12 Itinraires
Il est trs facile de dessiner un itinraire sur OSM. On donne le GeoPoint de dpart et celui darrive
dans une liste, ventuellement des tapes intermdiaires :
// itinraire pour aller de la gare l'IUT
RoadManager manager = new OSRMRoadManager(this);
ArrayList<GeoPoint> etapes = new ArrayList<GeoPoint>();
etapes.add(gpGare);
etapes.add(gpIUT);
Road route = manager.getRoad(etapes);
// ajouter cette route sur la carte sous les marqueurs
Polyline ligne = RoadManager.buildRoadOverlay(route, this);
mMap.getOverlays().add(0, ligne);
Seul problme : faire cela dans un AsyncTask ! (voir TP8 partie 2)
7.3.13 Position
GPS
Un dernier problme : comment lire les coordonnes fournies par le rcepteur GPS ? Il faut faire
appel au LocationManager. Ses mthodes retournent les coordonnes gographiques.
128
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
LocationManager =
(LocationManager) getSystemService(LOCATION_SERVICE);
Location position =
locationManager.getLastKnownLocation(
LocationManager.GPS_PROVIDER);
if (position != null) {
mapController.setCenter(new GeoPoint(position));
}
NB: a ne marche quen plein air (rception GPS). Consulter aussi cette page propos de lutilisation
du GPS et des rseaux.
7.3.14 Autorisations
Il faut aussi autoriser laccs au GPS dans le Manifeste, en plus des accs au rseau et lcriture sur
la carte mmoire :
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission
android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE"
/>
<uses-permission
android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
/>
7.3.15 Mise
jour en temps rel de la position
Si on veut suivre et afficher les mouvements :
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 0, 0, this);
On peut utiliser la localisation par Wifi, mettre NETWORK_PROVIDER.
Le dernier paramtre est un couteur, ici this. Il doit implmenter les mthodes de linterface
LocationListener dont :
public void onLocationChanged(Location position)
{
// dplacer le marqueur de l'utilisateur
mrkUti.setPosition(new GeoPoint(position));
// redessiner la carte
mMap.invalidate();
}
129
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
7.3.16 Positions
simules
Pour tester une application base sur le GPS sans se dplacer physiquement, il y a moyen denvoyer
de fausses positions avec Android Studio.
Il faut afficher la fentre Android Device Monitor par le menu Tools, item Android. Dans longlet
Emulator, il y a un panneau pour dfinir la position de lAVD, soit fixe, soit laide dun fichier GPX
provenant dun rcepteur GPS de randonne par exemple.
7.3.17 Clics
sur la carte
Cest le seul point un peu complexe. Il faut sous-classer la classe Overlay afin de rcuprer les
touchers de lcran. On doit seulement intercepter les clics longs pour ne pas gner les mouvements
sur la carte. Voici le dbut :
public class LongPressMapOverlay extends Overlay {
// constructeur
public LongPressMapOverlay(Context context) {
super(context);
}
@Override
protected void draw(Canvas c, MapView m, boolean shadow)
{}
Pour installer ce mcanisme, il faut rajouter ceci dans onCreate :
mMap.getOverlays().add(new
7.3.18 Traitement
LongPressMapOverlay(this));
des clics
Le cur de la classe traite les clics longs en convertissant les coordonnes du clic en coordonnes
gographiques :
@Override
public boolean onLongPress(MotionEvent event, MapView map)
{
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Projection projection = map.getProjection();
GeoPoint position = (GeoPoint) projection.fromPixels(
(int)event.getX(), (int)event.getY());
// utiliser position ...
}
return true;
}
Par exemple, elle cre ou dplace un marqueur.
130
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Dessin 2D interactif
le dessin de figures 2D et les interactions avec lutilisateur.
CustomView et Canevas
Un exemple de bote de dialogue utile
Figure 44: Application de dessin
8.1
Dessin en 2D
8.1.1 Principes
Une application de dessin 2D dfinit une sous-classe de View et surcharge sa mthode onDraw, cest
elle qui est appele pour dessiner la vue. Voici le squelette minimal :
package fr.iutlan.dessin;
public class DessinView extends View {
Paint mPeinture;
public DessinView(Context context, AttributeSet attrs) {
super(context, attrs);
mPeinture = new Paint();
131
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
mPeinture.setColor(Color.BLUE);
}
public void onDraw(Canvas canvas) {
canvas.drawCircle(100, 100, 50, mPeinture);
}
}
8.1.2
Layout pour le dessin
Pour voir DessinView, il faut linclure dans un layout :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="..."
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<fr.iutlan.dessin.DessinView
android:id="@+id/dessin"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Il faut mettre le package et le nom de la classe en tant que balise XML. Ne pas oublier les attributs
de taille.
8.1.3
Mthode onDraw
La mthode onDraw(Canvas canvas) doit effectuer tous les tracs. Cette mthode doit tre rapide.
galement, elle ne doit faire aucun new. Il faut donc crer tous les objets ncessaires auparavant, par
exemple dans le constructeur de la vue.
Son paramtre canvas reprsente la zone de dessin. Attention, ce nest pas un bitmap. Un canvas
ne possde pas de pixels ; cest le bitmap associ la vue qui les possde. Voici comment on associe
un canvas un bitmap :
Bitmap bm =
Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bm);
Cest dj fait pour le canvas fourni la mthode onDraw. On obtient le bitmap de la vue avec
getDrawingCache().
8.1.4
Mthodes de la classe Canvas
La classe Canvas possde de nombreuses mthodes de dessin :
drawColor(int color) : efface le canvas avec la couleur indique. Cette couleur est un code
32 bits retourn par la classe statique Color :
132
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Color.BLACK, Color.RED. . . : couleurs prdfinies,
Color.rgb(int r, int v, int b) : convertit des composantes RVB 0..255 en un code
de couleur.
drawLine (float x1, float y1, float x2, float y2, Paint peinture) :
trace une
ligne entre (x1,y1) et (x2,y2) avec la peinture
drawCircle (float cx, float cy, float rayon, Paint paint) dessine un cercle.
etc.
8.1.5
Peinture Paint
Cette classe permet de reprsenter les modes de dessin : couleurs de trac, de remplissage, polices,
lissage. . . Cest extrmement riche. Voici un exemple dutilisation :
mPeinture = new Paint(Paint.ANTI_ALIAS_FLAG);
mPeinture.setColor(Color.rgb(128,
255,
32));
mPeinture.setAlpha(192);
mPeinture.setStyle(Paint.Style.STROKE);
mPeinture.setStrokeWidth(10);
Il est prfrable de crer les peintures dans le constructeur de la vue ou une autre mthode, mais
surtout pas dans la mthode onDraw.
8.1.6
Quelques accesseurs de Paint
Parmi la liste de ce qui existe, on peut citer :
setColor(Color), setARGB(int a, int r, int v, int b), setAlpha(int a) : dfinissent
la couleur et la transparence de la peinture,
setStyle(Paint.Style style) : indique ce quil faut dessiner pour une forme telle quun
rectangle ou un cercle :
Paint.Style.STROKE uniquement le contour
Paint.Style.FILL uniquement lintrieur
Paint.Style.FILL_AND_STROKE contour et intrieur
setStrokeWidth(float pixels) dfinit la largeur du contour.
8.1.7
Motifs
Il est possible de crer une peinture base sur un motif. On part dune image motif.png dans le
dossier res/drawable quon emploie comme ceci :
Bitmap bmMotif = BitmapFactory.decodeResource(
context.getResources(),
R.drawable.motif);
BitmapShader shaderMotif = new BitmapShader(bmMotif,
Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
mPaintMotif = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintMotif.setShader(shaderMotif);
mPaintMotif.setStyle(Paint.Style.FILL_AND_STROKE);
Cette peinture fait appel un Shader . Cest une classe permettant dappliquer des effets progressifs,
tels quun dgrad ou un motif comme ici (BitmapShader).
133
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
8.1.8
Shaders
Voici la ralisation dun dgrad horizontal bas sur 3 couleurs :
final int[] couleurs = new int[] {
Color.rgb(128, 255, 32),
// vert pomme
Color.rgb(255, 128, 32),
// orange
Color.rgb(0, 0, 255)
// bleu
};
final float[] positions = new float[] { 0.0f, 0.5f, 1.0f };
Shader shader = new LinearGradient(0, 0, 100, 0,
couleurs, positions, Shader.TileMode.CLAMP);
mPaintDegrade = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintDegrade.setShader(shader);
Figure 45: Dgrad horizontal
8.1.9
Shaders, suite et fin
Le dgrad prcdent est base sur trois couleurs situes aux extrmits et au centre du rectangle.
On fournit donc deux tableaux, lun pour les couleurs et lautre pour les positions des couleurs
relativement au dgrad, de 0.0 1.0.
Le dgrad possde une dimension, 100 pixels de large. Si la figure dessiner est plus large, la couleur
sera maintenue constante avec loption CLAMP. Dautres options permettent de faire un effet miroir,
MIRROR, ou redmarrer au dbut REPEAT.
Cette page prsente les shaders et filtres dune manire extrmement intressante. Comme vous
verrez, il y a un grand nombre de possibilits.
8.1.10 Quelques
remarques
Lorsquil faut redessiner la vue, appelez invalidate. Si la demande de raffichage est faite dans un
autre thread, alors il doit appeler postInvalidate.
La technique montre dans ce cours convient aux dessins relativement statiques, mais pas un jeu
par exemple. Pour mieux animer le dessin, il est recommand de sous-classer SurfaceView plutt
que View. Les dessins sont alors faits dans un thread spar et dclenchs par des vnements.
8.1.11
Dessinables
Les canvas servent dessiner des figures gomtriques, rectangles, lignes, etc, mais aussi des Drawable,
cest dire des choses dessinables telles que des images bitmap ou des formes quelconques. Il
existe beaucoup de sous-classes de Drawable.
Un Drawable est cr :
134
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
par une image PNG ou JPG dans res/drawable...
Bitmap bm = BitmapFactory
.decodeResource(getResources(),
R.drawable.image);
Drawable d = new BitmapDrawable(getResources(),bm);
Android a dfini une norme pour des images PNG tirables, les 9patch .
8.1.12 Images
PNG tirables 9patch
Il sagit dimages PNG nommes en .9.png qui peuvent tre dessines de diffrentes tailles. gauche,
limage dorigine et droite, 3 exemplaires tirs.
Figure 46: Image tirable
Une image 9patch est borde sur ses 4 cts par des lignes noires qui spcifient les zones tirables
en haut et gauche, et les zones qui peuvent tre occupes par du texte droite et en bas.
Il faut utiliser loutil draw9patch pour les diter. a demande un peu de savoir-faire.
8.1.13 Drawable,
suite
Un drawable peut galement provenir dune forme vectorielle dans un fichier XML. Exemple :
res/drawable/carre.xml :
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke android:width="4dp" android:color="#F000" />
<gradient android:angle="90"
android:startColor="#FFBB"
android:endColor="#F77B" />
<corners android:radius="16dp" />
</shape>
Figure 47: Dessin vectoriel XML
135
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
8.1.14 Variantes
Android permet de crer des dessinables variantes par exemple pour des boutons personnaliss.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="...">
<item android:drawable="@drawable/button_pressed"
android:state_pressed="true" />
<item android:drawable="@drawable/button_checked"
android:state_checked="true" />
<item android:drawable="@drawable/button_default" />
</selector>
Lune ou lautre des images sera choisie en fonction de ltat du bouton, enfonc, relch, inactif.
8.1.15 Utilisation
dun Drawable
Ces objets dessinable peuvent tre employs dans un canvas. Puisque ce sont des objets vectoriels, il
faut dfinir les coordonnes des coins haut-gauche et bas-droit, ce qui permet dtirer la figure. Les
tailles qui sont indiques dans le xml sont pourtant absolues.
Drawable drw = getResources().getDrawable(R.drawable.carre);
drw.setBounds(x1, y1, x2, y2); // coins
drw.draw(canvas);
Remarquez le petit pige de la dernire instruction, on passe le canvas en paramtre la mthode
draw du drawable.
NB: la premire instruction est placer dans le constructeur de la vue, afin de ne pas ralentir la
fonction de dessin.
8.1.16 Enregistrer
un dessin dans un fichier
Cest trs facile. Il suffit de rcuprer le bitmap associ la vue, puis de le compresser en PNG.
public void save(String filename)
{
Bitmap bitmap = getDrawingCache();
try {
FileOutputStream out = new FileOutputStream(filename);
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
out.close();
} catch (Exception e) {
...
}
}
136
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
8.1.17 Coordonnes
dans un canvas
Un dernier mot sur les canvas. Il y a tout un mcanisme permettant de modifier les coordonnes
dans un canvas :
dplacer lorigine avec translate(dx,dy) : toutes les coordonnes fournies ultrieurement
seront additionnes (dx,dy)
multiplier les coordonnes par sx,sy avec scale(sx,sy)
pivoter les coordonnes autour de (px,py) dun angle ao avec rotate(a, px, py)
En fait, il y a un mcanisme de transformations matricielles 2D appliques aux coordonnes, ainsi
quune pile permettant de sauver la transformation actuelle ou la restituer.
save() : enregistre la matrice actuelle
restore() : restitue la matrice avec celle qui avait t sauve
8.2
Interactions avec lutilisateur
8.2.1 couteurs pour les touchers de lcran
Il existe beaucoup dcouteurs pour les actions de lutilisateur sur une zone de dessin. Parmi elles, on
doit connatre onTouchEvent. Son paramtre indique la nature de laction (toucher, mouvement. . . )
ainsi que les coordonnes.
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
...
break;
}
return true;
}
8.2.2
Modle de gestion des actions
Souvent il faut distinguer le premier toucher (ex: cration dune figure) des mouvements suivants (ex:
taille de la figure).
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
figure = Figure.creer(typefigure, color);
figure.setReference(x, y);
figures.add(figure);
break;
case MotionEvent.ACTION_MOVE:
137
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
if (figures.size() < 1) return true;
figure = figures.getLast();
figure.setCoin(x,y);
break;
}
invalidate();
8.2.3
Automate pour grer les actions
Lalgo prcdent peut se reprsenter laide dun automate de Mealy deux tats : repos et en cours
ddition dune figure. Les changements dtats sont dclenchs par les actions utilisateur et effectuent
un traitement.
Figure 48: Automate
8.3
Botes de dialogue spcifiques
8.3.1 Slecteur de couleur
Android ne propose pas de slecteur de couleur, alors il faut le construire soi-mme.
Figure 49: Slecteur de couleur
8.3.2
Version simple
En TP, on va construire une version simplifie afin de comprendre le principe :
138
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 50: Slecteur de couleur simple
8.3.3
Concepts
Plusieurs concepts interviennent dans ce slecteur de couleur :
La fentre drive de DialogFragment, elle affiche un dialogue de type AlertDialog avec des
boutons Ok et Annuler,
Cet AlertDialog contient une vue personnalise contenant des SeekBar pour rgler les composantes de couleur,
Les SeekBar du layout ont des callbacks qui mettent jour la couleur choisie en temps rel,
Le bouton Valider du AlertDialog dclenche un couteur dans lactivit qui a appel le slecteur.
8.3.4
Fragment de dialogue
Le fragment de dialogue doit dfinir plusieurs choses :
Cest une sous-classe de FragmentDialog
public class ColorPickerDialog extends DialogFragment
Il dfinit une interface pour un couteur quil appellera la fin :
public interface OnColorChangedListener {
void colorChanged(int color);
}
Une mthode onCreateDialog retourne un AlertDialog pour bnficier des boutons ok et
annuler. Le bouton ok est associ une callback qui active lcouteur en lui fournissant la
couleur.
8.3.5
Mthode onCreateDialog
public Dialog onCreateDialog(Bundle savedInstanceState) {
Context ctx = getActivity();
Builder builder = new AlertDialog.Builder(ctx);
builder.setTitle("Choisissez une couleur");
139
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
final ColorPickerView cpv = new ColorPickerView(ctx);
builder.setView(cpv);
builder.setPositiveButton(android.R.string.yes,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int btn) {
// prvenir l'couteur
mListener.colorChanged(cpv.getColor());
}
});
builder.setNegativeButton(android.R.string.no, null);
return builder.create();
}
8.3.6
Vue personnalise dans le dialogue
Voici la dfinition de la classe ColorPickerView qui est lintrieur du dialogue dalerte. Elle gre
quatre curseurs et une couleur :
private static class ColorPickerView extends LinearLayout {
// couleur dfinie par les curseurs
private int mColor;
// constructeur
ColorPickerView(Context context) {
// constructeur de la superclasse
super(context);
// mettre en place le layout
inflate(getContext(), R.layout.colorpickerdialog, this);
...
}
8.3.7
Layout de cette vue
Le layout colorpickerdialog.xml contient quatre SeekBar, rouge, vert, bleu et alpha. Ils ont une
callback comme celle-ci :
SeekBar sbRouge = (SeekBar) findViewById(R.id.sbRouge);
sbRouge.setOnSeekBarChangeListener(
new OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar,
int progress, boolean fromUser) {
mColor = Color.argb(
Color.alpha(mColor), progress,
Color.green(mColor), Color.blue(mColor));
}
});
Elle change seulement la composante rouge de la variable mColor. Il y a les mmes choses pour le
vert, le bleu et la transparence.
140
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
8.3.8
Utilisation du dialogue
Pour finir, voici comment on affiche ce dialogue, par exemple dans un menu :
new ColorPickerDialog(
new ColorPickerDialog.OnColorChangedListener() {
@Override
public void colorChanged(int color) {
// utiliser la couleur ....
}
}
).show(getFragmentManager(), "fragment_colorpicker");
Cela consiste dfinir un couteur qui reoit la nouvelle couleur du slecteur. Lcouteur peut la
transmettre la classe qui dessine une nouvelle figure.
8.3.9
Slecteur de fichier
Dans le mme genre mais nettement trop complexe, il y a le slecteur de fichiers pour enregistrer un
dessin.
141
INNOV MAROC 39 rue Vouziers, Angl Bvd Emile Zola, Casablanca
Tel : 0522 24 72 10 Site web : http://www.innov-maroc.com email : contact@ innov-maroc.com
Figure 51: Slecteur de fichier
142