ANDROID Tutoriel Lecture d'un flux XML distant et enchainement d'activités



Documents pareils
Outils, langage et approche Android Une introduction. Nicolas Stouls lyon.fr

TP au menu «UI ANDROID»

TP SIN Programmation sur androïde Support : eclipse

TP2 : Client d une BDD SqlServer

Programmation Mobile Android Master CCI

Android UIThread, Thread, Handler et AsyncTask

Tutorial pour une application simple

1.3 Gestion d'une application

Créer des applications Android

Projet Viticulture - TP 3 : bases de données distantes BTS Services informatiques aux organisations

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Les fondamentaux du développement d applications Java

Serveur d'application Client HTML/JS. Apache Thrift Bootcamp

Warren PAULUS. Android SDK et Android x86

Création d'un site dynamique en PHP avec Dreamweaver et MySQL

TD/TP 1 Introduction au SDK d Android

TP Composants Java ME - Java EE. Le serveur GereCompteBancaireServlet

Programmer en JAVA. par Tama

Projet de programmation (IK3) : TP n 1 Correction

La base de données XML exist. A. Belaïd

Page 1 sur 5 TP3. Thèmes du TP : l la classe Object. l Vector<T> l tutorial Interfaces. l Stack<T>

Java 7 Les fondamentaux du langage Java

Serveur d'archivage 2007 Installation et utilisation de la BD exist

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

RMI. Remote Method Invocation: permet d'invoquer des méthodes d'objets distants.

Android Publish/Subscribe, GCM, Google Cloud Messaging : une introduction

Installation et prise en main

contact@nqicorp.com - Web :

Application de lecture de carte SESAM-Vitale Jeebop

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

TP1 : Initiation à Java et Eclipse

RMI le langage Java XII-1 JMF

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Android 4 Les fondamentaux du développement d'applications Java

contact@nqicorp.com - Web :

JAVA 8. JAVA 8 - Les fondamentaux du langage. Les fondamentaux du langage Java. Avec exercices pratiques et corrigés JAVA 8 29,90.

1. Installation d'un serveur d'application JBoss:

Programmation des applications mobiles avec Android. 1 Inspiré du cours de Olivier Le Goaer

SOMMAIRE

Tutoriel d installation de Hibernate avec Eclipse

Chapitre 10. Les interfaces Comparable et Comparator 1

Développement sous Android

Web Tier : déploiement de servlets

Généralités sur le Langage Java et éléments syntaxiques.

Java DataBaseConnectivity

Java Licence Professionnelle CISII,

Cette application développée en C# va récupérer un certain nombre d informations en ligne fournies par la ville de Paris :

1. Base de données SQLite

JADE : Java Agent DEvelopment framework. Laboratoire IBISC & Départ. GEII Université & IUT d Evry nadia.abchiche@ibisc.univ-evry.

De Java à Android version 0.1

Java Licence Professionnelle Cours 7 : Classes et méthodes abstraites

Remote Method Invocation (RMI)

BTS SIO SISR3 TP 1-I Le service Web [1] Le service Web [1]

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

BASE DE DONNÉES XML NATIVE

Tutoriel: Création d'un Web service en C++ avec WebContentC++Framework

BTS S.I.O PHP OBJET. Module SLAM4. Nom du fichier : PHPRévisionObjetV2.odt Auteur : Pierre Barais

Création d une application JEE

TD Objets distribués n 3 : Windows XP et Visual Studio.NET. Introduction à.net Remoting

Pour plus de détails concernant le protocole TCP conférez vous à la présentation des protocoles Internet enseignée pendant.

Polymorphisme, la classe Object, les package et la visibilité en Java... 1

Programmation par les Objets en Java

Dossier. Développer en Java sur téléphone mobile. Benjamin Damécourt UFR SITEC Master 2 EESC 11 janvier 2012

SYNC FRAMEWORK AVEC SQLITE POUR APPLICATIONS WINDOWS STORE (WINRT) ET WINDOWS PHONE 8

RAPPELS SUR LES METHODES HERITEES DE LA CLASSE RACINE Object ET LEUR SPECIALISATION (i.e. REDEFINITION)

Plan du cours. Historique du langage Nouveautés de Java 7

Premiers Pas en Programmation Objet : les Classes et les Objets

Service WEB, BDD MySQL, PHP et réplication Heartbeat. Conditions requises : Dans ce TP, il est nécessaire d'avoir une machine Debian sous ProxMox

