Environnement de dveloppement
1.1
1.2
1.3
14
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
1.1.1
Android . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
1.1.2
Dfinition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
1.1.3
Composants dAndroid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
1.1.4
Programmation dapplications . . . . . . . . . . . . . . . . . . . . . . . . . .
16
16
1.2.1
SDK Android . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
1.2.2
SDK Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
1.2.3
16
1.2.4
Dossiers du SDK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
1.2.5
Android Studio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
Premire application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
1.3.1
Objectif de la semaine 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
1.3.2
18
IUT de Lannion
Dept Informatique
1.4
1.5
1.6
Programmation Android
P. Nerzic
2015-16
1.3.3
Choix de la version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
1.3.4
Choix de la version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
1.3.5
18
1.3.6
Points configurer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
1.3.7
22
1.3.8
Rsultat de lassistant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
1.3.9
Fentre du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
1.3.10
diteurs spcifiques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
1.3.11
Exemple res/values/strings.xml . . . . . . . . . . . . . . . . . . . . . . .
23
1.3.12
Exemple res/layout/main.xml . . . . . . . . . . . . . . . . . . . . . . . . .
23
1.3.13
23
1.3.14
Reconstruction du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
Premire excution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
1.4.1
Excution de lapplication . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
1.4.2
26
1.4.3
27
1.4.4
27
1.4.5
27
1.4.6
Contrle de lAVD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
27
1.5.1
Fentres Android . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
1.5.2
Fentre LogCat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
28
1.5.3
28
1.5.4
28
1.5.5
Logiciel ADB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
29
1.5.6
29
1.5.7
29
1.5.8
30
1.5.9
30
30
1.6.1
Paquet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
30
1.6.2
31
1.6.3
Cration du keystore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
1.6.4
Cration dune cl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
1.6.5
Cration du paquet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
1.6.6
Et voil
33
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2
34
Interface et ressources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
2.1.1
Activits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
2.1.2
34
2.1.3
Identifiant de ressource . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35
2.1.4
La classe R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35
2.1.5
35
2.1.6
36
2.1.7
36
2.1.8
Programme et ressources . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
2.1.9
37
2.1.10
37
2.1.11
Identifiants et vues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37
2.1.12
38
2.1.13
Images : R.drawable.nom . . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
2.1.14
38
2.1.15
Autres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
39
Dispositions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
39
2.2.1
39
2.2.2
39
2.2.3
Reprsentation en XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
40
2.2.4
Paramtres de positionnement . . . . . . . . . . . . . . . . . . . . . . . . . .
40
2.2.5
Paramtres gnraux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
40
2.2.6
40
2.2.7
Marges et remplissage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
41
2.2.8
41
2.2.9
41
2.2.10
42
2.2.11
42
2.2.12
43
2.2.13
43
IUT de Lannion
Dept Informatique
2.3
2.4
Programmation Android
P. Nerzic
2015-16
2.2.14
43
2.2.15
Autres groupements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
44
Composants dinterface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
44
2.3.1
Vues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
44
2.3.2
TextView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
44
2.3.3
Button . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
44
2.3.4
Bascules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
45
2.3.5
EditText . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
45
2.3.6
Autres vues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
45
Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
45
2.4.1
Styles et thmes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
45
2.4.2
Dfinir un style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
45
2.4.3
Utiliser un style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
46
2.4.4
Utiliser un thme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
46
2.4.5
Cest tout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
46
3.2
47
Applications et activits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
47
3.1.1
47
3.1.2
47
3.1.3
48
3.1.4
48
3.1.5
48
3.1.6
49
3.1.7
49
3.1.8
49
3.1.9
49
Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
50
3.2.1
50
3.2.2
50
3.2.3
50
3.2.4
50
3.2.5
52
3.2.6
52
IUT de Lannion
Dept Informatique
3.3
3.4
Programmation Android
P. Nerzic
2015-16
3.2.7
Mthode onActivityResult . . . . . . . . . . . . . . . . . . . . . . . . . . .
52
3.2.8
53
3.2.9
53
3.2.10
Contexte dapplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
53
3.2.11
53
3.2.12
54
3.2.13
54
Activits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
54
3.3.1
Prsentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
54
3.3.2
55
3.3.3
55
3.3.4
Squelette dactivit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
55
3.3.5
56
3.3.6
56
3.3.7
56
3.3.8
57
3.3.9
57
Vues et activits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
57
3.4.1
57
3.4.2
58
3.4.3
Actions de lutilisateur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
58
3.4.4
58
3.4.5
59
3.4.6
couteur priv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
59
3.4.7
59
3.4.8
60
3.4.9
60
3.4.10
60
Application liste
4.1
61
Prsentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
61
4.1.1
Principe gnral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
61
4.1.2
Schma global . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
4.1.3
62
IUT de Lannion
Dept Informatique
4.2
4.3
4.4
Programmation Android
P. Nerzic
2015-16
4.1.4
Donnes initiales
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
4.1.5
63
4.1.6
63
4.1.7
64
4.1.8
64
4.1.9
Remarques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
64
Affichage de la liste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
64
4.2.1
64
4.2.2
Mise en uvre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
65
4.2.3
65
4.2.4
65
4.2.5
66
4.2.6
Autre layouts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
66
4.2.7
Layouts prdfinis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
66
Adaptateurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
67
4.3.1
67
4.3.2
67
4.3.3
Adaptateurs prdfinis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
67
4.3.4
67
4.3.5
Exemple demploi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
68
4.3.6
68
4.3.7
68
Adaptateur personnalis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
69
4.4.1
69
4.4.2
69
4.4.3
70
4.4.4
Mthode PlaneteView.create . . . . . . . . . . . . . . . . . . . . . . . . . .
70
4.4.5
70
4.4.6
71
4.4.7
71
4.4.8
71
4.4.9
72
4.4.10
Mthode PlaneteView.create . . . . . . . . . . . . . . . . . . . . . . . . . .
72
4.4.11
Mthode findViews . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
72
IUT de Lannion
Dept Informatique
4.5
Programmation Android
P. Nerzic
2015-16
4.4.12
. . . . . . . . . . . . . . . . .
73
4.4.13
Rcapitulatif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
73
4.4.14
Le rsultat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
73
73
4.5.1
73
4.5.2
74
4.5.3
74
4.5.4
75
4.5.5
75
4.5.6
75
4.5.7
75
4.5.8
76
4.5.9
76
4.5.10
77
Ergonomie
5.1
5.2
78
78
5.1.1
Barre daction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
78
5.1.2
78
5.1.3
79
5.1.4
79
5.1.5
. . . . . . . . . . . . . . . . . . . . . . . . .
79
5.1.6
80
5.1.7
80
5.1.8
Menus en cascade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
80
5.1.9
Menus contextuels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
81
5.1.10
81
5.1.11
82
5.1.12
82
Annonces et dialogues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
82
5.2.1
Annonces : toasts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
82
5.2.2
Annonces personnalises . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
83
5.2.3
Dialogues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
83
5.2.4
Dialogue dalerte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
84
IUT de Lannion
Dept Informatique
5.3
5.4
Programmation Android
P. Nerzic
2015-16
5.2.5
84
5.2.6
84
5.2.7
Dialogues personnaliss . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
85
5.2.8
85
5.2.9
Affichage du dialogue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
85
Fragments et activits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
86
5.3.1
Fragments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
86
5.3.2
Tablettes, smartphones. . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
86
5.3.3
86
5.3.4
87
5.3.5
87
5.3.6
ListFragment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
87
5.3.7
ListFragment, suite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
88
5.3.8
Menus de fragments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
88
5.3.9
89
5.3.10
89
5.3.11
FragmentManager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
89
5.3.12
89
5.3.13
. . . . . . . . . . . . . . . . . . . .
90
5.3.14
90
5.3.15
91
5.3.16
91
5.3.17
91
5.3.18
couteur du fragment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
92
5.3.19
couteur de lactivit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
92
5.3.20
93
5.3.21
mditer, partie 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
93
Prfrences dapplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
93
5.4.1
Illustration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
93
5.4.2
Prsentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
93
5.4.3
94
5.4.4
Explications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
94
5.4.5
95
5.4.6
95
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
5.4.7
95
5.4.8
96
5.4.9
96
5.4.10
96
6.2
97
SQLite3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
97
6.1.1
Stockage dinformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
97
6.1.2
SQLite3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
97
6.1.3
Exemples SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
98
6.1.4
98
6.1.5
98
6.1.6
Commandes internes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
98
99
6.2.1
99
6.2.2
99
6.2.3
Principes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
99
6.2.4
6.2.5
Recommandations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
6.2.6
6.2.7
6.2.8
6.2.9
6.2.10
6.2.11
6.2.12
6.2.13
6.2.14
6.2.15
6.2.16
6.2.17
6.2.18
6.2.19
6.2.20
IUT de Lannion
Dept Informatique
6.3
6.4
P. Nerzic
2015-16
6.2.21
6.2.22
6.2.23
6.2.24
6.2.25
6.2.26
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
6.3.2
6.3.3
6.3.4
6.3.5
6.3.6
6.3.7
6.3.8
6.3.9
ContentProviders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
6.4.1
6.5
Programmation Android
WebServices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
6.5.1
6.5.2
6.5.3
6.5.4
6.5.5
6.5.6
6.5.7
6.5.8
6.5.9
6.5.10
6.5.11
6.5.12
6.5.13
10
IUT de Lannion
Dept Informatique
Programmation Android
7.2
7.3
P. Nerzic
2015-16
115
AsyncTasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
7.1.1
Prsentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
7.1.2
7.1.3
7.1.4
7.1.5
7.1.6
7.1.7
7.1.8
7.1.9
AsyncTask, suite
7.1.10
7.1.11
7.1.12
7.1.13
7.1.14
Simplification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
7.1.15
Recommandations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
7.1.16
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Prsentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
7.2.2
7.2.3
7.2.4
7.2.5
7.2.6
7.2.7
7.2.8
OpenStreetMap
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
7.3.1
Prsentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
7.3.2
Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
7.3.3
7.3.4
7.3.5
7.3.6
IUT de Lannion
Dept Informatique
Programmation Android
7.3.7
Calques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
7.3.8
7.3.9
Marqueurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
7.3.10
7.3.11
7.3.12
Itinraires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
7.3.13
7.3.14
Autorisations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
7.3.15
7.3.16
7.3.17
7.3.18
7.3.19
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Dessin 2D interactif
8.1
8.2
P. Nerzic
2015-16
130
Dessin en 2D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
8.1.1
Principes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
8.1.2
8.1.3
8.1.4
8.1.5
8.1.6
8.1.7
Motifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
8.1.8
Shaders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
8.1.9
8.1.10
8.1.11
Dessinables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
8.1.12
8.1.13
8.1.14
Variantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
8.1.15
8.1.16
8.1.17
IUT de Lannion
Dept Informatique
8.3
Programmation Android
P. Nerzic
2015-16
8.2.1
8.2.2
8.2.3
8.3.2
8.3.3
Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
8.3.4
8.3.5
8.3.6
8.3.7
8.3.8
8.3.9
8.3.10
13
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
Semaine 1
Environnement de dveloppement
Le cours de cette semaine prsente lenvironnement de dveloppement Android :
Le SDK Android et Android Studio
Cration dune application simple
Communication avec une tablette.
1.1.
1.1.1.
Introduction
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
14
IUT de Lannion
Dept Informatique
Programmation Android
15
P. Nerzic
2015-16
IUT de Lannion
Dept Informatique
1.1.3.
P. Nerzic
2015-16
Programmation Android
Composants dAndroid
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.
1.2.1.
Le SDK contient :
les
les
un
un
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, page 17.
1.2.3.
16
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
Android
Android
Android
Android
...
Android
6 (API 23)
5.1.1 (API 22)
5.0.1 (API 21)
4.4W.2 (API 20)
1.5 (API 3)
1.2.4.
Dossiers du SDK
1.2.5.
Android Studio
Pour finir, il faut installer Android Studio selon la procdure explique sur cette page. Il est dj
install lIUT, mais en version un peu plus ancienne.
17
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
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.
Objectif de la semaine 1
1.3.2.
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
1.3.5.
Ensuite, on choisit le type de projet. Pour un premier essai, on se limite au plus simple, Blank
Activity :
Voir la figure 5, page 21.
18
IUT de Lannion
Dept Informatique
Programmation Android
19
P. Nerzic
2015-16
IUT de Lannion
Dept Informatique
Programmation Android
20
P. Nerzic
2015-16
IUT de Lannion
Dept Informatique
Programmation Android
21
P. Nerzic
2015-16
IUT de Lannion
Dept Informatique
1.3.6.
Programmation Android
Points configurer
Nom
Nom
Nom
Nom
de lapplication, ex : HellorHorde,
de la classe principale : MainActivity,
du layout de la classe principale : activity_main,
du layout du menu principal : menu_main.
1.3.7.
1.3.8.
Rsultat de lassistant
1.3.9.
Fentre du projet
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
22
P. Nerzic
2015-16
IUT de Lannion
Dept Informatique
Programmation Android
23
P. Nerzic
2015-16
IUT de Lannion
Dept Informatique
Programmation Android
Figure 7: lments24
dun projet Android
P. Nerzic
2015-16
IUT de Lannion
Dept Informatique
Programmation Android
25
P. Nerzic
2015-16
IUT de Lannion
Dept Informatique
1.3.12.
Programmation Android
P. Nerzic
2015-16
Exemple res/layout/main.xml
1.3.13.
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.
1.4.1.
Premire excution
Excution de lapplication
1.4.2.
1.4.3.
IUT de Lannion
Dept Informatique
Programmation Android
27
P. Nerzic
2015-16
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
1.4.4.
1.4.5.
1.4.6.
Contrle de lAVD
1.5.
1.5.1.
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
IUT de Lannion
Dept Informatique
Programmation Android
29
P. Nerzic
2015-16
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
1.5.3.
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.
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.
IUT de Lannion
Dept Informatique
1.5.7.
Programmation Android
P. Nerzic
2015-16
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.
1.5.9.
31
. . . enfin en
IUT de Lannion
Dept Informatique
1.6.
1.6.1.
Programmation Android
P. Nerzic
2015-16
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.
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.
1.6.3.
Cration du keystore
1.6.4.
Cration dune cl
1.6.5.
Cration du paquet
1.6.6.
Et voil
Cest fini pour cette semaine, rendez-vous la semaine prochaine pour un cours sur les interfaces
Android.
32
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
Semaine 2
Cration dinterfaces utilisateur
Le cours de cette semaine 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 la semaine prochaine.
NB: les textes fuchsia sont des liens cliquables.
33
IUT de Lannion
Dept Informatique
Programmation Android
34
P. Nerzic
2015-16
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
2.1.
2.1.1.
Interface et ressources
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.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
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
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.
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
</element>
texte en vrac
</racine>
2.1.6.
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.
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
37
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
2.1.9.
2.1.10.
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
IUT de Lannion
Dept Informatique
Programmation Android
<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.
2.1.13.
Images : R.drawable.nom
2.1.14.
P. Nerzic
2015-16
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
2.1.15.
Autres
2.2.
2.2.1.
Dispositions
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.
2.2.3.
Reprsentation en XML
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
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
2.2.6.
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
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.
2.2.9.
Une faon intressante de spcifier les tailles des vues dans un LinearLayout consiste leur affecter
un poids avec lattribut android:layout_weight.
42
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
2.2.10.
Voici 4 LinearLayout horizontaux de 3 boutons ayant des poids gaux leurs titres. En 3e ligne, les
boutons ont une largeur de 0dp
2.2.11.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
2.2.12.
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.
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.
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
IUT de Lannion
Dept Informatique
2.2.15.
P. Nerzic
2015-16
Programmation Android
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.
2.3.1.
Composants dinterface
Vues
2.3.2.
TextView
<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
IUT de Lannion
Dept Informatique
2.3.4.
Programmation Android
P. Nerzic
2015-16
Bascules
2.3.5.
EditText
<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 les prochaines semaines, pour prciser les attributs utiles pour une
application. Dautres vues pourront aussi tre employes loccasion.
2.4.
2.4.1.
Styles
Styles et thmes
2.4.2.
Dfinir un style
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
2.4.3.
Utiliser un style
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.
2.4.5.
Cest tout
Cest fini pour cette semaine, rendez-vous la semaine prochaine pour un cours sur les couteurs et les
activits.
47
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
Semaine 3
Vie dune application
Le cours de cette semaine concerne la 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.
3.1.1.
Applications et activits
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, voir la semaine 5,
des rcepteurs dannonces : pour grer des vnements globaux envoys par le systme toutes
les applications.
3.1.2.
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
IUT de Lannion
Dept Informatique
3.1.3.
Programmation Android
P. Nerzic
2015-16
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.
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.
49
IUT de Lannion
Dept Informatique
3.1.6.
Programmation Android
P. Nerzic
2015-16
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.
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.
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.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
"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.
3.2.1.
Applications
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.
3.2.3.
3.2.4.
Le lancement dune activit avec attente de rsultat est plus complexe. Il faut dfinir un code dappel
RequestCode fourni au lancement.
51
IUT de Lannion
Dept Informatique
Programmation Android
52
P. Nerzic
2015-16
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
3.2.5.
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.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
3.2.8.
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.
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.
54
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
// initialisation du contexte
@Override
public void onCreate()
{
super.onCreate();
varglob = 3;
}
3.2.12.
3.2.13.
3.3.
3.3.1.
Activits
Prsentation
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
3.3.2.
3.3.3.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@Override signifie que cette mthode remplace celle hrite de la superclasse. Il faut quand mme
lappeler sur super en premier.
3.3.5.
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.
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.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
3.3.8.
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.
3.4.
Vues et activits
3.4.1.
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
IUT de Lannion
Dept Informatique
3.4.2.
Programmation Android
P. Nerzic
2015-16
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.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
btn.setOnClickListener(ecouteur);
3.4.5.
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.
IUT de Lannion
Dept Informatique
3.4.8.
Programmation Android
P. Nerzic
2015-16
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.
Heureusement, dans le cas de formulaires, les actions sont majoritairement bases sur des boutons.
3.4.10.
Cest assez pour cette semaine, rendez-vous la semaine prochaine pour un cours sur les applications
de gestion de donnes (listes ditems).
Plus tard, nous verrons comment Android raffine la notion dactivit, en la sparant en fragments.
61
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
Semaine 4
Application liste
Durant les prochaines semaines, nous allons nous intresser aux applications de gestion dune liste
ditems.
Stockage dune liste
Affichage dune liste, adaptateurs
Consultation et dition dun item
4.1.
4.1.1.
Prsentation
Principe gnral
On veut programmer une application pour afficher et diter une liste ditems.
Cette semaine, la liste est stocke dans un tableau dynamique appel ArrayList ; en semaine
6, a sera dans une base de donnes SQL locale ou sur un serveur distant.
62
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
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.
4.1.3.
};
4.1.4.
Donnes initiales
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
4.1.5.
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.
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 :
64
IUT de Lannion
Dept Informatique
4.1.7.
Programmation Android
P. Nerzic
2015-16
4.1.8.
4.1.9.
Remarques
Cette semaine, 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 en
semaine 3 et mettre ce tableau ainsi que son initialisation dedans. Ainsi, le tableau devient disponible
dans toutes les activits de lapplication. Voir le TP4.
En semaine 6, nous verrons comment utiliser une base de donnes SQL locale ou un WebService, ce
qui rsoud proprement le problme.
4.2.
4.2.1.
Affichage de la liste
Activit spcialise ou layout
Deux possibilits :
employer la classe ListActivity,
65
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
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.
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.
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);
66
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
// initialisation de la liste
mListe = new ArrayList<Planete>();
...
4.2.5.
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.
4.2.7.
Layouts prdfinis
IUT de Lannion
Dept Informatique
4.3.
4.3.1.
Programmation Android
P. Nerzic
2015-16
Adaptateurs
Relations entre la vue et les donnes
4.3.2.
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
4.3.4.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
4.3.5.
Exemple demploi
4.3.6.
4.3.7.
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
4.4.
Adaptateur personnalis
4.4.1.
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.
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
IUT de Lannion
Dept Informatique
4.4.3.
Programmation Android
P. Nerzic
2015-16
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.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
package fr.iutlan.planetes;
public class PlaneteView extends RelativeLayout
{
...
4.4.6.
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.
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.
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
4.4.9.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
R.id.item_planete_distance);
ivImage = (ImageView) findViewById(
R.id.item_planete_image);
4.4.12.
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
4.4.14.
4.5.
4.5.1.
Le rsultat
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
IUT de Lannion
Dept Informatique
P. Nerzic
2015-16
Programmation Android
4.5.2.
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.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
4.5.4.
4.5.5.
4.5.6.
4.5.7.
76
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
ListView lv=(ListView)findViewById(android.R.id.list);
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
4.5.8.
4.5.9.
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
IUT de Lannion
Dept Informatique
4.5.10.
Programmation Android
P. Nerzic
2015-16
Cest tout pour cette semaine. La semaine prochaine nous parlerons des menus, dialogues et fragments.
78
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
Semaine 5
Ergonomie
Le cours de cette semaine concerne lergonomie dune application Android.
5.1.
5.1.1.
La barre daction contient licne dapplication (1), quelques items de menu (2) et un bouton pour
avoir les autres (3).
5.1.2.
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
IUT de Lannion
Dept Informatique
5.1.3.
Programmation Android
P. Nerzic
2015-16
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.
Android distribue gratuitement un grand jeu dicnes pour les menus, dans les deux styles : HoloDark
et HoloLight.
5.1.5.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
<resources>
<style name="AppBaseTheme"
parent="android:Theme.Holo.Light" />
</resources>
Utiliser lassistant pour avoir les thmes adquats.
5.1.6.
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.
5.1.8.
Menus en cascade
81
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
5.1.9.
Menus contextuels
5.1.10.
82
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
lv.setOnCreateContextMenuListener(this);
5.1.11.
5.1.12.
5.2.
5.2.1.
Annonces et dialogues
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
5.2.2.
Annonces personnalises
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.
84
IUT de Lannion
Dept Informatique
5.2.4.
Programmation Android
P. Nerzic
2015-16
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.
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.
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
IUT de Lannion
Dept Informatique
5.2.7.
Programmation Android
P. Nerzic
2015-16
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.
5.2.8.
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
IUT de Lannion
Dept Informatique
5.3.
5.3.1.
Programmation Android
P. Nerzic
2015-16
Fragments et activits
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.
5.3.3.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(
R.layout.infos_fragment, container, false);
}
5.3.4.
5.3.5.
Les fragments ont un cycle de vie similaire celui des activits, avec quelques mthodes de plus
correspondant leur intgration dans une activit.
5.3.6.
ListFragment
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState)
{
// liste des lments venant de l'application
FragmentApplication app = (FragmentApplication)
getActivity().getApplicationContext();
listeItems = app.getListe();
// layout du fragment
setHasOptionsMenu(true);
// le fragment a un menu
return inflater.inflate(android.R.layout.list_content,
container, false);
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
IUT de Lannion
Dept Informatique
5.3.9.
Programmation Android
P. Nerzic
2015-16
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.
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.
En trois temps : obtention du manager, cration dune transaction et attribution des fragments aux
rceptacles .
90
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
// 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.
Le plus intressant est de faire apparatre les fragments en fonction de la taille et lorientation de
lcran (application liste + infos ).
5.3.14.
91
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
<LinearLayout xmlns:android="..."
android:orientation="horizontal" ... >
<fragment android:id="@+id/frag_liste" ... />
<fragment android:id="@+id/frag_infos" ... />
</LinearLayout>
5.3.15.
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.
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.
Dabord la classe ListeFragment : dfinir une interface pour grer les slections ditems et un
couteur :
92
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
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
IUT de Lannion
Dept Informatique
5.3.20.
Programmation Android
P. Nerzic
2015-16
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);
}
5.4.
5.4.1.
Prfrences dapplication
Illustration
Les prfrences mmorisent des choix de lutilisateur entre deux excutions de lapplication.
5.4.2.
Prsentation
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
5.4.3.
5.4.4.
Explications
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
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.
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.
5.4.7.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
editor.putInt("prefs_nbmax", 20);
// fin de la transaction
editor.commit();
5.4.8.
5.4.9.
5.4.10.
Cest fini pour cette semaine, rendez-vous la semaine prochaine pour un cours sur les adaptateurs de
bases de donnes et les WebServices.
97
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
Semaine 6
Bases de donnes SQLite3 <>
Aprs avoir reprsent une liste ditems sous forme dun tableau en semaine 4, nous allons la stocker
dans un SGBD SQL.
6.1.
6.1.1.
SQLite3
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
6.1.3.
Exemples SQL
6.1.4.
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.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
.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.
6.2.1.
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.
6.2.3.
Principes
100
IUT de Lannion
Dept Informatique
6.2.4.
Programmation Android
P. Nerzic
2015-16
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.
...
101
IUT de Lannion
Dept Informatique
6.2.7.
P. Nerzic
2015-16
Programmation Android
+
+
+
6.2.8.
Exemples de mthodes
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
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
6.2.12.
IUT de Lannion
Dept Informatique
6.2.13.
Programmation Android
P. Nerzic
2015-16
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
try {
if (cursor.moveToFirst()) {
while (!cursor.isAfterLast()) {
/** utiliser le curseur... **/
cursor.moveToNext();
}
}
} finally {
if (cursor != null) cursor.close();
}
table WHERE...");
// obligatoire
// test de fin
// n-uplet suivant
6.2.14.
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
IUT de Lannion
Dept Informatique
6.2.16.
Programmation Android
P. Nerzic
2015-16
6.2.17.
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.
Revenons vers les aspects gestion interne de la base de donnes. Louverture dune base se fait ainsi :
105
IUT de Lannion
Dept Informatique
P. Nerzic
2015-16
Programmation Android
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.
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 ("
"_id INTEGER PRIMARY KEY AUTOINCREMENT,"
"nom TEXT NOT NULL)");
+
+
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.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
6.2.23.
@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
107
IUT de Lannion
Dept Informatique
6.2.25.
Programmation Android
P. Nerzic
2015-16
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.
6.3.1.
CursorAdapter et Loaders
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
IUT de Lannion
Dept Informatique
6.3.2.
Programmation Android
P. Nerzic
2015-16
tapes suivre
6.3.3.
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.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
6.3.5.
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 : onCreateLoader,
onLoadFinished et onLoaderReset. Voyons dabord la premire.
6.3.6.
6.3.7.
classe MonCursorLoader
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
@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.
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.
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
IUT de Lannion
Dept Informatique
6.5.
6.5.1.
Programmation Android
P. Nerzic
2015-16
WebServices
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.
112
IUT de Lannion
Dept Informatique
6.5.4.
Programmation Android
P. Nerzic
2015-16
6.5.5.
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
IUT de Lannion
Dept Informatique
6.5.7.
Programmation Android
P. Nerzic
2015-16
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.
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 la semaine prochaine.
6.5.10.
114
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
6.5.11.
Script update_planete.php
6.5.12.
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. On verra cela la semaine prochaine.
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.
6.5.13.
Cest fini pour cette semaine, rendez-vous la semaine prochaine pour un cours sur les accs rseau
asynchrones ainsi que la cartographie OpenStreetView.
115
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
Semaine 7
Affichage de donnes golocalises
Cette semaine 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).
7.1.2.
Tches asynchrones
116
IUT de Lannion
Dept Informatique
7.1.3.
Programmation Android
P. Nerzic
2015-16
7.1.4.
7.1.5.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
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.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
7.1.10.
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.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
7.1.13.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
}
protected void onPostExecute(Float pluie) {
// utiliser pluie, ex: l'afficher dans un TextView
...
}
7.1.15.
Recommandations
7.1.16.
7.2.
7.2.1.
Requtes HTTP
Prsentation
Voici quelques explications sur la manire de faire une requte HTTP dune tablette vers un serveur.
Android propose plusieurs mcanismes :
121
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
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.
Crer une instance de URL qui indique lurl de la page voulue, avec ses paramtres,
Crer une instance de HttpURLConnection en appelant openConnection() sur lURL,
(optionnel) Configurer la requte : agent, authentification, type mime, session, cookies. . .
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.
7.2.4.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
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.
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.
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.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
7.2.8.
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.
7.3.1.
OpenStreetMap
Prsentation
Au contraire de Google Maps, OSM est vraiment libre et OpenSource, et il se programme extrmement
facilement.
7.3.2.
Documentation
7.3.3.
Pour commencer
7.3.4.
124
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
7.3.5.
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
IUT de Lannion
Dept Informatique
7.3.7.
Programmation Android
P. Nerzic
2015-16
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.
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
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
7.3.11.
Raction un clic
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
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.
IUT de Lannion
Dept Informatique
7.3.16.
Programmation Android
P. Nerzic
2015-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.
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 LongPressMapOverlay(this));
7.3.18.
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.
7.3.19.
Cest fini pour cette semaine, rendez-vous la semaine prochaine pour un cours sur le dessin en 2D.
130
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
Semaine 8
Dessin 2D interactif
Le cours de cette semaine concerne le dessin de figures 2D et les interactions avec lutilisateur.
CustomView et Canevas
Un exemple de bote de dialogue utile
8.1.
8.1.1.
Dessin en 2D
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
mPeinture.setColor(Color.BLUE);
}
public void onDraw(Canvas canvas) {
canvas.drawCircle(100, 100, 50, mPeinture);
}
8.1.2.
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.
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
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.
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
IUT de Lannion
Dept Informatique
8.1.8.
Programmation Android
P. Nerzic
2015-16
Shaders
8.1.9.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
8.1.12.
Il sagit dimages PNG nommes en .9.png qui peuvent tre dessines de diffrentes tailles. gauche,
limage dorigine et droite, 3 exemplaires tirs.
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>
135
IUT de Lannion
Dept Informatique
8.1.14.
Programmation Android
P. Nerzic
2015-16
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.
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.
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
IUT de Lannion
Dept Informatique
8.1.17.
Programmation Android
P. Nerzic
2015-16
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.
8.2.1.
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.
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
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
8.2.3.
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.
8.3.
8.3.1.
8.3.2.
Version simple
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
8.3.3.
Concepts
8.3.4.
Fragment de dialogue
8.3.5.
Mthode onCreateDialog
IUT de Lannion
Dept Informatique
Programmation Android
P. Nerzic
2015-16
8.3.6.
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.
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
IUT de Lannion
Dept Informatique
8.3.8.
Programmation Android
P. Nerzic
2015-16
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.
8.3.10.
Cest la fin
Cest fini, nous avons tudi tout ce quil tait raisonnable de faire en 8 semaines.
141
IUT de Lannion
Dept Informatique
Programmation Android
142
P. Nerzic
2015-16