Android - Ivan Madjarov

APPLICATIONS
JAVA
Android
Partie III
Ivan MADJAROV - 2014
Applications Java sous Android
IvMad, 2011-2014
3. Architecture d'une
application Android
L'objectif principal de ce cours est de découvrir la programmation sous
Android, sa plate-forme de développement et les spécificités du développement
embarqué sur téléphone mobile. Le cours s’inspire, reprend, modifie et enrichi
des supports disponibles sur Internet.
2
Applications Java sous Android
IvMad, 2011-2014
3
Composantes Android (1)
• Les éléments essentiels du Framework Android :
• Activity : C'est la composante principale d'une application Android.
Elle représente la couche représentative et visuelle de l'application
qui peut avoir plusieurs couches qui alternent entre elles lors de
l'exécution.
• Fragment : C'est une portion d'interface plus souple et dynamique.
Donc, une activité peut être constituée de plusieurs fragments.
• Views : Le IHM (GUI) est un "layout" ou une "widgets" couche qui
hérite des classes "android.view.View" et "android.view.ViewGroups".
• Service : A la différence d'une Activity un Service ne possède pas
d'interface mais permet l'exécution d'un traitement en tâche de
fond. Donc il n'a pas de vue, mais permet l’exécution d’un
algorithme sur un temps indéfini et terminé en fonction de la tâche.
Applications Java sous Android
IvMad, 2011-2014
4
Composantes Android (2)
• Content Provider : Il permet le partage des données entre
applications, via un fournisseur de contenu (photos, contacts, ...).
• Intents : Les composantes Android (Activity, Service, Broadcast receiver)
communiquent via des messages système que l'on appelle Intent
(intention). Une application peut appeler un service ou une activité
(explicite) ou appeler un service du système Android (implicites).
• Broadcast Receiver : C'est le récepteur d'événements qui réagit à un
événement système et les "Intents" implicites. Il ne possède pas
d'interface utilisateurs et est destiné à l'exécution de tâches légères.
Pour des tâches plus lourdes on lance un service. Un broadcast receiver
peut afficher un message, lancer une activité ou un service.
• Intent-Filter : un filtre d'intention sert à indiquer à une activité, service
ou broadcast receiver quels Intents peuvent implicitement traiter.
Applications Java sous Android
IvMad, 2011-2014
5
Cycle de vie d’une application Android
public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.acceuil); }
// suspendue détruit: onDestroy invoqué
protected void onDestroy() {
super.onDestroy(); }
// actif suspendue: ne détient plus le focus
protected void onPause() {
super.onPause(); }
// suspendue actif: onResume invoqué
protected void onResume() {
super.onResume(); }
// démarrage actif: détient le focus et est démarré
protected void onStart() {
super.onStart(); }
protected void onStop() {
super.onStop(); } }
Applications Java sous Android
IvMad, 2011-2014
6
Architecture d'une application Android
• onCreate : La méthode est appelée à la création d'une activité pour
•
•
•
•
•
initialiser les données nécessaires à l'exécution de l'application. A
l'appel de la méthode un Bundle est passé en argument. Il contient l’état
de sauvegarde enregistré lors de la dernière exécution.
onStart : La méthode est appelée dans le cas où l'application est en
arrière-plan et qu’elle repasse en avant-plan. Si l'activité ne peut pas
passer en avant plan alors, l’activité sera transférée à OnStop.
onResume : La méthode est appelée après OnStart quand l'application
passe en background à cause d’une autre application.
onPause : La méthode met en pause l'application et se relance avec la
méthodes OnResume.
onStop : Appelée quand l'activité n’est plus visible.
onDestroy : Appelée quand l'application est fermée (processus closed).
Applications Java sous Android
IvMad, 2011-2014
7
Contexte d'une application Android
• Le contexte relève l'état courant d'une application et les informations
sur son environnement et sert à récupérer des objets transmis par
d'autres parties de l'application.
• On dispose de quatre méthodes:
• getApplicationContext() : récupère le contexte de l'application en cours;
• getContext() : récupère le contexte de la vue courante;
• getBaseContext() : récupère le
contexte défini par la
méthode setBaseContext()
• this : peut être utilisé quant
on hérite directement de la
classe Context.
Applications Java sous Android
IvMad, 2011-2014
8
Programmer sous Android
• Interface graphique par programmation (partie dynamique)
• Pour faciliter le développement, Android propose un grand nombre de
"widgets": des éléments d’interface graphique qu'on peut utiliser dans une
application de manière directe et simple.
• On peut utiliser les classiques :
• boutons, listes déroulantes, cases à cocher
• mais aussi de composants plus poussés :
• des horloges, des sélecteurs de dates, des galeries photos et des afficheurs de
vidéos.
• Interface graphique par fichier XML (partie statique)
• Le fichier XML sera lu par le programme et l’interface graphique sera
automatiquement générée en conséquence. Il devient ainsi beaucoup plus
facile de modifier et de faire évoluer une interface graphique déjà
existante, et pouvoir l'adaptée suivant le contexte.
Applications Java sous Android
IvMad, 2011-2014
9
Le principe de l'interface graphique
Applications Java sous Android
IvMad, 2011-2014
10
Le principe de l'interface graphique
• Le GUI sous Android est basée sur les View, les Layout et les Widget.
• Un layout (gabarit) est une View (vue) spéciale qui peut contenir d'autres
•
•
•
•
View, ainsi le layout joue le rôle d'un conteneur.
Le Layout n'est pas destinée à fournir du contenu ou des contrôles à
l'utilisateur.
Les layouts se contentent de
disposer les Views par un
gestionnaire de placement.
Les Views se chargent de mettre
le contenu utilisateur en place.
Une View qui ne peut pas en
englober d'autres est appelée
un widget (composant).
Applications Java sous Android
IvMad, 2011-2014
11
Composants graphiques (Java)
• La class View est une zone de composant et source d'événement ce
qui forme la base du GUI.
Applications Java sous Android
IvMad, 2011-2014
12
Vues et schémas (Java)
• Les éléments graphiques héritent de la classe View. On peut regrouper
des éléments graphiques dans une ViewGroup.
• ViewGroup : le regroupement est prédéfini sous la forme de schémas
(layout) qui proposent une prédispositions des objets graphiques:
• LinearLayout : dispose les éléments de gauche à droite et du haut vers le
bas;
• RelativeLayout : les éléments enfants les uns par rapport aux autres;
• TableLayout : disposition en imitant un tableau par lignes et colonnes;
• FrameLayout : disposition en haut à gauche en empilant les éléments.
• La classe ViewGroup ressemble à un gestionnaire de placement connu
en Swing de Java2SE.
• Les déclarations peuvent se faire aussi en XML, ce qui évite de passer
par les instanciations Java (on verra ça par la suite).
Applications Java sous Android
IvMad, 2011-2014
13
Programmer: Bonjour tout le monde
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class Bonjour extends Activity {
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
TextView tv = new TextView(this);
tv.setText("Bonjour tout le monde !");
setContentView(tv);
}
}
Fait passer une instance de l'activité Simulateur d'unité mobile sous Android
• La méthode setText de la classe TextView met un String dans GUI.
• La méthode setContentView affiche la chaine de caractère dans l'interface graphique. Applications Java sous Android
IvMad, 2011-2014
Label de texte et zone de texte (Java)
Définir le conteneur
et l'ordre de
placement des
composants
14
Applications Java sous Android
IvMad, 2011-2014
15
Avec une image (Java)
ImageView() est la boite qui
peut contenir une image.
Les images utiles au projet sont
placées dans le dossier
"res/drawable"
Applications Java sous Android
IvMad, 2011-2014
TextView, EditText, ImageView, Bouton
16
Applications Java sous Android
IvMad, 2011-2014
17
Récupérer la saisie d'un texte (Java)
public void onClick(View view) {
// au click changer le texte sur la bouton
btn.setText("Bouton cliqué");
// récupérer le texte tapé dans le champ
String monTxt = edit.getText().toString();
// définir un affichage de texte
TextView txt = new TextView(this);
// mettre le texte du champ
txt.setText(monTxt);
// ajouter un texte au Layout
layout.addView(txt);
}
Applications Java sous Android
IvMad, 2011-2014
Android - un bouton
package ivmad.tp.nowdatetime;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.Button;
import java.util.Date;
public class MainActivity extends Activity implements View.OnClickListener {
Button btn;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
btn = new Button(this);
btn.setOnClickListener(this);
updateTime();
setContentView(btn);
}
public void onClick(View v) {
updateTime();
}
private void updateTime() {
btn.setText(new Date().toString());
}
}
18
Applications Java sous Android
IvMad, 2011-2014
19
Déroulement de l'exemple (1)
• La déclaration de paquetage doit être identique à celle utilisée pour
créer le projet.
• Pour un projet Java il faut importer les classes auxquelles l'application
fait référence.
• La plupart des classes spécifiques à Android se trouvent dans le paquetage
android
• Les classes de Java SE sont utilisables par les programmes Android, mail il
faut consulter le guide de référence des classes Android pour connaitre leur
disponibilité et compatibilité.
• Les activités sont des classes publiques héritées de la classe de base
android.app.Activity.
• Les widgets sont des éléments d’interface graphique qu'on peut utiliser
dans une application.
Applications Java sous Android
IvMad, 2011-2014
20
Déroulement de l'exemple (2)
• L’activité contient un bouton : Button btn;
• Un bouton est un widget Android et peut être utilisé dans une application.
• Pour capturer tous les clics de bouton dans l'activité elle-même on
implémente OnClickListener (écouteur d'événement).
• La méthode onCreate() est appelée au lancement de l’activité, alors
on établi un chaînage vers la superclasse afin d’initialiser l’activité
Android de base (super.onCreate(<Bundle object>)).
• L’instance de bouton créée (new Button(this)), on demande l’envoie
de tous les clics sur ce bouton à l’instance de l’activité
(setOnClickListener()) qui appelle la méthode onClick(View v).
• Un appel la méthode privée updateTime() est constitué, et pour finir
on configure la vue du contenu de l’activité avec le bouton lui-même
(setContentView()).
Applications Java sous Android
IvMad, 2011-2014
21
Déroulement de l'exemple (3)
• Tous les widgets dérivent de la classe de base View.
est un gestionnaire opaque, que toutes les activités
reçoivent lors de leur création.
Avec Swing, un clic sur un JButton déclenche un ActionEvent qui est
transmis à l’ActionListener configuré pour ce bouton (Java2SE).
Avec Android un clic sur un bouton fait appel de la méthode
onClick() sur l’instance OnClickListener configurée pour ça.
L’écouteur reçoit la vue qui a déclenché le clic et on fait alors appel à
la méthode privée updateTime().
L’ouverture de l’activité (onCreate()) ou un clic sur le bouton (onClick())
doit provoquer la mise à jour du label du bouton avec la date courante.
On utilise pour cela la méthode setText(), qui fonctionne exactement
comme avec les JButton de Swing.
• Bundle icicle
•
•
•
•
Applications Java sous Android
IvMad, 2011-2014
22
Toast : popup surgissant
• Afficher un contenu dans un popup surgissant
• La classe Toast avec la méthode makeText affiche une fenêtre popup pour un délai
'court' ou 'long'. La méthode prend trois paramètres:
Context context = getApplicationContext(); // référence vers l'application
String text = "Bonjour toast!";
// le texte à afficher
int duration = Toast.LENGTH_SHORT;
// La durée d'exposition
Toast toast = Toast.makeText(context, text, duration);
toast.show();
// Appel
// Visualiser
• Appel direct du Toast pour une durée 'courte'
Toast.makeText(this,text,Toast.LENGTH_SHORT).show();
• Appel direct du Toast pour une durée 'longue'
Toast.makeText(this,text,Toast.LENGTH_LONG).show();
Applications Java sous Android
IvMad, 2011-2014
23
CheckBox
public void onClick(View v) {
Toast tst;
String answer="";
if (cba.isChecked()) {
answer += cba.getText()+" ";
}
if (cbb.isChecked()) {
answer += cbb.getText()+" ";
}
if (cbc.isChecked()) {
answer += cbc.getText()+" ";
}
tst = Toast.makeText(this, answer,
Toast.LENGTH_LONG);
tst.show();
}
}
CheckBox cba, cbb, cbc;
protected void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout ll = new LinearLayout(this);
ll.setGravity(Gravity.TOP);
ll.setOrientation(LinearLayout.VERTICAL);
// add button
Button b = new Button(this);
b.setText("Cliquez ici!");
b.setOnClickListener(this);
ll.addView(b);
//add checkboxes
cba = new CheckBox(this);
cba.setText("Bleu");
ll.addView(cba);
cbb = new CheckBox(this);
cbb.setText("Blanc");
ll.addView(cbb);
cbc = new CheckBox(this);
cbc.setText("Rouge");
ll.addView(cbc);
setContentView(ll);
}
Afficher avec Toast
Applications Java sous Android
IvMad, 2011-2014
Radio bouton
protected void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
// Gestionnaire de placement
LinearLayout ll = new LinearLayout(this);
ll.setGravity(Gravity.TOP);
ll.setOrientation(LinearLayout.VERTICAL);
// Bouton
Button b = new Button(this);
b.setText("Affichez votre langage préféré");
b.setOnClickListener(this);
ll.addView(b);
// Radio boutons en groupe
rg = new RadioGroup(this);
rg.setOrientation(RadioGroup.VERTICAL);
rba = new RadioButton(this);
rba.setText("Java");
rg.addView(rba);
rbb = new RadioButton(this);
rbb.setText("Python");
rg.addView(rbb);
rbc = new RadioButton(this);
rbc.setText("C#");
rg.addView(rbc);
// Placement dans layout
ll.addView(rg);
setContentView(ll);
}
public void onClick(View v) {
Toast tst;
if ( rba.isChecked() ) {
tst = Toast.makeText(this,
rba.getText(), Toast.LENGTH_LONG);
tst.show();
}
if ( rbb.isChecked() ) {
tst = Toast.makeText(this,
rbb.getText(), Toast.LENGTH_LONG);
tst.show();
}
if ( rbc.isChecked() ) {
tst = Toast.makeText(this,
rbc.getText(), Toast.LENGTH_LONG);
tst.show();
}
}
Afficher avec Toast
24
Applications Java sous Android
IvMad, 2011-2014
25
Android Spinner (ComboBox)
public class SpinnerComBoxActivity extends Activity implements OnClickListener {
String colors[] = {"Red","Blue","White","Yellow","Black"};
Spinner sp;
public class SpinnerComBoxActivity extends Activity implements OnClickListener {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout ll = new LinearLayout(this);
ll.setGravity(Gravity.TOP);
ll.setOrientation(LinearLayout.VERTICAL);
Button b = new Button(this);
b.setText("Affichez votre choix");
b.setOnClickListener(this);
ll.addView(b);
sp = new Spinner(this);
// Appliquer une 'Array' pour le 'Spinner'
ArrayAdapter<String> spArrayAdapter =
new ArrayAdapter<String> (this,android.R.layout.simple_spinner_item,colors);
sp.setAdapter(spArrayAdapter);
ll.addView(sp);
setContentView(ll);
}
public void onClick(View v) {
int i = sp.getSelectedItemPosition();
Toast.makeText(getBaseContext(),"Votre choix: "+colors[i],Toast.LENGTH_SHORT).show();
}
}
Applications Java sous Android
IvMad, 2011-2014
Android Spinner (ComboBox)
• Pour réaliser la liste déroulante avec la classe Spinner dans le fichier
activity_spinner_com_box.xml il faut ajouter le code suivant:
<Spinner
android:id="@+id/Spinner01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawSelectorOnTop="true">
</Spinner>
Enregistrer la
description XML
du Spinner dans le
layout de l'activité
26
Applications Java sous Android
IvMad, 2011-2014
27
Android Toggle button
public class ToggleButtonMainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ScrollView scrl = new ScrollView(this);
final LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
scrl.addView(ll);
// ajouter un 'Toggle button'
ToggleButton tb = new ToggleButton(this);
tb.setTextOn("ON");
tb.setTextOff("OFF");
tb.setChecked(true);
tb.setLayoutParams(new LayoutParams
(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
ll.addView(tb); this.setContentView(scrl); } }
Applications Java sous Android
IvMad, 2011-2014
Android - GUI dynamique
28
Applications Java sous Android
IvMad, 2011-2014
29
Android : Ecrire dans un fichier
WriteData(getApplicationContext(),textOut); // Appel de la méthode
............
// context: id de l'application
public void WriteData(Context context, String data) {
FileOutputStream fOut = null;
OutputStreamWriter osw = null;
try {
// Ouvrir un fichier 'contacts.dat' en mode ajouter
fOut = context.openFileOutput("contacts.dat",MODE_APPEND);
osw = new OutputStreamWriter(fOut);
osw.write(data);
// Ecrire les données dans le flux de sortie
osw.flush();
// Vider le flux de sortie
// affiche le résultat de l'opération
Toast.makeText(context,"Sauvegarde réussie",Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(context,"Problème de
sauvegarde!",Toast.LENGTH_SHORT).show();
}
finally {
try {
osw.close();
// Fermer le flux d'écriture
fOut.close();
// Fermer le fichier 'contact.dat'
} catch (IOException e) {
Toast.makeText(context,"Problème de
sauvegarde",Toast.LENGTH_SHORT).show();
}
}
}
Applications Java sous Android
IvMad, 2011-2014
30
Android : Lire dans un fichier
String dataread = ReadData(getApplicationContext()); // Appel de la méthode
.....................
// context: id de l'application
public String ReadData(Context context) {
FileInputStream fIn = null;
InputStreamReader isr = null;
char[] inputBuffer = new char[255];
String data = null;
try {
fIn = context.openFileInput("contacts.dat"); // Ouvrir le fichier
isr = new InputStreamReader(fIn);
// Lire dans le flux d'entrée
isr.read(inputBuffer);
// Lire le contenu du tampon
data = new String(inputBuffer); // Convertir les données en chaine de car.
// affiche le contenu du fichier dans un popup surgissant
Toast.makeText(context,"Contenu: "+data,Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(context,"Erreur de lecture",Toast.LENGTH_SHORT).show();
}
finally {
try { isr.close(); fIn.close();
} catch (IOException e) {
Toast.makeText(context,"Erreur de lecture",Toast.LENGTH_SHORT).show();
}
}
return data;
}