APPLICATIONS JAVA
Android Partie I
Ivan MADJAROV - 2014
1. Android
Développement d'activités Java sous 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.
L'architecture du système Android
• Androidest un système d'exploitation basé Linux pour les appareils mobiles (Smartphone
et Tablette) avec une interface de programmation Java.
• Le SDK Androida tous les outils nécessaires pour le développement d'applications:
• Compilateur
• Débogueur
• Emulateur
• Machine virtuelle
Applications Java sous Android IvMad, 2011-2014 3
Application Android
•Androidest un SE créé par l'Open Handset Alliancedirigée parGoogle.
•Androidpropose une interface de programmation Java avec sa propre machine virtuelle DVM (Virtual Machine Dalvik).
• L'interface fournit des outils pour la compilation, le débogage et un simulateur de périphérique mobile est embarqué.
•Android utilise une machine virtuelle spéciale. Son byte-code est incompatible avec celui de Java standard (Oracle).
• Un outil "dx" est proposé pour convertir un fichier Java classe dans le format Android "dex" (Dalvik exécutable).
•Une application Android est emballée dans un fichier .apk (Android Package) par AAPT (Android Asset Packaging Tool)
•Pour développer Google fournit ADT (Android Development Tools) pour l'IDEEclipseet pour l'IDENetBeansde Sun (Oracle).
Applications Java sous Android IvMad, 2011-2014 4
Application Android
• L'ADT effectue automatiquement la conversion d'une classe "dex" en .apkau cours du déploiement.
• Androidsupporte le graphisme 2-D et 3-D avecOpenGL library.
• Le stockage de données dans une BD est pris en charge parSQLite.
•SQLiteest uneOpen Source Database intégrée dansAndroid.
•SQLite supporte les fonctionnalités standards pour une BDR telles que SQL syntaxe, la gestion des transactions et "prepared statements".
• Une application Android s'exécute dans son propre processus et sous son propre nom d'utilisateur qui est généré automatiquement au cours de son déploiement. Par conséquent, l'application est isolée des autres applications en cours et ne peut pas facilement affecter leur sécurité.
Applications Java sous Android IvMad, 2011-2014 5
L'architecture du système Android
•LeGUId'Androidest un systèmemono-thread,événementielavec une bibliothèque à composants extensibles organisée autour du modèle Model-View-Controller (MVC).
• Model: représente les données et le conteneur de données: base de données, images, sons, etc.
• View: c'est la partie de l'application chargée de rendre l'affichage, l'envoi de l'audio aux haut-parleurs, générant un retour tactile.
• Controller: c'est la partie qui répond à des actions externes: le clavier, l'écran tactile, les appels entrants.
Applications Java sous Android IvMad, 2011-2014 6
Le développement Android
• Androiddispose d'un SDK basé sur le langage Java.
• Le SDKd'Androidest disponible pour les plateformes Linux, Mac et Windows à l'adresse :
http://code.google.com/android/download.html
• Pour développer avec l'IDE EclipseGoogle fournit un plugin ADT (Android Development Tools):
https://dl-ssl.google.com/android/eclipse/
• Pour le développementt avec l'IDE NetBeans Android propose le plugin "nbandroid" accessible à :http://nbandroid.kenai.com.
• Le développement pour Android est possible aussi sans un IDE particulier en se servant des commandes du SDK d'Android avec Ant pour la compilation et la gestion du simulateur.
•A consulter :http://ydisanto.developpez.com/tutoriels/android/debuter/
Applications Java sous Android IvMad, 2011-2014 7
Le développement Android
•La chaine de production JavaAndroid
Applications Java sous Android IvMad, 2011-2014 8
Le système Android
• Architecture d'une application JavaAndroid
Java2SE (Oracle) et Java Dalvik (Google)
Architecture Android
Applications Java sous Android IvMad, 2011-2014 11
L'application Android
•Une application Android en général est composée d'éléments identifiables qui peuvent se séquencer différemment en fonction des objectifs :
1. Interface graphique : la partie visuelle de l'application, elle sert de support pour les interactions de l'utilisateur.
2. Traitement d'un événement : Les interactions de l'utilisateur avec le GUI déclenche des événements qui sont gérés par les écouteurs d'événements (Listener)
3. Opération de fond (Intent) : Des opérations de fond peuvent échanger des messages par la technique desIntents.
4. Connexion TCP ou Bluetooth: connexion à un réseau Wi-Fi ou à un autre Smartphone.
5. Affichage des résultats : on retourne à l'interface graphique
Applications Java sous Android IvMad, 2011-2014 12
APPLICATIONS JAVA
Android Partie II
Ivan MADJAROV - 2014
2. Android
Développement sous Eclipse avec SDK Android
Applications Java sous Android IvMad, 2011-2014 2
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.
Développer avec Eclipse
• Les outils nécessaires sont :
•Android SDK:http://dl.google.com/android/android-sdk_r22.3-windows.zip
•Eclipse:http://www.eclipse.org/downloads/eclipse-standard-kepler-x86_64.zip
•Le plugin ADT de Eclipse:https://dl-ssl.google.com/android/eclipse/
• Préparation de l’environnement
•Installation du SDKAndroiddans SE.
•Installation plug-in ADT pourAndroiddansEclipse
•Installation d’un téléphone virtuelAndroid
•Configuration d'une unité virtuel dans l'IDEEclipse
•Un téléphone ou tabletteAndroidse connectent à un PC par le câble USB.
Applications Java sous Android IvMad, 2011-2014 3
Développer avec Eclipse
Applications Java sous Android IvMad, 2011-2014 4
Zone de stockage des projets Eclipse
Développer avec Eclipse Développer avec Eclipse
Développer avec Eclipse
Applications Java sous Android IvMad, 2011-2014 7
Développer avec Eclipse
Applications Java sous Android IvMad, 2011-2014 8
Développer avec Eclipse
Applications Java sous Android IvMad, 2011-2014 9
1
2
3
Développer avec Eclipse
Applications Java sous Android IvMad, 2011-2014 10
Développer avec Eclipse
• Installation du plug-in ADT pourEclipse -> Help -> Installer un nouveau Software
Applications Java sous Android IvMad, 2011-2014 11
Développer avec Eclipse
Applications Java sous Android IvMad, 2011-2014 12
Développer avec Eclipse
• Renseigner les champs:NameetLocation
Développer avec Eclipse
1
2
3
Développer avec Eclipse
Applications Java sous Android IvMad, 2011-2014 15
Développer avec Eclipse
Applications Java sous Android IvMad, 2011-2014 16
Développer avec Eclipse
Applications Java sous Android IvMad, 2011-2014 17
Installation du SDK Android
Applications Java sous Android IvMad, 2011-2014 18
Installation du SDK Android
Applications Java sous Android IvMad, 2011-2014 19
Développer avec Eclipse
•Installation d’un téléphone virtuel Android
Applications Java sous Android IvMad, 2011-2014 20
Android SDK Manager
• Installation d’un téléphone virtuel Android
Android Virtual Device Manager
Android Virtual Device Manager
Applications Java sous Android IvMad, 2011-2014 23
Android Virtual Device Manager
Applications Java sous Android IvMad, 2011-2014 24
Nouveau projet Eclipse-Android
Applications Java sous Android IvMad, 2011-2014 25
Nouveau projet Eclipse-Android
Applications Java sous Android IvMad, 2011-2014 26
Nouveau projet Eclipse-Android
Applications Java sous Android IvMad, 2011-2014 27
Nouveau projet Eclipse-Android
Applications Java sous Android IvMad, 2011-2014 28
Nouveau projet Eclipse-Android Nouveau projet Eclipse-Android
Nouveau projet Eclipse-Android
Applications Java sous Android IvMad, 2011-2014 31
Code généré à la création du projet
Nouveau projet Eclipse-Android
Applications Java sous Android IvMad, 2011-2014 32
Pour exécuter l'application on click sur le bouton "Run".
L'émulateur Android est lancé (le chargement est long)
Nouveau projet Eclipse-Android
Applications Java sous Android IvMad, 2011-2014 33
Le "premier_projet_android" avec les composants à compiler et à exécuter dans un environnement d'émulateur
La classe R accède aux ressources
Classe interne associée à une ressource
Nom de la ressource dans le répertoire
res/layout
Plug-Ins Eclipse-Android
Applications Java sous Android IvMad, 2011-2014 34
Nouveau projet Eclipse-Android
Applications Java sous Android IvMad, 2011-2014 35
Log.i: méthode de traçage de l'exécution d'une
application Android
ADT Bundle pour Windows
•Pour le développement Android un seul kit est proposé le ADT Bundle qui inclue tous les outils nécessaires pour le développement d'une application sous Eclipse:
• Eclipse + ADT plugin
• Android SDK Tools
• Android Platform-tools
• The latest Android platform
• The latest Android system image for the emulator
• http://developer.android.com/sdk/index.html
Applications Java sous Android IvMad, 2011-2014 36
Intégrer un Smartphone au ADT
• Le Smartphone doit être configuré en mode "PTP"
• Avant de lancer Eclipse il faut brancher le Smartphone à l'ordinateur
• Ouvrir un invité de commandes et exécuter la commande:
• C:\Program Files\Android\android-sdk\platform-tools\adb.exe -c devices
• A la demande du Smartphone autoriser l'adresse MAC du PC sur le Smartphone (étape à ne pas rater!)
APPLICATIONS JAVA
Android Partie III
Ivan MADJAROV - 2014
3. Architecture d'une application Android
Applications Java sous Android IvMad, 2011-2014 2
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.
Composantes Android (1)
•Les éléments essentiels du FrameworkAndroid :
•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 3
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. Unbroadcast receiver peut afficher un message, lancer une activité ou un service.
• Intent-Filter : un filtre d'intention sert à indiquer à une activité, service oubroadcast receiverquelsIntentspeuvent implicitement traiter.
Applications Java sous Android IvMad, 2011-2014 4
Cycle de vie d’une application Android
public class MainActivity extends Activity { public voidonCreate(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();
} }
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 unBundleest 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éthodesOnResume.
•onStop: Appelée quand l'activité n’est plus visible.
•onDestroy: Appelée quand l'application est fermée (processus closed).
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 7
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 8
Le principe de l'interface graphique
Applications Java sous Android IvMad, 2011-2014 9
Le principe de l'interface graphique
•LeGUIsous Android est basée sur lesView, lesLayoutet lesWidget.
•Unlayout (gabarit) est uneView (vue) spéciale qui peut contenir d'autres View,ainsi lelayoutjoue le rôle d'un conteneur.
•Le Layout n'est pas destinée à fournir du contenu ou des contrôles à l'utilisateur.
•Les layoutsse contentent de disposer les Viewspar un gestionnaire de placement.
•Les Viewsse chargent de mettre le contenu utilisateur en place.
•Une Viewqui ne peut pas en englober d'autres est appelée un widget(composant).
Applications Java sous Android IvMad, 2011-2014 10
Composants graphiques (Java)
Applications Java sous Android IvMad, 2011-2014 11
• La class Viewest une zone de composant et source d'événement ce qui forme la base du GUI.
Vues et schémas (Java)
•Les éléments graphiques héritent de la classeView. On peut regrouper des éléments graphiques dans uneViewGroup.
•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 classeViewGroup ressemble à un gestionnaire de placement connu enSwingde 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 12
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);
} }
Simulateur d'unité mobile sous Android
• La méthode setTextde la classe TextViewmet un String dans GUI.
• La méthode
setContentViewaffiche la chaine de caractère dans l'interface graphique.
Fait passer une instance de
l'activité
Label de texte et zone de texte ( Java)
Définir le conteneur et l'ordre de placement des
composants
Avec une image (Java)
Applications Java sous Android IvMad, 2011-2014 15
ImageView() est la boite qui peut contenir une image.
Les images utiles au projet sont placées dans le dossier
"res/drawable"
TextView, EditText, ImageView, Bouton
Applications Java sous Android IvMad, 2011-2014 16
Récupérer la saisie d'un texte (Java)
Applications Java sous Android IvMad, 2011-2014 17
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);
}
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());
} }
Applications Java sous Android IvMad, 2011-2014 18
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 programmesAndroid, mail il faut consulter le guide de référence des classesAndroidpour connaitre leur disponibilité et compatibilité.
• Les activités sont des classes publiques héritées de la classe de base android.app.Activity.
• Leswidgets sont des éléments d’interface graphique qu'on peut utiliser dans une application.
Applications Java sous Android IvMad, 2011-2014 19
Déroulement de l'exemple (2)
•L’activité contient un bouton :Button btn;
• Un bouton est unwidgetAndroidet peut être utilisé dans une application.
•Pour capturer tous les clics de bouton dans l'activité elle-même on implémenteOnClickListener(é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é Androidde 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éthodeonClick(View v).
•Un appel la méthode privéeupdateTime() 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 20
Déroulement de l'exemple (3)
• Tous leswidgetsdérivent de la classe de baseView.
• Bundle icicle 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’ActionListenerconfiguré pour ce bouton (Java2SE).
• Avec Android un clic sur un bouton fait appel de la méthode
onClick()sur l’instanceOnClickListenerconfigurée pour ça.
• L’écouteur reçoit la vue qui a déclenché le clic et on fait alors appel à la méthode privéeupdateTime().
• 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éthodesetText(),qui fonctionne exactement comme avec lesJButtondeSwing.
Toast : popup surgissant
•Afficher un contenu dans un popupsurgissant
• La classe Toastavec la méthode makeTextaffiche une fenêtre popuppour 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); // Appel toast.show(); // 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();
CheckBox
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);
}
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();
} }
Applications Java sous Android IvMad, 2011-2014 23
Afficher avec Toast
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();
} }
Applications Java sous Android IvMad, 2011-2014 24
Afficher avec Toast
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 25
Android Spinner (ComboBox)
•Pour réaliser la liste déroulante avec la classe Spinnerdans le fichier activity_spinner_com_box.xmlil faut ajouter le code suivant:
<Spinner
android:id="@+id/Spinner01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawSelectorOnTop="true">
</Spinner>
Applications Java sous Android IvMad, 2011-2014 26
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 27
Android - GUI dynamique
Applications Java sous Android IvMad, 2011-2014 28
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();
} } }
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;
}
APPLICATIONS JAVA
Android Partie IV
Ivan MADJAROV - 2014
4. Application réseaux, Bluetooth, Wi-Fi
Android
Applications Java sous Android IvMad, 2011-2014 2
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.
Android : LogCat view
• Le développement pose toujours le problème de tester l'application avant sa mise en "service". La View de l'application est en mode graphique. Les logs permettent l'affichage en mode texte dans la fenêtre duLogCat.
• Pour afficher les opérateurs 'log' dans Eclipse il faut activer le LogCat view:
•Window->Show View->Other...->LogCat.
• Pour écrire un opérateur 'Log' il faut importer la classe android.util.Log qui propose les méthodesLog.i()"Info", Log.d()"Debug", Log.w()
"Warning", Log.e()"Error" .
• Exemple:
•Log.i("NameActivity", "Bonjour, ça marche!");
Applications Java sous Android IvMad, 2011-2014 3
Android : Bluetooth (1)
• Bluetooth est un protocole d'interconnexion à de courtes distances, de type "peer-to-peer" avec une bande passante faible. La communication est cryptée entre les périphériques appariés. L'API Bluetooth permet de scanner et de lier les appareils entre eux et de transférer des données.
• Les connexionsBluetoothsont gérées par les classes suivantes :
•BluetoothAdapter: est l'unité locale où l'applicationBluetoothest lancée.
•BluetoothDevice : est le périphérique distant avec lequel on cherche à communiquer.
•BluetoothSocket: fait une demande de connexion au périphérique distant par l'appel de la méthodecreateRfcommSocketToServiceRecord.
•BluetoothServerSocket : installe un Socket Bluetooth serveur pour écouter les demandes de connexion entrantes en utilisant la méthode listenUsingRfcommWithServiceRecord.
Applications Java sous Android IvMad, 2011-2014 4
Android : Bluetooth (2)
•Pour s'assurer que le périphérique possède le Bluetooth on procéder à une vérification rapide en instanciant la classe BluetoothAdapter. Le retour de son objet va indiquer la présence ou non de cette option.
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null)
Toast.makeText(BluetoothActivity.this, "Pas de Bluetooth!", Toast.LENGTH_SHORT).show();
else
Toast.makeText(BluetoothActivity.this,"Le Bluetooth est disponible", Toast.LENGTH_SHORT).show();
•Pour autoriser l'opération, il faut ajouter la permission d'accéder aux API Bluetooth en ajoutant la ligne suivante dans le fichier
AndroidManifest.xml:
<uses‐permission android:name="android.permission.BLUETOOTH"/>
Android : Bluetooth (3)
• LeBluetoothpeut être disponible sur l'appareil mais non activé. On peut demander l'autorisation à l'utilisateur d'activer cette option. Pour cela, on appelle la méthode startActivityForResult avec un paramètre d'Intent BluetoothAdapter.ACTION_REQUEST_ENABLE. On vérifie que le Bluetooth n'est pas activé et on demande son activation :
private final static int BLUETOOTH_ACTIVATION = 1;
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
...
if (!bluetoothAdapter.isEnabled() {
startActivityForResult(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE), BLUETOOTH_ACTIVATION);
}
• Un dialog-box incitera l'utilisateur d'accepter ou non l'activation du Bluetoothsur son appareil. Le résultat de sa décision est récupérable par la méthodeonActivityResult.
Android : Bluetooth (4)
•On surcharge la méthode onActivityResultpour savoir si le Bluetoothest activé ou non. La méthode est appelée à la sortie de la boite de dialogue
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data) { super.onActivityResult(requestCode, resultCode, data);
if (requestCode == BLUETOOTH_ACTIVATION) { if (resultCode == RESULT_OK) {
Toast.makeText(BluetoothActivity.this, "Bluetooth est activé", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(BluetoothActivity.this, "Bluetooth non activé", Toast.LENGTH_SHORT).show();
} } }
Applications Java sous Android IvMad, 2011-2014 7
Android : Bluetooth (5)
• Si on rend l'appareil Bluetoothdétectable cela permet à d'autres appareils de le découvrir et de se connecter par la suite. Pour cela, on utilise la méthode startActivityForResultavec le paramètre Intentapproprié :
startActivityForResult(new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE),
BLUETOOTH_SCAN);
• On obtient la liste des appareils déjà liés avec getBoundedDevices.
Set<BluetoothDevice> knownDevices = bluetoothAdapter.getBoundedDevices();
for (BluetoothDevice device : knownDevices) {
Log.v("BluetoothActivity", "appareil = " + devices.getName());
}
• Set: interface de collection pour des objets qui n'autorisent pas des doublons dans l'ensemble, existe au moins un nul (un tableau d'objets).
• for-each: boucle qui accède à chaque élément d'une collection d'objets comme dans un tableau (eg, ArrayList).
Applications Java sous Android IvMad, 2011-2014 8
Android : Bluetooth (6)
•Le code complet (étudiez les instructions 'Set' et 'for') :
public class BluetoothDeviceListActivity extends Activity { private final static int BLUETOOTH_SCAN = 1;
String s = "";
@Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
startActivityForResult(new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE),BLUETOOTH_SCAN);
Set<BluetoothDevice> knownDevices =
bluetoothAdapter.getBondedDevices();
for (BluetoothDevice device : knownDevices) { s += "appareil = " + device.getName();
}
Toast.makeText(BluetoothDeviceListActivity.this,"Les Bluetooth liés:
"+s,Toast.LENGTH_SHORT).show();
} }
Applications Java sous Android IvMad, 2011-2014 9
Android : Bluetooth (7)
• La recherche d'appareils inconnus est un traitement asynchrone et gourmant en energie effectué par le Broadcast Receiver.
• Android permet de créer une classe qui implémente BroadcastReceiverpour recevoir des Intents et appliquer des comportements spécifiques au code.
• L’interface BroadcastReceiverpossède une seule méthode onReceive() qu'on doit implémenter.
BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Toast.makeText(BluetoothActivity.this, "New Device = " +
device.getName(), Toast.LENGTH_SHORT).show();
} } };
Applications Java sous Android IvMad, 2011-2014 10
Android : BT (8) Mettre tout ensemble
Applications Java sous Android IvMad, 2011-2014 11
Ajouter les permissions dans le fichier manifest.xml
Android : Wi-Fi (1)
•Sous Android le Wi-Fi est géré par un WifiManager. Le WifiManager représente un Android Wi-Fi Connectivity Service. Il est capable de configurer une connexion Wi-Fi, de gérer une connexion en cours, de scanner pour des points d'accès et d'enregistrer tout changement dans une connexion Wi-Fi.
•Le Wi-FiManager utilise la méthode getSystemService en précisant le type de service en constante:Context.WIFI_SERVICE
String service = Context.WIFI_SERVICE;
WifiManager wifi = (WifiManager)getSystemService(service);
•Pour autoriser l'utilisation du Wi-FiManager les paramètres des permissions pour accès et modification doivent être réglés dans le fichiermanifestdu projet.
<uses‐permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses‐permission android:name="android.permission.CHANGE_WIFI_STATE"/>
Applications Java sous Android IvMad, 2011-2014 12
Android : Wi-Fi (2)
• Avec le Wi-FiManager on peut notamment activer ou désactiver la fonction Wi-Fi dans l'appareil par la méthodesetWifiEnabled, obtenir le statut actuel du Wi-Fi par la méthodegetWifiStateou vérifier si le Wi-Fi est activé avec la méthodeisWifiEnabled.
if (!wifi.isWifiEnabled())
if (wifi.getWifiState() != WifiManager.WIFI_STATE_ENABLING) wifi.setWifiEnabled(true);
• La méthodegetWifiState()retourne un entier entre 0 et 4 pour indiquer la situation en cours duWiFide l'appareil :
0 ‐ WIFI_STATE_DISABLING 1 ‐ WIFI_STATE_DISABLED 2 ‐ WIFI_STATE_ENABLING 3 ‐ WIFI_STATE_ENABLED 4 ‐ WIFI_STATE_UNKNOWN
Android : Wi-Fi (3)
•Si on met tout ensemble on peut vérifier l'état de notre appareil :
public class WiFiStateActivity extends Activity { String[] wifiState = {"WIFI_STATE_DISABLING",
"WIFI_STATE_DISABLED", "WIFI_STATE_ENABLING",
"WIFI_STATE_ENABLED", "WIFI_STATE_UNKNOWN"};
@Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
String service = Context.WIFI_SERVICE;
WifiManager wifi = (WifiManager)getSystemService(service);
Toast.makeText(this, "Wi‐Fi : " +
wifiState[wifi.getWifiState()],
Toast.LENGTH_LONG).show();
} }
Android : Wi-Fi (4)
• Pour obtenir des informations détaillées sur une connexion il faut se référer à la méthodegetConnectionInfode la classeWifiInfo.
• Cette classe offre un certain nombre de méthodes qui apportent des informations importantes sur les paramètres du réseau Wi-Fi:
•getSSID: Retourne l'identificateur du réseau 802.11 en cours;
•getBSSID(): Retourne l'identificateur de base de ce réseau;
•getMacAddress(): Retourne l'adresse MAC de l'appareil;
•getIpAddress() : Retourne l'adresse IP de l'appareil en format 'int'. Une conversion en format 'String' est alors nécessaire.
•getLinkSpeed(): Retourne le débit en Mbps
•getRssi(): Retourne le niveau de puissance reçu du réseau 802.11 connecté.
Applications Java sous Android IvMad, 2011-2014 15
Android : Wi-Fi (5)
Applications Java sous Android IvMad, 2011-2014 16
• Afficher les éléments d'une connexion Wi-Fi en ajoutant les composants dans un StringBuilderpar la méthode append()
Android : Wi-Fi (6)
• Avec le Wi-FiManager on peut procéder à la recherche des hotspot (bornes Wi-Fi) dans le voisinage par la méthodestartScan.
• Pour effectuer cette opération il faut utiliser un Broadcasr Receiver avec un Intent SCAN_RESULTS_AVAILABLE_ACTION passé en paramètre. Cela assure un traitement asynchrone et la prise du résultat quand le scan a terminé.
• On appelle la méthode getScanResultspour obtenir les résultats sous la forme d'une liste d'objetsScanResult.
• Chaque objet du type ScanResult comporte les détails de la connexion repérée.
• Le résultat du Scan est récupéré dans un objet de typeList<E>. C'est une collection d'éléments indexés à partir de zéro.
List<ScanResult> results = wifi.getScanResults();
Applications Java sous Android IvMad, 2011-2014 17
Android : Wi-Fi (7)
Applications Java sous Android IvMad, 2011-2014 18
• Retourne le nombre de hotspotdétectés et le SSID avec le plus fort signale à proximité
Android : StrictMode
•Dans une application Android, on doit éviter d'effectuer des opérations lentes sur lethreadde l'interface utilisateur (GUI).
• Les opérations lecture et écriture de fichiers et l'accès au réseau sont considérées comme lentes, car le temps d'aboutir est indéfini, voir imprévisible.
•StrictModeest configuré pour une sécurité accrue, c.à.d. pour éviter de faire des choses incorrectes. L'exception NetworkOnMainThreadException est provoqué si l'accès réseau est effectué de l'interface utilisateur (le threadprincipal de l'application).
•A partir de l'Android3.0 on peut désactiver cette option pour faire des tests plus facilement sur l'accès réseau en plaçant dans la méthode onCreate()le code:
StrictMode.ThreadPolicy policy = new StrictMode.
ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Applications Java sous Android IvMad, 2011-2014 19
Android : client-side TCP socket
package ivmad.TCP.Client;
import java.io.DataInputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.net.Socket;
import java.net.InetAddress; import java.net.UnknownHostException;
import android.app.Activity; import android.os.Bundle;
import android.os.StrictMode; import android.view.View;
import android.widget.Button; import android.widget.EditText;
import android.widget.LinearLayout; import android.widget.TextView;
public class ClientTCPAndroidActivity extends Activity {
LinearLayout layout; EditText textOut; TextView textIn; Button buttonSend;
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
textIn = new TextView(this);
textIn.setText("Message à soumettre");
textOut = new EditText(this);
buttonSend = new Button(this);
buttonSend.setText("Envoyer");
buttonSend.setOnClickListener(buttonSendOnClickListener);
layout.addView(textIn);
layout.addView(textOut);
layout.addView(buttonSend);
setContentView(layout);
}
Applications Java sous Android IvMad, 2011-2014 20
Android : client-side TCP socket
Button.OnClickListener buttonSendOnClickListener = new Button.OnClickListener() { public void onClick(View v) {
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
InetAddress serverAddr;
String serverIpAddress = "192.168.0.141";
// Définir les droits d'accès au ressources réseaux StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
try {
serverAddr = InetAddress.getByName(serverIpAddress);
socket = new Socket(serverAddr, 1234);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream.writeUTF(textOut.getText().toString());
textIn.setText(dataInputStream.readUTF());
} catch (UnknownHostException e) { e.printStackTrace();
} catch (IOException e) { e.printStackTrace(); } finally {
if (socket != null && dataOutputStream != null && dataInputStream != null) { try {
socket.close(); dataOutputStream.close(); dataInputStream.close();
} catch (IOException e) { e.printStackTrace(); } } } } }; }
Android : client-side TCP socket
•Le fichier AndroidManifest.xmlcontient la description des ressources et les autorisations d'accès au réseau Internet
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ivmad.TCP.Client"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".ClientTCPAndroidActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
L'autorisation d'accéder au réseau et configurée dans le Manifestde
l'application
Android : client-side TCP socket
Applications Java sous Android IvMad, 2011-2014 23
Le serveur TCP reçoit le message du client Android
Le client TCP basé Android envoie un message au Serveur basé TCP
Android : client HTTP
Applications Java sous Android IvMad, 2011-2014 24
• Avant de procéder à une connexion réseau, il faut s'assurer que cette connexion est disponible. Un téléphone portable, un Smartphone ou une tablette peut être hors réseau ou connexion Wifi désactivée.
• Cette disponibilité est testée avec les méthodesgetActiveNetworkInfo() et isConnected().
• La classe ConnectivityManager détecte les connexions Wifi, GPRS, UMTS, etc.
public boolean isNetworkAvailable() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
// Si le réseau est indisponible networkInfo = null et la // méthode retourne false, sinon true.
if (networkInfo != null && networkInfo.isConnected()) { return true;
}
return false;
}