A DESTINATION DES SERVICES TIERS. Editeurs d applications et ressources pédagogiques connectées à l ENT

Un ordonnanceur stupide

as Architecture des Systèmes d Information

Généralités. javadoc. Format des commentaires. Format des commentaires. Caractères spéciaux. Insérer du code

Android et le Cloud Computing

Environnements de développement (intégrés)

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Initiation à JAVA et à la programmation objet.

TP architecture N-tiers en Java EE ou Java EE, Android : la synthèse. Le serveur GereCompteBancaireServlet

Documentation CAS à destination des éditeurs

Corrigé des exercices sur les références

INITIATION AU LANGAGE JAVA

Dis papa, c est quoi un bus logiciel réparti?

PHP 5.4 Développez un site web dynamique et interactif

Bases Java - Eclipse / Netbeans

Développement Android. J.-F. Couchot

Développement mobile MIDP 2.0 Mobile 3D Graphics API (M3G) JSR 184. Frédéric BERTIN

Créer un rapport pour Reporting Services

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

SECURIDAY 2013 Cyber War

DÉVELOPPEMENT ANDROID

Soon_AdvancedCache. Module Magento SOON. Rédacteur. Relecture & validation technique. Historique des révisions

Gestion d Active Directory à distance : MMC & Délégation

TUTORIEL: INSTALLATION D'UN SERVEUR LOCAL SOUS WINDOWS 7 POUR APPINVENTOR version du 06/04/2013

Projet Android (LI260) Cours 2

Installation de la plate-forme Liberacces 2.0 «Intégrale» avec LiberInstall

Auto-évaluation Programmation en Java

Développement sous Android

Introduction à JDBC. Accès aux bases de données en Java

Module http MMS AllMySMS.com Manuel d intégration

Remote Method Invocation Les classes implémentant Serializable

Assistance à distance sous Windows

Transcription:

L'objectif de ce tutoriel est de vous présenter une des façons d'exploiter en lecture des informations distantes disponibles au format XML. L'application présentera le résultat dans une ListView 1/ Prérequis Savoir utiliser une ListView : faire le tutoriel suivant httph://developers.androidcn.com/resources/tutorials/views/hello-listview.html Remplacer dans ce tutoriel le new OnItemClickListener() par une implémentation de l'interface OnItemClickListener. Disposer d'une connexion internet permettant l'accès à cette ressource distante. Pour cela vous pouvez télécharger cette ressource : http://guyonst.free.fr/android/jukebox.tar.gz Une fois décompresser dans votre [home directory]/public_html, vous accéder à cette ressource http://localhost/~sio/jukebox/albums-by-genre.php L'application utilise SQLITE et non MYSQL, si vous avez un message d'erreur vous devez installer le driver sqlite, pour l'installer, connectez vous en root : # aptitude install php5-sqlite #/etc/init.d/apache2 restart ( relancer apache) => vérifier à l'aide d'un navigateur, et observer le source de la réponse. 2/ Projet 1. Lancez le logiciel Eclipse et un émulateur Android 2. Créer un nouveau projet Android : TpFluxXml. On utilisera comme cible (Target) : Android 2.2 dans un objectif purement pédagogique. En effet à partir de la version 4 la lecture d'un flux distant est devenu beaucoup plus complexe comme le verrez dans la suite du TP. L'objectif de la première partie de ce TP étant de comprendre comment lire et ensuite parser un flux distant Xml. Version du 28/03/2014 Page 1 sur 12

L'application devant accéder à une ressource distante, nous devons signaler la nécessité d'utiliser une connexion Internet. Ceci se déclare dans le fichier AndroidManifest.xml placé à la racine de l'application : <?xml version="1.0" encoding="utf 8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.ldv.tpxml" android:versioncode="1" android:versionname="1.0"> <uses permission android:name="android.permission.internet" /> <uses sdk android:minsdkversion="8" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".main" 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> Il est parfois nécessaire de réaliser un clean (Project/Clean) pour permettre la suppression des versions compilées des différentes sources du projet et forcer de nouveau leur compilation. Lancer l'application. Vous devriez voir dans la console : Le nom de l'activité qui est sera créée au démarrage : org.ldv.tpxml.main Le nom du fichier de déploiement : tpxml.apk Le nom de l'émulateur sur lequel l'application packagée est déployée. 3/ Document XML et Classe métier Notre application exploite des données structurées. Extrait du document XML reçu : <albums genre='rock'> <album> <artist>u2</artist> <title>sunday Bloody Sunday</title> <year>1983</year> </<album> etc. </albums> Version du 28/03/2014 Page 2 sur 12

