Développement sur Android - V. Barichard L3 - Info
←
→
Transcription du contenu de la page
Si votre navigateur ne rend pas la page correctement, lisez s'il vous plaît le contenu de la page ci-dessous
Développement sur Android
V. Barichard
LERIA - Département Informatique
Université d’Angers
L3 - Info
L3 - Info Développement sur Android 1Une histoire très récente
La naissance du smartphone
1994 : Le Simon IBM®
1996 : Les Nokia® sous Symbian
1997 : Les smartphones Ericsson®
2001 : L’environnement Palm OS
2002 : Le Pocket PC de Microsoft®
2002 : Les smartphones BlackBerry®
2007 : L’Iphone avec l’iOS d’Apple®
2008 : Le HTC Dream sous l’Android de
Google®
L3 - Info Développement sur Android 4Une histoire très récente
Le développement sur smartphones
L’émergence de iOS
iOS est le premier système d’exploitation démocratisant
l’utilisation des smartphones
Simple d’utilisation et pourvu d’un grand nombre
d’applications il plait au plus grand nombre
Il est associé à un «SDK» et un «store» d’applications
accessibles aux développeurs
BlackBerry est plus orienté vers les professionnels
Windows axe son système vers l’amusement
Android dans ses premières versions était moins simple que
iOS mais plus complet et paramétrable
Il centre ses développements vers la géolocalisation et les
réseaux sociaux
Il offre comme iOS un «SDK» (Open Source) et un «store»
d’applications
L3 - Info Développement sur Android 5Une histoire très récente
Google
Slogan : «Don’t be evil»
Fondé le 27 septembre 1998 par Larry Page et Sergey Brin
Chiffre d’affaires en 2012 : 50, 2 milliards de $
Effectif (le 20 Juillet 2012) : 54604
Développe des produits connus et répandus :
Moteur de recherche, YouTube, Chrome, AdSense,
GoogleEarth, Android
Google a bâti sa renommée grâce à l’utilisation de produits
«Open Source»
En retour Google soutient l’Open Source en employant
certains de ses grands acteurs
C’est en appliquant cette idée qu’il développe Android, un
système d’exploitation libre pour smartphones
L3 - Info Développement sur Android 6Une histoire très récente
Android
Android est un système d’exploitation Open Source basé sur
un noyau Linux
Il fonctionne sur smartphones, tablettes, montres, lunettes, . . .
Initialement développé par une startup du même nom,
rachetée par Google en 2005
En 2008, le gPhone est lancé aux États-Unis dans un
parteneriat entre Google et T-mobile
La mascotte BugDroid est un personnage du jeu Gauntlet :
The Third Encounter sorti sur Atari dans les années 1990
L3 - Info Développement sur Android 7Une histoire très récente
Enjeux pour Google
Avènement de l’Open Handset Alliance
Google est dépendant d’acteurs tiers du marché
Sa politique actuelle est d’étendre aux smartphones ses
services existants (recherche, publicité, réseaux sociaux, . . . )
En 2007, Google initie la création de l’Open Handset Alliance
Composée en 2013 de 84 industriels
A pour objectif de développer des normes ouvertes pour les
appareils mobiles
Google devient acteur dans la partie matérielle avec le rachat
de Motorola Mobility
Diversification des appareils utilisant Android (téléviseurs,
appareils photos, montres, lunettes, . . . )
L3 - Info Développement sur Android 8Une histoire très récente
Stratégie et rentabilité d’Android
Revenus basés sur la vente d’applications et l’intégration de la
publicité
Android est rentable depuis octobre 2010 et génère plus de
revenus qu’iOS depuis novembre 2010
Stratégie de développement :
Basée sur l’Open Source
Un «store» de plusieurs milliers d’applications
Des mises à jours régulières et faciles d’installation
Un système ouvert pour facilité sa diffusion et son adaptation
sur différents matériels
L3 - Info Développement sur Android 9Le SDK d’Android et Éclipse
Qu’est-ce qu’un programme Android ?
Android offre un framework riche mais suffisamment rigide et
étanche :
Du XML pour les interfaces
Les activités : briques de base d’une application
Les services : conçus pour durer
Les fournisseurs de contenus : abstraction de données
Les intentions (intents) : interagir avec le système
Android permet d’accéder aux fonctionnalités avancées de
l’appareil :
Stockage (base de données, support externe)
Réseau (Wifi, Bluetooth, 3G, . . . )
Multimédia (lecture audio, photo, caméra)
GPS (géolocation des applications par différents moyens)
Services de téléphonie (appels, SMS)
L3 - Info Développement sur Android 11Le SDK d’Android et Éclipse
Le SDK d’Android
Langage Java
Sauf cas particuliers, une application Android est écrite en
Java
Le code Java est compilé pour pouvoir s’exécuter sur la
machine virtuelle Dalvik embarquée sur Android
L’application est empaquetée dans un fichier APK (Android
PacKage) puis installée sur l’appareil
Le JDK (Java Development Kit) est un prérequis à la
réalisation d’un programme Android
Il est conseillé d’installer le SDK Java de Sun/Oracle
L3 - Info Développement sur Android 12Le SDK d’Android et Éclipse
Le SDK d’Android
Installation
Les outils de développement d’Android :
http://developer.android.com/sdk/index.html
Installation « des » SDK et des greffons :
Dans le répertoire tools/, lancer l’Android SDK and AVD
Manager (exécuter le script android ou le programme
setup.exe)
Sélectionner puis installer les versions du SDK voulues ainsi que
les greffons tiers requis (API Google Maps)
L3 - Info Développement sur Android 13Le SDK d’Android et Éclipse
Le SDK d’Android
La jungle des matériels et des versions
Plusieurs versions d’Android coexistent
À chaque version du système est associé un niveau d’API
Une « cible » est la combinaison d’un niveau d’API et d’un
indicateur précisant si l’on inclut les API Google :
10 : Android 2.3.4 GINGERBREAD
13 : Android 3.2 HONEYCOMB
15 : Android 4.0.4 ICE CREAM SANDWICH
16/17/18 : Android 4.1.x 4.2.x 4.3 JELLY BEAN
19 : Android 4.4 KITKAT
L3 - Info Développement sur Android 14Le SDK d’Android et Éclipse
L’émulateur, un outil indispensable
L’émulateur Android permet de simuler plusieurs terminaux
Informations nécessaires à la configuration d’un AVD :
Une version cible du SDK
Des informations sur le stockage (mémoire, carte SD)
Résolution de l’appareil choisi
L3 - Info Développement sur Android 15Le SDK d’Android et Éclipse
Monitor, le couteau Suisse
Monitor permet de :
Parcourir les logs de l’émulateur
Modifier la position GPS
Simuler la réception de SMS ou d’appels
Prendre une capture d’écran de l’émulateur
Accéder au gestionnaire du SDK et des émulateurs
...
L3 - Info Développement sur Android 16Le SDK d’Android et Éclipse
Éclipse et Android
Éclipse est un IDE adapté pour le développement Java
Combiné au Plugin ADT il permet de créer et gérer des
applications Android
Création de projet
Gestion des émulateurs
Compilation, déboggage et exécution dans un émulateur
Éclipse n’est toutefois pas indispensable :
Apache Ant (version 1.8.1 ou supérieure) permet de compiler
un projet Android
Il faut ensuite utiliser android et adb pour exécuter des
actions spécifiques Android (création de projet, déploiement,
...)
L3 - Info Développement sur Android 17Ma première application Android
Création d’un projet
En ligne de commande
Un squelette complet pour un projet Android peut-être créé
par la commande suivante :
android create project --target "android-18" \
--path ProjetTest \
--activity Debut \
--package com.univangers.l3info.projettest
Liste des cibles disponibles : android list targets
Compilation, installation : ant clean debug install
Un fichier apk a été créé
Le programme est disponible sur l’émulateur dans le launcher
L3 - Info Développement sur Android 19Ma première application Android
Organisation d’un projet
En ligne de commande
Un projet Android est constitué d’une arborescence de
répertoires et de fichiers :
AndroidManifest.xml, build.xml, *.properties,
proguard-project.txt
bin/, libs/, res/, src/, assets/, gen/
Le répertoire src/ contient la hiérarchie des activités
La première compilation produira le fichier R.java contenant
l’activité principale
bin/nomapp-*.apk est la véritable application Android
nomapp-debug-aligned.apk correspond à l’application
optimisée et compilée en mode debug
L3 - Info Développement sur Android 20Ma première application Android
Organisation d’un projet
Le fichier AndroidManifest.xml
AndroidManifest.xml déclare les activités, services ainsi que
la façon dont il s’intègre au système
Le nom du paquet Java est la «base» de l’application et de
l’espace de nom
Il sert également d’identifiant unique
L3 - Info Développement sur Android 21Ma première application Android
Création d’un projet
Sous Éclipse/ADT
Le SDK Android met à disposition le plugin Éclipse ADT :
Assistants pour la création d’un projet
Boutons et raccourcis pour la compilation et l’exécution des
applications
Une ébauche de conception de l’interface à la souris
Création et gestion des émulateurs
Il est possible d’importer un projet Android ainsi que d’en
créer un de zéro
Intégration de monitor pour parcourir les fichiers journaux,
modifier la position GPS, simuler des appels ou SMS
Lors de l’exécution du projet, il faut avoir un fichier java dans
l’onglet actif. Si l’éditeur contient un fichier xml, l’exécution
provoquera une erreur
L3 - Info Développement sur Android 22Ma première application
Un bouton et clic la date se met à jour . . .
package com.univangers.l3info.projettest;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.util.Date;
public class Debut extends Activity implements View.OnClickListener {
Button btn;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
btn = new Button(this);
btn.setOnClickListener(this);
updateTime();
setContentView(btn);
}
public void onClick(View view) {
updateTime();
}
private void updateTime() {
btn.setText(new Date().toString());
}
}
L3 - Info Développement sur Android 24Description de l’interface graphique
Le choix des ressources en XML
Séparer la description de l’interface de son comportement
Les layouts XML sont stockés dans res/layout
aapt est appelé automatiquement à la compilation pour
intégrer les layouts
Chaque fichier XML décrit une View, il contient une
arborescence d’éléments dont les attributs peuvent :
Décrire l’aspect d’un widget
Décrire le comportement d’un conteneur
Les widgets sont accessibles depuis le code Java
Le nom du fichier XML est celui de la classe du widget de la vue
L3 - Info Développement sur Android 25Description de l’interface graphique
res/layout/main.xml
fill_parent a été renommé en match_parent depuis Android 2.2, version 8 de l’API
Code Java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.button);
btn.setOnClickListener(this);
updateTime();
}
Convention de format : @+id/nom_unique
Seule la première occurrence de l’id fait apparaitre le «+»
L3 - Info Développement sur Android 26Les «widgets»
Introduction
Les principaux widgets héritent de la classe View
Ils ont une taille minimale qui s’adapte en fonction de leur
contenu
Le padding permet de contrôler l’espacement avec les widgets
adjacents
Un widget peut changer d’état (actif/inactif) avec
setEnabled()
requestFocus() donne le focus à un widget particulier
getParent() retourne le widget ou le conteneur parent
findViewById() renvoie un widget d’après son identifiant
getRootView() renvoie la racine de l’arborescence (fournie à
l’activité via l’appel à setContentView())
L3 - Info Développement sur Android 28Les «widgets»
Les «labels» et les «boutons»
Le widget label est obtenu avec une instance de TextView
Un élément TextView possède de nombreux attributs :
android:text, android:typeface, . . .
Le widget Button (sous-classe de TextView) a déjà été vu
plus tôt
Depuis Android 1.6, un écouteur de clic peut être ajouté à la
ressource :
Une méthode publique de l’activité (prenant un argument
View et renvoyant void) doit être définie
L’attribut android:onClick du Button doit être renseigné
L3 - Info Développement sur Android 29Les «widgets»
Les «labels» et les «boutons»
exemple
...
public class Debut extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
updateTime();
}
public void clicReaction(View view) {
updateTime();
}
private void updateTime() {
Button btn;
btn = (Button)findViewById(R.id.button);
btn.setText(new Date().toString());
}
}
L3 - Info Développement sur Android 30Les «widgets»
Les images
Les widgets ImageView et ImageButton
permettent d’intégrer des images
ImageButton (sous-classe de ImageView)
ajoute les comportements d’un Button à
ImageView
L’attribut android:src précise la ressource
graphique à utiliser
L3 - Info Développement sur Android 31Les «widgets»
Les champs de saisie
Le widget EditText permet d’éditer et de
capturer du texte saisi par l’utilisateur
Il hérite de TextView mais possède des
propriétés supplémentaires :
android:autoText, android:inputType,
android:singleLine, . . .
L3 - Info Développement sur Android 32Les «widgets»
Les champs de saisie
exemple
package com.univangers.l3info.projettest;
import android.app.Activity;
import android.os.Bundle;
import android.widget.EditText;
public class Debut extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
EditText txt = (EditText)findViewById(R.id.champs);
txt.setText("Un exemple de saisie ...");
}
}
L3 - Info Développement sur Android 33Les «widgets»
Les cases à cocher
Le widget CheckBox correspond à la boite à
cocher
Il hérite de CompoundButton qui dérive
elle-même de TextView
Les méthodes isChecked(), setChecked et
toggle permette d’interagir avec le widget
depuis le code Java
Pour servir d’écouteur, l’activité doit
implémenter l’interface
OnCheckedChangeListener
L3 - Info Développement sur Android 34Les «widgets»
Les cases à cocher
exemple
...
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
public class Debut extends Activity implements CompoundButton.OnCheckedChangeListener {
CheckBox cb;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
cb = (CheckBox)findViewById(R.id.caseCoche);
cb.setOnCheckedChangeListener(this);
}
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) cb.setText("Case cochée");
else cb.setText("Case décochée");
}
}
L3 - Info Développement sur Android 35Les «widgets»
Les boutons radios
Le widget RadioButton implémente le
comportement du bouton radio
Comme CheckBox, il hérite de
CompoundButton et permet d’utiliser
isChecked(), toggle(), . . .
Les RadioButton sont groupés dans un
RadioGroup afin de les lier
En y affectant un id, le groupe devient
accessible depuis le code Java
L3 - Info Développement sur Android 36Les «widgets» Les boutons radios exemple L3 - Info Développement sur Android 37
Les «conteneurs»
Introduction
Le «layout manager»
Dans quasiment toutes les bibliothèques graphiques, un
«layout manager» place les widgets
Pour donner les indications de placement, des «conteneurs»
sont utilisés
La plupart du temps, ils permettent de ranger les widgets en
ligne ou dans une grille
Android fournit plusieurs conteneurs dont les principaux :
LinearLayout : pour le placement séquentiel
RelativeLayout : pour le placement relatif
TableLayout : pour le placement en grille
ScrollView : pour le placement dans une zone avec barres de
défilement
Comme les widgets, ils peuvent être implémentés dans des
ressources XML
L3 - Info Développement sur Android 39Les «conteneurs»
Le «LinearLayout»
Le «LinearLayout» permet de disposer les widgets les uns
derrières les autres dans une boite
Il faut pour cela indiquer l’orientation de la boite (verticale ou
horizontale)
ex : android:orientation="horizontal"
La disposition des widgets dépend de la place occupée par le
conteneur
Les propriétés android:layout_width (et layout_height)
modifient le comportement du widget :
wrap_content indique que le widget occupe la place minimale
nécessaire
match_parent indique que le widget occupe tout l’espace
disponible de son conteneur
Il est possible d’indiquer des marges grâce aux propriétés
android:layout_margin, . . .
L3 - Info Développement sur Android 40Les «conteneurs»
Le «LinearLayout»
Poids et alignement
Lorsque plusieurs widgets utilisent match_parent des poids
peuvent être renseignés dans android:layout_weight
Si les poids sont identiques, l’espace sera réparti équitablement
entre les widgets
Si le poids d’un widget est deux fois plus important qu’un
autre, il occupera deux fois plus de place à l’écran
L’alignement des widgets dans un LinearLayout est défini
par la propriété android:layout_gravity
setGravity() permet de modifier la propriété depuis le code
Java
Les gravités les plus courantes sont : left, right,
center_horizontal et center_vertical
L3 - Info Développement sur Android 41Les «conteneurs»
Le «LinearLayout»
Exemple
Il est possible de combiner les
LinearLayout
Il est possible d’utiliser des pourcentages au
lieu des poids si :
La propriété layout (layout_width ou
layout_height) de la dimension libre est à
0dip
La somme des pourcentages est égale à 100
L3 - Info Développement sur Android 42Les «conteneurs» L3 - Info Développement sur Android 43
Les «conteneurs» L3 - Info Développement sur Android 44
Les «conteneurs»
Les «conteneurs»
Le «RelativeLayout»
Le placement relatif des widgets
Le RelativeLayout permet :
De placer un widget relativement au conteneur
De placer un widget à gauche, en dessous, . . . d’un autre
D’aligner des widgets les uns par rapport aux autres
Placement relatif au conteneur :
android: (layout_alignParentTop, layout_alignParentBottom,
layout_alignParentLeft et layout_alignParentRight) permettent
d’aligner le haut (resp. bas, gauche et droite) du widget avec
celui du conteneur
android: (layout_centerHorizontal, layout_centerVertical et
layout_centerInParent) permettent de centrer horizontalement
(resp. verticalement et les deux) le widget dans le conteneur
L3 - Info Développement sur Android 46Les «conteneurs»
Le «RelativeLayout»
Le placement relatif des widgets
Placement relatif aux widgets :
android: (layout_above, layout_below, layout_toLeftOf et
layout_toRightOf) permettent de placer un widget au-dessus
(resp. en-dessous, à gauche ou à droite) d’un autre widget
android: (layout_alignTop, layout_alignBottom, layout_alignLeft
et layout_alignRight) permettent d’aligner le haut (resp. bas,
gauche et droite) du widget avec un autre (indiqué)
Il est aussi possible de recouvrir un widget par un autre en
utilisant habilement ces propriétés
L3 - Info Développement sur Android 47Les «conteneurs»
Le «RelativeLayout»
Faire référence à d’autres widgets
Lors du placement relatif, il faut faire référence à d’autres
widgets dans la ressource XML
Comme nous l’avons vu, les widgets peuvent avoir des id (les
rendants accessibles depuis le code Java)
Leur syntaxe est la suivante : android:id="@+id/nomUnique"
Le symbole "+" est ajouté uniquement la première fois où l’id
est utilisé
L3 - Info Développement sur Android 48Les «conteneurs» Le «RelativeLayout» Exemple 1 L3 - Info Développement sur Android 49
Les «conteneurs»
Le «RelativeLayout»
Exemple 1, ressource XML
L3 - Info Développement sur Android 50Les «conteneurs» Le «RelativeLayout» Exemple 2 L3 - Info Développement sur Android 51
Les «conteneurs» Le «RelativeLayout» Exemple 2, ressource XML L3 - Info Développement sur Android 52
Les «conteneurs»
Le «TableLayout»
Le placement dans une grille
Le TableLayout permet de placer les widgets dans les cellules
d’un tableau
Il est forcément associé au conteneur TableRow symbolisant
les lignes du tableau
Le nombre de colonnes est calculé en fonction de la ligne qui
contient le plus de widgets
La propriété android:layout_span permet de fusionner des
cellules horizontalement
La propriété android:layout_column force le widget à être
dans la cellule indiquée
L3 - Info Développement sur Android 53Les «conteneurs»
Le «TableLayout»
Influencer le comportement des colonnes
Habituellement TableLayout ne contient que des TableRow
Il est possible de glisser des widgets entre les lignes
−→ déconseillé
La propriété android:stretchColumns permet d’étirer la ou
les colonnes indiquées dans l’espace libre
La propriété android:shrinkColumns permet de réduire la
taille des colonnes indiquées en découpant les widgets sur
plusieurs lignes
La propriété android:collapseColumns contient la liste des
colonnes refermées initialement
L3 - Info Développement sur Android 54Les «conteneurs» Le «TableLayout» Exemple L3 - Info Développement sur Android 55
Les «conteneurs»
Le «ScrollView»
Le défilement des widgets
Scroller sur une activité est indispensable sur petit écran
ScrollView est conteneur permettant à un contenu de défiler
Il permet d’encapsuler un autre conteneur ne pouvant être
affiché intégralement
Des bars de défilement apparaissent
Depuis Android 1.5, le conteneur HorizontalScrollView
permet de faire défiler horizontalement les widgets contenus
L3 - Info Développement sur Android 56Les «conteneurs» Le «ScrollView» Exemple L3 - Info Développement sur Android 57
Poser une question à l’utilisateur Le framework des méthodes de saisie
Claviers physiques et logiciels
Depuis Android 1.5 le framework IMF 1 a été introduit
IMF permet, par exemple, d’abstraire la notion de clavier :
Si il n’y a pas de clavier physique un IME 2 apparaît
Il permet aussi de contrôler l’IME (contrôle du recouvrement,
nature des données. . . )
La propriété android:inputType indique la nature des
données attendues lors d’une saisie :
text, number, phone, datetime, date, time
Il est aussi possible de contrôler la touche accessoire en bas à
droite du clavier
La propriété android:imeOptions contrôle la touche
accessoire (ex : actionSend, actionDone)
1. Input Method Framework
2. Input Method Editor
L3 - Info Développement sur Android 60Poser une question à l’utilisateur Le framework des méthodes de saisie Contôle du mode de saisie L3 - Info Développement sur Android 61
Poser une question à l’utilisateur Le framework des méthodes de saisie
Aller plus loin avec IMF
Il possible de modifier le mode d’apparition du clavier en
fonction des circonstances :
L’activité entière peut glisser vers le haut
La taille de l’activité peut-être modifiée
L’activité entière peut-être masquée (en mode paysage par
exemple)
Android choisit par défaut le mode le plus adapté à l’activité,
mais il peut-être fixé dans le manifest par la propriété
android:windowSoftInputMode
Il est aussi possible de masquer le clavier depuis le code Java :
InputMethodManager mgr=(InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(fld.getWindowToken(), 0);
ou
mgr.hideSoftInputFromWindow(fld.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
L3 - Info Développement sur Android 62Poser une question à l’utilisateur Widgets de sélection
Introduction
La saisie d’informations sur un smartphone est toujours
problématique
Les erreurs de frappes peuvent se multiplier . . .
Contrôler l’IME est une première étape pour limiter les erreurs
La solution la plus adéquate reste de limiter le nombre de
réponses possibles
Les listes de choix sont donc des widgets indispensables
Android permet de lier directement un widget liste à un type
abstrait de données adapté
Ce sont les adapteurs
L3 - Info Développement sur Android 64Poser une question à l’utilisateur Widgets de sélection
L’adapteur «ArrayAdapter»
ArrayAdapter permet de lier un tableau à un widget adapté
String[] items = { "rouge", "vert", "bleu", "jaune" };
new ArrayAdapter(this, android.R.layout.simple_list_item1, items);
ArrayAdapter prend trois paramètres :
Un contexte, généralement l’activité
L’identifiant de ressource de la vue à utiliser
La liste des éléments
Par défaut, ArrayAdapter appelle la méthode toString() des
objets de la liste
Il instanciera ensuite la vue avec le résultat
Le second paramètre de ArrayAdapter renseigne la vue
La valeur android.R.layout.simple_list_item_1
correspond à une vue prédéfinie simple
L3 - Info Développement sur Android 65Poser une question à l’utilisateur Widgets de sélection
La «ListActivity»
Utilisation de «ArrayAdapter»
Le widget d’Android pour les listes est le ListView
Toutefois, utiliser une ListActivity est préconisé quand
l’activité se réduit à une liste
La propriété android:choiceMode="multipleChoice" permet
d’obtenir une liste à choix multiples
L3 - Info Développement sur Android 66Poser une question à l’utilisateur Widgets de sélection
La «ListActivity»
Utilisation de «ArrayAdapter»
package com.univangers.l3info.projettest;
import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class Debut extends ListActivity {
private TextView selection;
private static final String[] items = { "rouge", "bleu", "vert", "jaune", "rose" };
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setListAdapter(new ArrayAdapter(this,
android.R.layout.simple_list_item_1,
items));
selection=(TextView)findViewById(R.id.selection);
}
public void onListItemClick(ListView parent, View v, int pos, long id) {
selection.setText(items[pos]);
}
}
L3 - Info Développement sur Android 67Poser une question à l’utilisateur Widgets de sélection
Les listes déroulantes
Les listes déroulantes sont implémentées avec le widget
Spinner
La méthode setAdapteur() renseigne l’adaptateur à utiliser
La méthode setOnItemSelectedListener() fournit l’écouteur
en cas de clic
L3 - Info Développement sur Android 68Poser une question à l’utilisateur Widgets de sélection
public class Debut extends Activity
implements AdapterView.OnItemSelectedListener {
private TextView selection;
private static final String[] items = { "rouge", "bleu", "vert", "jaune", "rose" };
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
selection=(TextView)findViewById(R.id.selection);
Spinner spin = (Spinner)findViewById(R.id.boitederoulante);
spin.setOnItemSelectedListener(this);
ArrayAdapter aa = new ArrayAdapter(this,
android.R.layout.simple_spinner_item,
items);
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spin.setAdapter(aa);
}
public void onItemSelected(AdapterView parent, View v, int pos, long id) {
selection.setText(items[pos]);
}
public void onNothingSelected(AdapterView parent) {
selection.setText("");
}
}
L3 - Info Développement sur Android 69Poser une question à l’utilisateur Widgets de sélection
L’autocomplétion
Économie de temps et gain de fiabilité !
Le widget AutoCompleteTextView est
un mélange de EditText et de Spinner
Il hérite de EditText
Le texte saisi est utilisé pour présenter
les choix possibles restants
Un TextWatcher permet de réaliser
des actions quand le texte change
L3 - Info Développement sur Android 70Poser une question à l’utilisateur Widgets de sélection
L’autocomplétion
public class Debut extends Activity
implements TextWatcher {
private TextView selection;
private AutoCompleteTextView editAuto;
private static final String[] items = { "rouge", "bleu", "vert", "jaune", "rose" };
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
selection=(TextView)findViewById(R.id.selection);
editAuto = (AutoCompleteTextView)findViewById(R.id.editAuto);
editAuto.addTextChangedListener(this);
editAuto.setAdapter(new ArrayAdapter(this,
android.R.layout.simple_dropdown_item_1line,
items));
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
selection.setText(editAuto.getText());
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
public void afterTextChanged(Editable s) { }
}
L3 - Info Développement sur Android 71Pour aller plus loin . . . Autres widgets et conteneurs
Encore plus de widgets
En plus des widgets déjà vus, Android fournit un grand
nombre de widgets et conteneurs :
saisie des dates, des temps, sélecteurs de fichiers,
positionnement absolu . . .
Les listes, vues avant peuvent avoir un rendu complètement
personnalisé
il est aussi possible d’utiliser des onglets grâce au conteneur
TabHost et l’activité TabActivity
Toutefois, la philosophie d’Android est de limiter au
maximum leur utilisation
Il est aussi possible d’utiliser des bases de données SQL, de
faire apparaître des pop-ups et même d’intégrer un navigateur
web.
L3 - Info Développement sur Android 74Pour aller plus loin . . . Autres widgets et conteneurs
Les tiroirs : «SlidingDrawer»
Le SlidingDrawer peut passer d’ouvert à fermé
Comme il se superpose à l’affichage, il ne peut se trouver que
dans un RelativeLayout ou un FrameLayout
Un FrameLayout est dédié à la supperposition de widgets
Il est possible depuis le code Java, de l’ouvrir, le fermer, le
bloquer, . . .
L3 - Info Développement sur Android 75Pour aller plus loin . . . Autres widgets et conteneurs
Les tiroirs
Exemple
La ressource affichée dans le ImageView doit être fournie
L3 - Info Développement sur Android 76Pour aller plus loin . . . Autres widgets et conteneurs
Intégrer le navigateur «webkit»
Le widget WebView permet d’intégrer
un navigateur web dans l’activité
Il faut modifier les permissions de
sécurité en conséquence
Il dispose d’un grand nombre de
fonctionnalités (JavaScript,
navigation arrière/avant, . . . )
Il possible de charger des URLs mais
également du code HTML par l’appel à
loadData()
L3 - Info Développement sur Android 77Pour aller plus loin . . . Autres widgets et conteneurs
Intégrer le navigateur «webkit»
Exemple
AndroidManifest.xml
package com.univangers.l3info.projettest;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
public class Debut extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
WebView ww=(WebView)findViewById(R.id.navigateur);
ww.loadUrl("http://www.google.fr");
}
}
L3 - Info Développement sur Android 78Pour aller plus loin . . . Menus et «pop-ups»
Les menus
Comme dans tout type d’application, il est possible d’ajouter
des menus
Il peuvent s’ouvrir soit :
Lors de l’appui sur la touche menu (menu d’options)
Lors d’un appui long sur un widget (menu contextuel)
Ils peuvent apparaître en mode icône . . .
Seuls quelques éléments sont visibles, le texte Plus peut
apparaitre
. . . ou en mode étendu
Il se constituent/remplissent depuis le code Java
L3 - Info Développement sur Android 80Pour aller plus loin . . . Menus et «pop-ups»
Les menus
Les menus d’options
La méthode onCreateOptionsMenu() de l’activité concernée
doit être redéfinie
Les items du menu sont rajoutés par l’appel à méthode add()
du menu
Il prend en compte les paramètres suivants :
Un identifiant de groupe (NONE normalement)
Possibilité de créer des items exclusifs (radio)
Un identifiant de choix pour identifier le choix lors du rappel
La méthode onOptionsItemSelected() effectue le rappel
Un identifiant d’ordre (NONE le plus souvent)
Le libellé de l’item
Il est possible de rendre des options «checkable» par l’appel à
MenuItem#SetCheckable
Il est possible de créer des sous-menus en appelant
addSubMenu()
L3 - Info Développement sur Android 81Pour aller plus loin . . . Menus et «pop-ups»
Les menus
Les menus contextuels
Les menus contextuels fonctionnent comme les menus
d’options
La méthode registerForContextMenu() associe un widget à
un menu contextuel
La méthode onCreateContextMenu() doit être redéfinie pour
construire le menu
onCreateContextMenu() est appelé à chaque affichage du
menu contextuel
getMenuInfo() est utilisé pour obtenir le widget qui a
déclenché le menu
L3 - Info Développement sur Android 82Pour aller plus loin . . . Menus et «pop-ups»
Les menus
Exemple
public class Debut extends ListActivity {
public static final int MENU_ADD = Menu.FIRST+1;
public static final int MENU_RESET = Menu.FIRST+2;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
/* Initialisation de la liste d’éléments */
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(Menu.NONE, MENU_ADD, Menu.NONE, "Ajouter")
.setIcon(R.drawable.ic_menu_add);
menu.add(Menu.NONE, MENU_RESET, Menu.NONE, "Réinitialiser")
.setIcon(R.drawable.ic_menu_refresh);
return(super.onCreateOptionsMenu(menu));
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_ADD:
return(true);
case MENU_RESET:
initAdapter();
return(true);
}
return(super.onOptionsItemSelected(item));
}
L3 - Info Développement sur Android 83Pour aller plus loin . . . Menus et «pop-ups»
Les menus
Exemple
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
/* Initialisation de la liste d’éléments */
registerForContextMenu(getListView());
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
menu.add(Menu.NONE, MENU_CAP, Menu.NONE, "Capitaliser");
menu.add(Menu.NONE, MENU_REMOVE, Menu.NONE, "Supprimer");
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info=
(AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
ArrayAdapter aa=
(ArrayAdapter)getListAdapter();
switch (item.getItemId()) {
case MENU_CAP:
String item=items.get(info.position);
...
return(true);
case MENU_REMOVE:
aa.remove(items.get(info.position));
return(true);
}
return(super.onContextItemSelected(item));
L3 - Info Développement sur Android 84Pour aller plus loin . . . Menus et «pop-ups»
Les «pop-ups»
Les «toasts» et les «alertes» !
Pour informer l’utilisateur, il est nécessaire de lui afficher des
messages
Le «toast» est un message qui ne reste affiché que pendant un
certain laps de temps
Il ne modifie pas le focus de l’activité
Pas moyen de savoir si l’utilisateur l’a lu
Un toast est émis en appelant la méthode statique
makeText() de la classe Toast
Les «alertes» sont déclenchées en instanciant une boîte de
dialogue modale affichée à l’écran
Elle prend le focus
L’utilisateur doit valider (donner une réponse) pour la fermer
Une alerte est créée par instanciation de la classe AlertDialog
L3 - Info Développement sur Android 85Pour aller plus loin . . . Menus et «pop-ups»
Les «pop-ups»
Exemple
public class Debut extends Activity {
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
Toast.makeText(Debut.this, "Ça va démarrer !",
Toast.LENGTH_SHORT).show();
new AlertDialog.Builder(this)
.setTitle("Une boite !")
.setMessage("Bla bla bla.")
.setCancelable(false)
.setPositiveButton("Quitter",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
Debut.this.finish();
}
})
.setNegativeButton("Rester",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
dialog.cancel();
}
}).show();
}
}
L3 - Info Développement sur Android 86Le système reste le seul maître à bord ! Ça s’en va et ça revient . . .
Une gestion spécifique à un matériel aux ressources limités
Sur un PC l’OS 3 peut tuer des processus
Toutefois, on considère qu’une tâche ne peut se terminer de
manière inopinée
Sur un smartphone, les ressources et notamment la mémoire
sont plus limitées
Des activités peuvent être tuées pour permettre à d’autres de
s’exécuter
Certaines doivent mourir pour que d’autres vivent
Sur Android il ne faut pas supposer que l’application ira
jusqu’à son terme !
3. Operating System
L3 - Info Développement sur Android 90Le système reste le seul maître à bord ! Ça s’en va et ça revient . . .
États d’une activité
Une activité est toujours dans l’un des quatre états suivants :
Active : elle s’execute au premier plan
En pause : l’activité est visible mais inacessible (une
notification ou un message apparaît devant)
Stoppée : elle est cachée par une autre activité
Morte : elle n’a pas été lancée ou a été tuée
Android fournit des méthodes appelées lors de la transition
d’un état à un autre
Elles sont implémentées dans la classe Activity et sont à
redéfinir dans les sous-classes
Certaines transitions font appel successivement à plusieurs de
ces méthodes, la documentation doit être lue attentivement !
L3 - Info Développement sur Android 91Le système reste le seul maître à bord ! Ça s’en va et ça revient . . .
États d’une activité
Cycle de vie
Pour chaque méthode de transition
redéfinie, il faut rappeler la méthode
de la superclasse !
OnCreate()
Appelée :
Lors du lancement de l’activité
(avec NULL comme paramètre)
Lors du redémarrage de
l’activité (après un «kill»), avec
un «Bundle» comme argument
Également après une rotation
L3 - Info Développement sur Android 92Le système reste le seul maître à bord ! Ça s’en va et ça revient . . .
États d’une activité
Cycle de vie
OnDestroy()
Libérations des ressources :
Lors de l’appel à finish()
Lorsque qu’elle est tuée
OnStart(),OnRestart() et OnStop()
onStart() est appelé lors du
passage au premier plan
onRestart() est appelé
uniquement lorsque l’activité a
été stoppée et redémarre
onStop() est appelé lorsque
l’activité va être stoppée
L3 - Info Développement sur Android 93Le système reste le seul maître à bord ! Ça s’en va et ça revient . . .
États d’une activité
Cycle de vie
OnResume()
Est appelé juste avant que
l’activité passe au premier plan
Lors de son lancement
Lors de son retour après avoir
été rendue inaccessible
Après la fermeture d’une
notification ouverte par le
système
C’est le bon endroit pour
reconstruire l’interface !
L3 - Info Développement sur Android 94Le système reste le seul maître à bord ! Ça s’en va et ça revient . . .
États d’une activité
Cycle de vie
OnPause()
Est appelé juste avant que
l’activité quitte le premier plan
Elle permet de libérer les
ressources exclusives (threads,
appareil photo) et ce qui a été
fait dans OnResume()
Lorsqu’une activité est en
pause, Android peut la tuer à
tout moment
L3 - Info Développement sur Android 95Le système reste le seul maître à bord ! Ça s’en va et ça revient . . .
États d’une activité
Sauvegarde de l’état d’une instance
Pour rendre transparente toute cette gestion, Android permet
de sauvegarder et restaurer l’état d’une instance
La méthode onSaveInstanceState() fournit un Bundle dans
lequel une activité peut sauver des données
onRestoreInstanceState() et onCreate() permettent de
récupérer le Bundle réalisé
onSaveInstanceState() est appelé régulièrement par
Android :
Il faut donc que son exécution soit rapide et efficace
onSaveInstanceState() possède une version prédéfinie basée
sur les ID des widgets
Il est possible de la personnalisée complètement
L3 - Info Développement sur Android 96Le système reste le seul maître à bord ! La rotation des écrans
Fonctionnement de la rotation
La majorité des smartphones peuvent passer du mode portrait
au mode paysage
Lors de l’ouverture d’un clavier physique
Lors de la détection d’un mouvement défini (grâce à des
accéléromètres)
Lors d’un changement d’orientation, Android supprime et
recrée toutes les activités
Il est possible d’adapter les activités pour bien réagir face à la
rotation
L3 - Info Développement sur Android 98Le système reste le seul maître à bord ! La rotation des écrans
Mise en œuvre de la rotation
Par défaut, il n’y a rien à faire,
l’activité gère elle même la rotation
L’émulateur peut effectuer une
rotation en pressant la combinaison
«Ctrl+F11»
Un layout différent pour le mode
paysage peut être défini en utilisant :
res/layout/ et
res/layout-land/
Il est possible de bloquer la rotation
d’une activité en modifiant le
manifest :
L3 - Info Développement sur Android 99Le système reste le seul maître à bord ! La rotation des écrans
Contrôler la rotation
Lors d’une rotation, l’activité est détruite puis recrée
La méthode onSaveInstanceState() est appelée avant le
retournement
L’objet Bundle permet de stocker des paramètres
supplémentaires
Les valeurs sont restorées depuis onRestoreInstanceState()
ou onCreate()
L3 - Info Développement sur Android 100Le système reste le seul maître à bord ! La rotation des écrans Contrôler la rotation Exemple L3 - Info Développement sur Android 101
Le système reste le seul maître à bord ! La rotation des écrans
Contrôler la rotation
Exemple : code Java
public class Debut extends Activity {
String strNom="";
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.main);
if (state != null)
strNom = state.getString("savedStrNom");
}
public void sauveTxt(View v) {
TextView tv=(TextView)findViewById(R.id.txtNom);
strNom=tv.getText().toString();
}
public void montreTxt(View v) {
Toast.makeText(Debut.this, strNom,
Toast.LENGTH_SHORT).show();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("savedStrNom", strNom);
}
}
L3 - Info Développement sur Android 102Le système reste le seul maître à bord ! La rotation des écrans
Gérer totalement la rotation
Une mauvaise idée . . .
Il est possible de gérer totalement la rotation en :
Utilisant l’attribut android:configChanges de l’activité dans
le manifest
Redéfinissant la méthode onConfigurationChanged() de la
classe de l’activité
C’est déconseillé par Google :
Risque d’oublier des ressources (chaîne, disposition, . . . )
L’approche gérée par Android peut ne pas être appropriée
dans certains cas :
Fluidité lors d’un jeu en réseau
Lecture vidéo d’un flux ⇒ perte du tampon
L3 - Info Développement sur Android 103Utiliser d’autres activités
Introduction
La philosophie d’Android demande au développeur de
découper son application en activités autonomes
Il est alors possible de lancer une activité (ou sous-activité)
depuis une autre activité :
Soit en connaissant le nom de l’activité à lancer
Soit par le biais d’une URI résolue par Android
Le cas le plus courant est l’ouverture d’un fichier attaché par
une autre activité
Question ?
L’activité initiale doit-elle être informée de la fin de l’activité fille ?
Si oui, l’activité fille est lancée comme sous-activité
Si non, l’activité est lancée comme «pair» de l’activité initiale
L3 - Info Développement sur Android 105Utiliser d’autres activités
Les intentions «intents» d’Android
Les intents sont des messages qui permettent à des
composants de demander une fonctionnalité spécifique
Ils peuvent aussi être utilisés pour informer le système d’un
nouvel évènement
Les intents sont envoyés à Android qui se chargera de trouver
un récepteur adéquat
Les intents peuvent être de deux catégories :
Explicites : le composant à lancer est donné explicitement
Implicites : le composant à lancer n’est pas connu, une URI
peut être construite permettant à Android de chercher parmi
les composants enregistrés, le plus adéquat
Il est possible de créer des récepteurs d’intention en modifiant
le fichier manifest de son activité
L3 - Info Développement sur Android 106Utiliser d’autres activités
Les intentions «intents» d’Android
Exemple avec startActivity
startActivity() lance une intention depuis une URI ou une
classe connue
L3 - Info Développement sur Android 107Utiliser d’autres activités Les intentions «intents» d’Android Exemple avec startActivity : ressource XML L3 - Info Développement sur Android 108
Utiliser d’autres activités
Les intentions «intents» d’Android
Exemple avec startActivity : le code Java
public class Debut extends Activity {
private EditText txtUrl;
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.main);
txtUrl=(EditText)findViewById(R.id.url);
// Pour connecter le bouton Go
txtUrl.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View view, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
goUrl(view);
return true;
} else {
return false;
}
}
});
}
public void goUrl(View v) {
Toast.makeText(Debut.this, txtUrl.getText().toString(),
Toast.LENGTH_SHORT).show();
Uri uri=Uri.parse(txtUrl.getText().toString());
startActivity(new Intent(Intent.ACTION_VIEW, uri));
}
};
L3 - Info Développement sur Android 109Utiliser d’autres activités
Le plus important reste à faire : la pratique !
L3 - Info Développement sur Android 110Vous pouvez aussi lire