La structure d'un album sera déclarée par une Classe métier nommée Album : package org.ldv.tpxml; public class Album { private String artist; private int year; private String title; etc. public String tostring() { return title; public String getartist() { return artist; public void setartist(string artist) { this.artist = artist; Version du 28/03/2014 Page 3 sur 12

4/ Classe (ou activité) principale Pour pouvoir utiliser avec plus de facilité le composant widget d'andoid ListView, nous avons fait hériter la classe Main non pas de Activity mais de ListActivity : public class Main extends ListActivity Le type (TextView) des éléments de la liste sera renseigné dans un fichier list_item.xml. Ce fichier est placé dans le répertoire layout lui-même sous-répertoire de res comme le montre cette arborescence : Contenu du fichier list_item.xml : <?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="10dp" android:textsize="14sp" > </TextView> Sont renseignés ici le type (TextView) mais aussi les paramètres utiles à leur affichage. Ces informations sont référencées dans notre projet par un identifiant public placé dans une classe statique générée par le système (à ne pas modifier!) : R.layout.list_item // dans la méthode oncreate this.setlistadapter(new ArrayAdapter<Album>(this, R.layout.list_item, albums)); Pour lier la liste d'objets Album à la ListView, on utilise un objet ArrayAdapter qui se charge d'adapter la liste d'objets Album au besoin du composant utilisé (ListActivity). On distingue bien ici le modèle (albums) de la vue (TextView). Notre application conservera en mémoire la structure de l'arbre sous la forme d'une collection. Pour cela nous parcourons le document XML afin d'ajouter, un par un, les éléments compatibles avec la déclaration de la collection (ici un objet de type List contenant des objets de type Album). Nous utilisons une solution clé en main offerte par l'api XmlPullParser disponible avec le framework Android. Version du 28/03/2014 Page 4 sur 12

Voici la partie déclaration des constantes et attributs d'instances de la classe Main. public class MainActivity extends ListActivity implements OnItemClickListener { // on renseigne l'adresse de la machine host private static final String URL_XMLRESSOURCE = "http://xxx/albums-by-genre.php"; // 10.0.2.2 (pour atteindre le localhost à partir de l'émulateur) // "http://10.0.2.2/~xx/xxx.php"; // Le nom des balises du doc XML reçu private static final String ALBUMS = "albums"; private static final String ALBUM = "album"; private static final String ARTIST = "artist"; private static final String TITLE = "title"; // la liste des albums en mémoire (petite liste) private List<Album> albums; Voici la méthode appelée lors de la création de l'instance de l'activité, fortement inspirée du tutoriel Hello List View : http://developers.androidcn.com/resources/tutorials/views/hello-listview.html public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); // on obtient la liste des albums en appelant la méthode parse albums = parse(url_xmlressource) ; // on initialise la ListView (comme dans le tuto Hello List View) setlistadapter(new ArrayAdapter<Album>(this, R.layout.list_item, albums)); ListView lv = getlistview(); lv.settextfilterenabled(true); lv.setonitemclicklistener(this); La classe Main implémente l'interface OnItemClickListener, lorsqu'on implémente une interface, on doit implémenter toutes les méthodes de cette interface, dans ce cas la méthode : public void onitemclick(adapterview<?> arg0, View arg1, int arg2, long arg3) arg2 : représente la position de l'item sélectionné dans la liste public void onitemclick(adapterview<?> arg0, View arg1, int arg2, long arg3) { Toast.makeText(getApplicationContext(),"L'index de cet élément est : " + arg2, Toast.LENGTH_SHORT).show(); Version du 28/03/2014 Page 5 sur 12

La méthode parse ci-dessous s'inspire fortement sur l'exemple de la documentation de l'api XmlPullParser : http://developer.android.com/reference/org/xmlpull/v1/xmlpullparser.html Son objectif est d'intégrer les données de la ressource distante dans l'application. /** * Obtient une liste d'objet Album à partir d'une ressource XML * @param strurl l'adresse de la ressource * @return liste d'objets Album (peut être vide) */ private List<Album> parse(string strurl) { List<Album> listealbums = new ArrayList<Album>(); XmlPullParser parser = Xml.newPullParser(); try { // auto-detect the encoding from the stream parser.setinput(this.getinputstream(strurl), null); int eventtype = parser.geteventtype(); Album currentalbum = null; boolean done = false; while (eventtype!= XmlPullParser.END_DOCUMENT &&!done) { String name = null; switch (eventtype) { case XmlPullParser.START_TAG: name = parser.getname(); if (name.equalsignorecase(album)) { currentalbum = new Album(); Log.i("tag1 : ", "creation album"); else if (currentalbum!= null) { if (name.equalsignorecase(artist)) { currentalbum.setartist(parser.nexttext()); else if (name.equalsignorecase(title)) { currentalbum.settitle(parser.nexttext()); // etc. break; case XmlPullParser.END_TAG: name = parser.getname(); // fin de balise Album? if (name.equalsignorecase(album) && currentalbum!= null) { Log.i("ajout album : ", currentalbum.tostring()); listealbums.add(currentalbum); // fin de balise Albums? else if (name.equalsignorecase(albums)) { // oui, on signe l'arrêt de la boucle done = true; break; // avance dans le flux eventtype = parser.next(); catch (Exception e) { throw new RuntimeException(e); return listealbums; Version du 28/03/2014 Page 6 sur 12

Il ne nous reste qu'à présenter la méthode getinputstream utilisée par notre méthode parse. private InputStream getinputstream(string strurl) { InputStream res = null; try { URL url = new URL(strUrl); res = url.openconnection().getinputstream(); catch (Exception e) { Log.d("Erreur.", e.getmessage()); if (res == null) res = new ByteArrayInputStream("<albums><album><title>Vide! </title></album></albums>".getbytes()); return res; À partir d'une URL donnée (reçue en paramètre) sous la forme d'une chaîne de caractères, nous instancions la classe URL (standard du JDK) nous permettant de réaliser une connexion réseau (protocole HTTP par défaut). L'astuce consiste ici à retourner toujours une donnée valide (une instance qui implémente l'interface InputStream), que l'url soit bien formée ou non, contenant une ressource ou non. TRAVAIL À FAIRE 1. Quel est l'objectif de cette instruction : List<Album> listealbums = new ArrayList<Album>(); 2. Que signifie «parser» un fichier XML? 3. Que représente les «tags»? Comment est structuré un document XML? 4. Quel est «l'élement ROOT» et les éléments enfants de votre document XML? 5. Quel est le type de la valeur retournée par les méthodes parse et getinputstream? 6. Quelles lignes de codes font appel à ces méthodes? 7. Quel est le type de la valeur retournée par la méthode Toast.makeText(...)? 8. Pourquoi la méthode parse est-elle déclarée private? 9. A quoi correspond cette instruction : name = parser.getname() ; 10. Que font les instructions suivantes : if (name.equalsignorecase(album)) { currentalbum = new Album(); Suite à ces instructions, quel est le titre de l'album? Quelle est l'instruction qui permet de donner un titre à cet album? 11. Quel est l'intérêt de la variable done? 12. Quelles informations sont «loguées» dans la boucle? 13. Pourquoi la logique de la classe Main utilise des constantes, par exemple ALBUM? 14. (programmation) Après avoir complété le code, vous lancerez l'application (compilation, déploiement et exécution), le résultat devrait être proche de celui-ci (ne pas tenir compte du message Toast): Version du 28/03/2014 Page 7 sur 12

15. (programmation) Modifier le code afin que le message Toast renseigne le nom de l'artiste de l'album sélectionné (voir copie écran ci-dessus). 16. Remplacer le Toast par AlertDialog Plus dur : essayer d'afficher dans l'alertdialog, tous les titres d'un même artiste. Voilà, vous avez maintenant les connaissances de bases pour vous lancer dans de petits projets Android! Version du 28/03/2014 Page 8 sur 12

ANDROID 4 Lors du développement d une application, il faut bien avoir en tête que toutes les tâches consommatrices de ressources (requêtes http, calculs lourds, ) doivent désormais se faire dans un Thread (processus) séparé. En effet, le système affiche un message d erreur et ferme l application lorsque le Thread principal (appelé UI Thread) est bloqué trop longtemps. Le langage Java autorise la définition d une classe à l intérieur d une autre classe : class Englobante { int a; class Englobee{... Englobante.this.a = 12... Un des intérêts de cette notation est qu une classe interne peut avoir accès aux méthodes et attributs de la classe englobante. C'est la raison pour laquelle nous allons «englobée» notre classe TraitementTache dans notre classe principale : public class TraitementTache extends AsyncTask<String, Void, ArrayList<Album> Notre classe hérite d AsyncTask, Les trois paramètres attendus lors de la déclaration sont des types génériques dont voici la signification : Le premier est le type des paramètres fournis à la tâche Le second est le type de données transmises durant la progression du traitement Enfin le troisième est le type du résultat de la tâche Dans notre exemple, seul le troisième paramètre sera modifié, en effet on souhaite que notre classe retourne un ArrayList d'objet Album. Une AsyncTask doit obligatoirement implémenter la méthode doinbackground. C est elle qui réalisera le traitement de manière asynchrone dans un Thread séparé. Les méthodes onpreexecute (appelée avant le traitement), onprogressupdate (appelée lorsque vous souhaitez afficher sa progression) et onpostexecute (appelée après le traitement) sont optionnelles. Nous allons donc effectuer la lecture et le traitement de notre flux XML distant dans la méthode doinbackground. Lorsque le traitement sera terminé la méthode onpostexecute sera appelée, cette méthode se chargera de l'affichage de la liste. public class TraitementTache extends AsyncTask<String, Void, ArrayList<Album>> { private static final String URL_XMLRESSOURCE = "http://10.0.2.2/~stephane/xxx/xxx" ; private static final String ALBUMS = "albums"; private static final String ALBUM = "album"; private static final String ARTIST = "artist" ; private static final String TITLE = "title"; // la liste des albums en mémoire (petite liste) private ArrayList<Album> albums; protected ArrayList<Album> doinbackground(string... params) { // on obtient la liste des albums en appelant la méthode parse albums = parse(url_xmlressource) ; return albums; private ArrayList<Album> parse(string strurl) { idem android 2 private InputStream getinputstream(string strurl) { idem android2 Version du 28/03/2014 Page 9 sur 12

protected void onpostexecute(final ArrayList<Album> albums) { setlistadapter(new ArrayAdapter<Album>(MainActivity.this, R.layout.list_item, albums)); ListView lv = getlistview(); lv.settextfilterenabled(true) ; lv.setonitemclicklistener(new OnItemClickListener() { ); public void onitemclick(adapterview<?> parent, View view, int position,long id) { Toast.makeText(getApplicationContext(),"L'index de cet élément est : " + albums.get(position), Toast.LENGTH_SHORT).show(); Notre classe TraitementTache sera instanciée dans notre classe principale : public class MainActivity extends ListActivity { protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); new TraitementTache().execute(); Le résultat final : public class MainActivity extends ListActivity { protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); new TraitementTache().execute(); public class TraitementTache extends AsyncTask<String, Void, ArrayList<Album>> { protected ArrayList<Album> doinbackground(string... params) { // TODO private ArrayList<Album> parse(string strurl) { //TODO private InputStream getinputstream(string strurl) { //TODO protected void onpostexecute(final ArrayList<Album> albums){ //TODO Version du 28/03/2014 Page 10 sur 12

Projet fin d'année : Reprendre votre PPE, vous devez avoir une Table Contact (ou autre) et une Table Loisirs ( ou autre) et une Table de liason ( LoisirsContacts par exemple ). 1 - A partir de la table Contact générer un fichier XML, dont vous définirez la structure. 2 Afficher vos contacts dans une ListView Android ( la version 4 d'android serait appréciable) 3 La ListView n'affichera que les informations sommaires du contact ( nom, prénom etc...). Lorsque l'on cliquera sur un contact des informations plus complètes devront s'afficher dans une AlertDialog. 4 Prévoir également d'afficher les loisirs du contact. 4 Envisager une évolution de votre activité, comme par exemple une authentification, la possibilité de mettre à jour, d'ajouter un contact, présenter dans la ListView une photo du contact etc... A déposer sur moodle le jour de la rentrée (28 avril ) : Une archive contenant : les réponses aux questions 1 à 13 du TP la structure de votre fichier XML le code PHP permettant de générer ce fichier le code Android de votre application Exemples de réalisations possibles : Version du 28/03/2014 Page 11 sur 12

Version du 28/03/2014 Page 12 sur 12