Tutoriel PDF pour apprendre la programmation sous Android pour les nuls


Télécharger Tutoriel PDF pour apprendre la programmation sous Android pour les nuls

★★★★★★★★★★3.5 étoiles sur 5 basé sur 1 votes.
Votez ce document:

Télécharger aussi :


 

Chapitre 1

Découvrir la plateforme Android

Plan du chapitre 1

 

? La plateforme Android

? L'architecture Android

? Les outils de développement

                                                                                                 © JMF (Tous droits réservés)                                 2

Android =

 

? Android = un système d'exploitation open source pour smartphones,

PDA, tablettes : systèmes légers

? = une startup rachetée en août 2005 par Google

? 5 novembre 2007, création de l’OHA (Open Handset Alliance) = un consortium créé à l’initiative de Google réunissant des entreprises opérateurs mobiles, constructeurs et éditeurs logiciels

? But de l'OHA = favoriser l’innovation sur les appareils mobiles en fournissant une plate-forme véritablement ouverte et complète

? est gratuit


 

Android et Google

 

? A suscité l'engouement des développeurs grâce à deux Android Developer Challenge en 2008 et 2009 financé par Google

? Conçu pour intégrer les applications Google : Gmail, Google Maps, Google

Agenda, YouTube et la géolocalisation

? Les différentes versions ont des noms de dessert (qui suivent l'ordre alphabétique, de A à Z) qui sont sculptés et affichés devant le siège social de Google (Mountain View)

? source :

? 1.0 : Version connue des développeurs : sortie avant le premier téléphone Android (fin 2007)

? 1.1 : Version incluse dans le premier téléphone, le HTC Dream

? 1.5 : Cupcake (Petit Gâteau), sortie en avril 2009

? 1.6 : Donut (Beignet), sortie en septembre 2009

? 2.0 (2.0.1) : A cause de nombreux bugs, remplacée par la la 2.1

? 2.1 : Eclair, sortie en janvier 2010

? 2.2 : FroYo (Frozen Yogourt : Yaourt glacé), sortie en mai 2010

? 2.3 : Gingerbread (Pain d'épice), sortie le 6 décembre 2010

? 3.0 : Honeycomb10 (Rayon de miel), sortie le 26 janvier 2011

? 4.0 : Ice Cream Sandwich (Sandwich à la crème glacée), version unifiée pour Smartphone, Tablette et GoogleTV, combinant Gingerbread et Honeycomb, sortie le 19 octobre 2011

? 4.2.2 : API 17 sortie le 11 février 2013

? Voir historique des versions et fonctionnalités de chacunes d'entre elles à

'

Android

Parts de chaque version octobre 2013

 

? Versions des machines Android qui ont accédé à Google Play (ex

Android Market) une semaine avant le 2 octobre 2013

? Voir à

Smartphone != ordinateur

 

? Android tire partie des particularités des smartphones :

? interface homme machine adapté (tactile, widget) 

? divers modes : vibreur, sonnerie, silencieux, alarme

? notifications (d'applications, d'emails, de SMS, d'appels en instance)

? de boussole, accéléromètre, GPS

? divers capteurs (gyroscope, gravité, accélération linéaire, baromètre)

? NFC, RFID

? téléphonie (GSM) et réseau EDGE, 3G

? En plus de ce qu'on peut avoir sur un ordinateur : navigateur, bibliothèques graphiques 2D, 3D (Open GL), base de données (SQLite), applications de rendu multimédia (audio, vidéo, image) de divers formats, réseau Bluetooth et Wi-Fi, caméra

Le Google Play (ex Android Market)

 

? Google Play, est une boutique en ligne créée par Google (le 6 mars 2012) par fusion des services Android Market et d'autres services Google (location de films, achat de musique, etc.). Elle permet de télécharger et d'installer de nouvelles applications ("apps") dans le smartphone

? Android market est "né" le 22 octobre 2008

? "Au 30 octobre 2012, Google Play est fort de 700 000 applications ce qui le met à égalité avec iOS" : voir historique à

? Les développeurs d'applications payantes reçoivent 70 % du prix du logiciel, 30

% allant à Google (redistribués aux développeurs via Google Checkout)

? Chaque nouveau développeur paie $25 comme frais de dossier (une seule fois)

Le SDK Android

 

? l'Android SDK (Software Development Kit) amène des outils :

? un environnement de développement

? une machine virtuelle Java adaptée : la Dalvik virtual machine

? un environnement debugueur DDMS (Dalvik Debug Monitor

Service) utilisant adb (Android Debug Bridge)

? un environnement de construction d'application Android aapt

(Android Asset Packaging Tool)

? des émulateurs de téléphones ou de tablettes AVD (Android Virtual Device)

? et une énorme API (voir à )


(1/3)

 

? Architecture en "pile logicielle"

 

(2/3)

 

? La couche "Applications" : Android est utilisé dans un ensemble contenant déjà des applications natives comme, un client de mail, des programmes pour envoyer des SMS, d'agenda, de navigateur web, de contacts personnels

? La couche "Application Framework" : cette couche permet au programmeur de construire de nouvelles applications. Cette couche fournit la gestion :

? des Views (= IHM)

? des ContentProviders = l'accessibillité aux données des autres applications (ex : les contacts) et donc les partages de données

? des ressources = les fichiers non codes comme les images, les écrans (Resource Manager)

? des Notifications (affichage d'alerte dans la barre de titre)

? des Activitys = l'enchaînement des écrans

(3/3)

 

? La couche "Libraries" (bibliothèques) = couche logicielle basse pour utiliser

? les formats multimédia : images, audio et vidéo enregistrement comme rendu

? les dessins 2D et 3D, bitmap et vectoriel

? une base de données SQL (SQLite)

? L'environnement d'exécution (Android Runtime). Toute application est éxécutée dans son propre processus, dans sa propre Dalvik virtual machine

? Le noyau Linux sur lequel la Dalvik virtual machine s'appuie pour gérer le multithreading, la mémoire. Le noyau Linux apporte les services de sécurité, la gestion des processus, etc.


La Dalvik virtual machine (DVM)

 

? Est la machine virtuelle Java pour les applications Android

? Conçu pour exécuter du code Java pour des systèmes ayant des contraintes de place mémoire et rapidité d'exécution

? Exécute du code .dex (Dalvik executable) = des .class adaptés à l'environnement Android

? Ecrit par Dan Bornstein d'où le nom (= village islandais dont sont originaires certains de ses ancêtres)

? A été choisi par Google car une machine Android peut être lancé plusieurs instance de la DVM efficacement ? Le code de la DVM est open source ? référence :

Installer l'environnement de développement Android

?

? Comme indiqué, cet ADT (Android Development Tools) délivre :

Eclipse, le SDK Android, le plug-in Eclipse vers ce SDK Android (= le ADT plugin)

? Euh Kesako ?

AVD Manager

SDK Android

 

ADT

Plugin

 

Eclipse

 

JDK Java (SE)

 

La pile des outils de développement pour Android


 

Fin de l'installation de l'environnement

 

? Après extraction de adt-bundle-windows-XXX, lancer

SDK

? Un répertoire eclipse est construit contenant une version d'Eclipse avec l'ADT plug-in initialisé correctement sur le SDK Android téléchargé

? Et c'est tout : on peut commencer à faire du développement pour Android

? Remarque :

Si vous avez une ancienne installation de l'environnement Android, celle ci peut être perturbée par cette nouvelle installation

Correspondance num Android, num API

?

?

Le AVD (Android Virtual Device) (1/2)

 

? Pour exécuter les programmes Android, il suffit d'un émulateur. C'est le AVD (Android virtual device)

? A la première utilisation il faut en obtenir un. Par la suite on pourra utiliser toujours celui là

? Dans Eclipse, on peut construire un nouvel AVD par le bouton de la barre de menu : ou bien par Window | AVD Manager

Le AVD (Android Virtual Device) (2/2)

 

? Dans la fenêtre "Android Virtual Device Manager" cliquer New

 

? Dans la fenêtre "Create new Android Virtual Device (AVD)", Donner lui un nom "parlant" puis le chercher dans la liste Target

?

Bibliographie pour ce

chapitre

 

? Le site officiel d'Android : ? Pour installer l'environnement de développement Android :


 

Chapitre 2 Développement Android

Plan du chapitre 2

 

? Les composants d'une application Android : Activity,

Service, Content Provider, Broadcast Receiver

? Les Intent

? Le manifeste :

? Développer une application Android

? Un premier programme

Concepts debase

 

? Les programmes sont écrits en Java (eh oui)

? L'Android SDK compile l'ensemble du développement (code Java, données, fichier de ressources, fichier XML) dans un paquetage Android : un .apk

? Toute une application tient dans un .apk et un .apk = une application

? Les composants fondamentaux d'une application Android sont :

Activity, Service, Content Provider, Broadcast Receiver

? Certains de ces composants communiquent entre eux à l'aide d'Intent


Activity, Service, Content Provider

? Une activité (activity) "gère l'affichage et l'interaction d'un écran" (DE). Les activités sont indépendantes les unes des autres.  Une activité est une sous classe de .Activity

? Un service (service) est un composant qui est exécuté en tâche de fond. Il ne fournit pas d'interface graphique. Exemple de service : jouer de la musique, rechercher des données sur le réseau. Un service est une sous classe de .Service

? Un fournisseur de contenu (content provider) gère des données partageables. C'est le seul moyen d'accéder à des données partagées entre applications.  Exemple de fournisseur de contenu : les informations de contact de l'utilisateur du smartphone. On peut créer un fournisseur de contenus pour des données qu'on veut partager. On récupère un fournisseur de contenu pour des données partageables en demandant le

ContentResolver cr = getContentResolver();

© JMF (Tous droits réservés)cr.laRequete(lURIDesDonnees, ); 26

ContentResolver du système et en donnant ensuite, dans les requêtes, l'URI des données. Par exemple :

Broadcast Receiver, Intent

 

? Un récepteur d'informations (broadcast receiver) est un composant à l'écoute d'informations qui lui sont destinées. Un tel récepteur indique le type d'informations qui l'intéressent et pour lesquelles il se mettra en écoute. Exemple : appel téléphonique entrant, réseau Wi-Fi connecté, informations diffusées par des applications

? L'application réceptrice d'informations (c'est à dire possédant un récepteur d'informations) n'a pas besoin d'être lancée. Si elle ne l'est pas, Android la démarre automatiquement

? Un récepteur n'est pas une IHM mais peut en lancer une (éventuellement petite : une barre de notification), ou peut lancer un service traitant l'arrivée de l'information

? Un récepteur d'informations est une sous classe de

android.content.BroadcastReceiver

? Les informations sont des Intent

Intent

 

? Un évènement (intent) est une "intention" à faire quelque chose contenant des informations destinées à un autre composant Android. C'est un message asynchrone

? Les activités, services et récepteurs d'informations utilisent les

Intent pour communiquer entre eux

? Un évènement est une sous classe de android.content.Intent

Composants applicatifs :

un résumé

 

? Activité = logique associée à un écran

? Service = opération s'exécutant en arrière plan

? Content Provider = fournisseur de contenu ! c'est à dire gestionnaire des données partageables et/ou persistentes

? Broadcast receiver = gestionnaire des messages systèmes ou applicatifs

? Intent = message indiquant une intention à faire une certaine action

Le manifeste :

 

? Toute application doit contenir le fichier XML

? Ce fichier déclare, entre autre, les différents composants de l'application. Ils doivent être fils du premier élément manifest du ce fichier XML ? Ce fichier contient aussi :

? les permissions nécessaires à l'application (accès internet, accès en lecture/écriture aux données partagées)

? le numéro minimum de la version API utilisée

? des logiciels et matériels utilisés par l'application (caméra)

? des bibliothèques supplémentaires à l'API de base (Google maps library)

? Parmi les composants, seuls les récepteurs d'évènements (broadcast receiver) peuvent ne pas être indiqués dans le manifeste. Les autres (activitys, services, content providers) doivent l'être sinon ils ne seront jamais lancés quel que soit le code écrit !

Développer une application Android

 

? De l'installation de l'environnement à la publication de l'application ? Les phases sont :

? installation de l'environnement (setup) = installer le SDK et les AVDs Android Virtual Device

? le développement = développer le code et les ressources de l'application

? débuguer et tester = DDMS et JUnit

? publier sur le Google Play

? On peut faire ces diverses phases en ligne de commande ou avec Eclipse

? source :

 

Un premier projet : Hello World

Hello World en Android

?

?


Hello World (1/4)

 

? Dans Eclipse, choisir File | New | Android Application Project

?

Hello World (2/4)

?

n'est pas exécutée)

Hello World (3/4)

 

? Cliquez Next > sur les écrans suivants pour arriver à :

 

? MainActivity sera le nom de la première classe chargée, instanciée et sur laquelle est lancée la première méthode

? activity_main est le nom de base du fichier xml d'écrivant la première IHM à afficher

? Cliquer Finish

Hello World (4/4)

?

?

?

?

?


L'activité généréeL'activité générée

 

•   Visiblement on utilise le R.java !

•   Remarque : R.java est généré par l'environnement (parfois à la première compilation) et ne devra pas être édité, contrairement au source de l'activité ci dessus

SMBXXX : Programmation Android

Le R.java généré

 

•   Des constantes dont :

•   la constante main ()

•   app_name (R.string.app_name)

•   hello (R.string.hello)

SMBXXX : Programmation Android

(1/4)

 

•   Comme indiqué en tête, il est automatiquement généré (le forcer à se générer à la première construction du projet)

•   Il y a correspondance entre les noms dans le fichier R.java et les noms utilisés dans le programme Android. Les identificateurs dans R.java font référence à des fichiers se trouvent dans le répertoire res. Par exemple indique le fichier se trouvant dans le répertoire layout (sous répertoire de res)

•   Comme décrit une interface graphique, on affecte cette IHM à une activité par setContentView();


(2/4)

   

• Les images sont accessibles par R.drawable.nomImage et corrrespondent à des fichiers images dans le répertoire res/drawable. Le fichier R.java permet d'associer un int à ce nom (de fichier)

(3/4)

 

•   Les noms sont accessibles par R.string.nom et correspondent à des chaînes de caractères dans le fichier (avec un s !) dans le répertoire res/values. On récupère ces noms dans le code source par

getResources().getString(R.string.nom);

•   Le fichier R.java permet d'associer un int à ce nom (bis)

(4/4)

 

•   Les composants graphiques ont un identifiant dans le fichier xml qui les contient (par exemple le ). Cet identifiant est la valeur de l'attribut android:id et est de la forme "@+id/leId". On récupère, dans le code, le composant graphique grâce à cet identifiant par l'appel

findViewById(R.id.leId);

•   Par exemple

Button leBouton = (Button)findViewById(R.id.leBelId);


LayoutLayout

 

Le activity_main.xmlLe généré

généré

 

•   Fichier répéré par la constante main (R.layout.activity_main)

•   argument de setContentView() dans l'activité

•   Son contenu peut être visualisé par :

           suivant l'onglet choisi                                              

= ? = ?

(suite)

(suite)

 

•   = un LinearLayout a été utilisé contenant un TextView

•   Le texte affiché par le TextView (= une zone de texte ~ Label de AWT) est la chaîne (@string) de l'élément hello du fichier

(ligne android:text="@string/hello")

 

•   L'élément hello du fichier a pour corps Hello World, MonActivite!

•   C'est la chaîne affichée dans le TextField à l'éxécution

Le manifesteLe manifeste


L'exécution (1/3)

 

? Sélectionner le projet dans l'onglet Package Explorer (clic droit), et, dans le menu contextuel Run As | 2 Android Application

 

                                                                                                                 © JMF (Tous droits réservés)                     50

L'éxécution (1/)

L'exécution (2/3)

finit par amener :

• Déplacer alors la                                glissière (c'est un smartphone !)

51 SMBXXX : Programmation Android

L'exécution (3/3)L'éxécution (2/)

 

• Apparaît alors votre application Android :

 

                                                                                                                 © JMF (Tous droits réservés)                     52

SMBXXX : Programmation Android


Application Android

 

? Pour obtenir cet "Hello World", nous avons besoin de fichiers XML de configuration (), de définitions de constantes (), d'interfaces graphiques

() en plus de programmes Java (presque) créé par le programmeur () ou par l'environnement (R.java)

? Tout cet ensemble constitue une application Android (Android app)

? Pour d'autres applications plus importantes, on aura besoin d'autres "ressources"

Des exemples d'applications Android (1/2)

 

? L'environnement Android apporte de multiples exemples d'applications

? Pour les exécuter revenir au l'écran "home" Au besoin cliquez sur :

? Cliquez ensuite sur la grille des applications :

 

Des exemples d'applications Android (2/2)

?

?

? Le code de ces applications est accessible à partir de :

%repInstalAndroidSDK%\samples\android-XXX\ApiDemos


appareil Android (1/3)

 

? Il faut avoir cocher la case "débugage USB" sur l'appareil ? L'appareil étant non connecté,

? pour une tablette Samsug Galaxy Tab,  faire Applications |

Paramêtres | Applications | Développement | Débogage USB,

? pour un téléphone Samsug Nexus S, faire Paramêtres | {}

Options pour les développeurs | Débogage USB,

? Activer le débugage USB (la case doit être cochée)

? En général cette étape est faite une seule fois

? Connecter le cable USB au PC

? Vérifier dans une fenêtre de commandes, taper

adb devices doit afficher la tablette et retourner quelque chose comme :

appareil Android (2/3)

? Dans Eclipse, se mettre dans la perspective DDMS

? Dans l'onglet Devices apparaît la tablette : la sélectionner



 

? Revenir dans la perspective Java. Lancer le programme (Run As après avoir sélectionné le projet). La sortie est sur la tablette

? Remarque : sous Linux c'est un peu plus délicat voir à

appareil Android (3/3)

 

? Si on n'arrive toujours pas à lancer l'application sur un vrai smartphone, cliquer doit sur le projet puis Run As | Run Configurations

? Sélectionner l'application sous Android, puis l'onglet Target, et sélectionner l'option Manual

? A la prochaine exécution il sera demandé la machine (virtuelle ou pas) d'exécution, plutôt que le lancement automatique


smartphone (1/3)

 

? En général, si la case Débogage USB est cochée, lorsque le cable USB entre le smartphone et l'ordinateur est mis, tout devrait bien se passer, l'ordinateur et Eclipse finisse par trouver le smartphone

? Si ce n'est pas le cas, vérifier que le gestionnaire d'USB Driver est bien installé dans le SDK : on doit avoir :

? source :

smartphone (2/3)

 

? Si vous êtes sous windows, voir ensuite à l'URL

#InstallingDriver ? Les principales étapes sont :

? Connecter le smartphone à l'ordinateur

? Sélectionner l'icône de l'ordinateur, cliquer droit, et sélectionner Gérer

? Sélectionner Gestionnaire de périphériques dans le panneau gauche, puis Autres périphériques dans le panneau droit

smartphone (3/3)

 

? Cliquer droit sur l'icône du smartphone puis l'item "Mettre à jour le pilote"

? Dans la nouvelle fenêtre cliquer sur "Rechercher un pilote sur mon ordinateur"

? Aller le chercher dans

RepInstallAndroid%\extras\google\usb_driver\

? Cliquer le bouton Suivant


Pour désinstaller une application

 

? Sélectionner l'application (en laissant le doigt sur son icône) puis la glisser sur Uninstall. Confirmer la désinstallation (2 fois OK !)

? Une autre solution :

? Choisir bouton Menu | Settings (ou Paramêtres) | Applications |

Manage Applications (ou Gérer les applications)

? Choisir l'application à désinstaller

? Cliquer sur bouton Uninstall (ou Désinstaller)

? Cliquer OK

? Cliquer OK ? C'est fini !

Bibliographie pour ce chapitre

 

? Pour ce chapitre

 

Chapitre 3

Les interfaces utilisateurs avec Android


Les IHM des smartphones

 

? Pas seulement clavier écran

? Mais écran tactile

? Accéléromètre

? GPS

? Enregistrement de messages audio (notes audio)

? Prendre des photos, des vidéos, les envoyer par le réseau (MMS)

? SMS

? Téléphone

Les IHM avec Android

 

? Bibliothèque propre

? Pas AWT, ni Swing, ni Java ME / LCDUI

? Décrit par fichier XML

? Ecran en Android géré par une activité

Activité (Activity)

 

? Correspond à une seule classe Java

? Une activité gère l’affichage et l’interaction d’un unique écran (IHM) ou fenêtre flottante

? Gère les événements, lance l'affichage d'autres écrans, lance du code applicatif

? Suit un cycle de vie déterminé (cf. applets, midlets, servlets, EJB, )

? Crée des Intent pour appeler d'autres activités

Construction d'une IHM

 

? Plutôt en XML mais

? XML ne peut pas être déboggué !

? Tout ne peut pas être fait en XML


(1/4)

 

(2/4)

 

(3/4)

(4/4)

(Premier principe) : construire une IHM, s'est mettre des composants graphiques les uns à l'intérieur des autres

Il y a donc, dans une IHM à présenter à l'utilisateur, un arbre de composants graphiques

Les éléments de cet arbre sont des composants graphiques (redite !)

Etre "fils de" dans cet arbre signifie "être contenu dans"

Voilà pour les composants graphiques ! (et le premier principe des

IHM)


Second principe des IHM (1/3)

 

? Les ensembles de composants graphiques sont des classes. On aura la classe des boutons, la classe des cases à cocher, etc.

? Un composant graphique particulier sera une instance particulière d'une classe. Par exemple le bouton "Quitter" et le bouton ''Sauvegarder" d'une IHM seront deux instances de la classe des boutons : merci l'OO !

? Il y a une famille de conteneurs et une famille de non conteneurs

? D'où les classes de composants graphiques :

? Question : Comment sont rangées ces classes ?

? Réponse : dans un arbre d'héritage de classe : merci l'OO (bis) !

Second principe des IHM (2/3)

 

? Plus précisément le point de départ de l'arborescence des classes est :

 

? C'est le design pattern Composite

? remarque : travailAFaire() est répercutée sur tout l'arbre des instances

Second principe des IHM (3/3)

(Second principe) : les bibliothèques pour construire des IHM sont, en Java, (et souvent !) des classes rangées par arborescence d'héritage

Les éléments de cette arborescence sont des classes (redite !)

Etre "fils de" dans cette arborescence signifie "hérite de"

Voilà pour les classes (et le second principe des IHM)

Les deux principes des IHM

 

? Lorsqu'on parle d'IHM, il existe deux arborescences et donc deux "principes"

? 1er principe : Une IHM est construite en mettant des composants graphiques les uns à l'intérieur des autres

? 2ième principe : les composants graphiques sont obtenus comme instances de classes. Ces classes sont rangées dans une arborescence d'héritage

? Remarque : Ces deux arbres (celui des composants graphiques et celui des classes) ont peu de choses à voir l'un l'autre

? Le premier est l'architecture de l'interface i.e. le placement des divers composants graphiques les uns par rapport aux autres,

? le second est un arbre d'héritage de classes donné une bonne fois par le concepteur de la bibliothèque graphique

Un composant IHM  =

3 parties

 

? Un composant graphique a 3 parties :

? les données qu'il représente : le modèle (model)

? le dessin d'affichage : la vue (view)

? ce qui prend en charge les actions de l'utilisateur sur ce composant : le controleur (controler)

? C'est l'architecture MVC

? "L'idée est de bien séparer les données, la présentation et les traitements" (*)

? Les traitements sont souvent délégués à un objet autre que le composant graphique lui même (et qui n'est pas, en général, un composant graphique) : programmation par délégation

? (*) source :

Les fondamentaux d'Android

 

? La classe "Noyau" de base est la classe (~ .Component de AWT)

? La classe de base des conteneurs est .ViewGroup

(~ .Container de AWT) ? On a donc : 

? En Android, les conteneurs sont souvent appelés les Layout, les contrôles sont parfois appelés des widgets (window objects)

IHM : construction procédurale vs. déclarative

 

? En Android on peut construire les IHM en codant en Java des instructions

? ou en décrivant l'IHM par un fichier XML

? La première solution est celle habituelle de Java (SE Swing et AWT,

ME) ou d'autres domaines (Motif, Openwin de Sun, )

? La seconde est courante dans certains domaines (NeXT, )

? La bonne nouvelle : on peut construire la plupart des IHM en glisser déposer cf. Interface Builder de NeXT : Jean-Marie Hullot (1989) , Visual Basic,

Un second programme

 

? On veut créer un programme qui affiche un bouton. Lorsque l'utilisateur actionne le bouton, l'heure est affichée. Le résultat est :

? L'heure est mise à jour lorsqu'on actionne le Bouton


Code du second programme (1/2)

 

? On peut tout coder en Java dans l'activité :

package ;

import .Activity; import .Bundle; import ; import android.widget.Button; import ; public class BoutonHeureActivite extends Activity implements View.OnClickListener

{ private Button btn;

@Override public void onCreate(Bundle icicle) { super.onCreate(icicle); btn = new Button(this); btn.setOnClickListener(this); updateTime(); setContentView(btn);

} public void onClick(View view) { updateTime();

}

private void updateTime() { btn.setText(new Date().toString());© JMF (Tous droits réservés) 81

}

}

Code du second programme (2/2)

 

? L'activité est le listener du bouton :

public class BoutonHeureActivite extends Activity implements View.OnClickListener

? Ce qui nécessite d'implémenter la méthode :

public void onClick(View view) qui est lancée lorsqu'on actionne le bouton (technique des listeners cf. événement Java SE)

? Le bouton est mis dans l'activité (setContentView(btn))

autre solution (1/5)

 

? En général, pour l'IHM on utilise plutôt les fichiers XML

? Créer une nouvelle application Android

? Ouvrir le (dans ). Uniquement des caractères a-z, 0-9 et _ pour les noms de fichiers sous

res\layout

? Et on peut construire l'IHM en glisser déposer !

 

autre solution (2/5)

?

?

?

?

?

Designer

autre solution (3/5)

?

?

?

autre solution (4/5)

?

?

? source :

autre solution (5/5)

 

? L'IHM est alors généré cf. les deux onglets du :

 

Correspondance attribut méthode

 

? Pour positionner une propriété (= valeur d'attribut = données = ) d'un composant graphique on peut le faire soit en XML soit par appel d'une méthode appropriée

? Dans le fichier XML, on positionne une propriété d'un composant graphique à l'aide d'une valeur d'attribut d'une balise XML

? Donc il y a une correspondance entre les noms d'attribut d'une balise XML et une méthode, pour positionner une propriété d'un composant graphique. On a, par exemple :

 

à

Identifier les composants = la méthode "miracle"

 

? Le fichier repère les composants par android:id

 

? Dans cet exemple il s'agit de Button01

? Le composant est manipulé par cet identifiant dans le programme Java à l'aide de la méthode ("miracle")

findViewById(R.id.nomIdentifiant);

? La valeur nomIdentifiant est celle qui apparaît dans le fichier après @+id/

? Pour cet exemple ce sera findViewById(R.id.Button01);

Second programme, solution 2 : le code

 

? Comme toute l'IHM est faite dans le , voici le code de l'activité :

package ; import ;

import .Activity; import .Bundle; import ; import android.widget.Button;

public class BoutonHeure2Activite extends Activity implements View.OnClickListener { private Button btn;

@Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(); btn=(Button)findViewById(R.id.Button01); btn.setOnClickListener(this); updateTime();

} public void onClick(View view) { updateTime();

} private void updateTime() { btn.setText(new Date().toString());

                }                         © JMF (Tous droits réservés)                                                     90

}

Les Layout

 

? Les containeurs Android sont souvent des XXXLayout !

? C'est un peu différent de Java AWT ou Swing. Un Layout Android est un container et un Layout AWT à la fois

? Les principaux Layout Android sont :

? LinearLayout (~ un containeur AWT géré par un FlowLayout AWT)

? RelativeLayout

? AbsoluteLayout (déprécié depuis l'API 3 !) ? On a donc :


LinearLayout

 

? Les composants à l'intérieur d'un LinearLayout sont rangés les uns à la suite des autres horizontalement ou verticalement

? Principales propriétés d'un LinearLayout : l'orientation, le mode de remplissage (fill model)

Orientation d'un

LinearLayout

 

? L'orientation indique si le LinearLayout présente ces contenus sur une ligne (horizontalement) ou sur une colonne (verticalement)

? La propriété d'orientation à utiliser pour un LinearLayout dans le fichier XML est l'attribut android:orientation de la balise

LinearLayout. Les valeurs possibles pour cette propriété sont vertical et horizontal

? La valeur vertical indique que les contenus seront les uns en dessous des autres, la valeur horizontal indique qu'ils seront les uns à la suite des autres

? L'orientation peut être modifiée à l'éxécution par la méthode setOrientation() lancée sur le LinearLayout en précisant la valeur LinearLayout.HORIZONTAL ou

LinearLayout.VERTICAL

Mode de remplissage (fill model) d'un LinearLayout

 

? Cela concerne les attributs android:layout_width et android:layout_height à positionner sur les composants graphiques contenus dans le LinearLayout

? Les valeurs possibles de ces propriétés peuvent être :

? une valeur exacte de pixel (125px pour 125 pixels) : c'est fortement déconseillé

? wrap_content qui indique que le composant prend la taille qu'il faut pour s'afficher correctement entièrement

? fill_parent (renommé match_parent

après l'API 8) indique que le composant remplit complètement la dimension indiquée du LinearLayout

Les contrôles Android

 

? Ce sont les composants graphiques que voient l'utilisateur, avec lesquels il agit sur (contrôle) l'interface graphique

? Appelés dans certains domaines, les contrôles ? En Android ce sont (par exemple) :

? les zones de texte non éditable (~ Label AWT) ou éditable (~

TextComponent AWT) : TextView

? les boutons  (~ Button AWT) : Button

? les zones de texte éditables (~ TextField et TextArea de

AWT) : EditText 

? les cases à cocher (~ Checkbox AWT) :  CheckBox et les boutons radio RadioButton à regrouper dans un ensemble

? Toutes ces classes sont dans le package android.widget et dérivent de

Arborescence des principaux contrôles Android

 

? Les classes de composants non conteneurs (contrôles) sont rangées dans l'arbre d'héritage :

TextView

 

? Peut servir de zone de texte non éditable (~ Label AWT) et dans ce cas, sert souvent pour présenter les widgets qui suivent ? Propriétés importantes :

? android:text : le texte du TextView

? android:typeface : le type de police utilisée

(monospace, )

? android:textStyle : le style (italic pour l'italique, bold_italic pour gras et italique, )

? android:textColor pour la couleur d'affichage du texte.

Les valeurs sont en hexadécimal en unité RGB (par exemple

#FF0000 pour le rouge)

?

Arborescence des composants graphiques dans une IHM

? Faire une IHM c'est mettre des composants dans des composants dans des composants On peut le faire par programmation en utilisant addView(View) d'un ViewGroup ou dans un fichier XML ? Par exemple le fichier :

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="; android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" >

    <TextView android:id="@+id/text"               android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello, I am a TextView" />

<Button android:id="@+id/button"

android:layout_width="wrap_content"             android:layout_height="wrap_content" android:text="Hello, I am a Button" />

</LinearLayout>

= un TextView et un Button dans un LinearLayout représente l'IHM :


Une conclusion : les 3 principaux fichiers XML

 

? Les 3 (types de) fichiers xml : les fichiers sous layout,

values\,

? Les fichiers sous layout sont les fichiers xml décrivant des (parties) d'IHM

? Le fichier values\ contient des valeurs de chaines de caractères

? Le fichier contient la configuration de l'application Android (sa description, ses demandes d'autorisation, etc.)

 

 

 

Si problème avec leR.java

 

? Envisager les traitements suivants :

? 1°) faire File | Refresh et/ou Project | Clean dans Eclipse

? 2°) Vérifier les fichiers XML sous res

? 3°) Enlever import android.R; dans le code

? 4°) Détruire le fichier R.java et attendre qu'il se reconstruise

La gestion des événements

 

? Deux moyens :

? 1°) créer un auditeur d'événements (classe qui implémente une interface connue) et l'enregistrer auprès du composant (View)

? 2°) les View sont elles mêmes auditrices de certains événements : (touché de l'écran). Spécialiser la méthode adaptée et lancée lorsque l'événement survient

? 1°) est classique (Java SE, Java ME). Les interfaces sont des interfaces internes à la classe View et de nom OnXXXListener (donc des interfaces de nom View.OnXXXListener). Cela nécessite d'implémenter une méthode de nom onXXX(). On enregistre un auditeur par

setOnXXXListener(View.OnXXXListener l)

? 2°) permet d'écrire directement la gestion de certains événements qui peuvent se produire dans la View

Créer un auditeur d'événements : exemple

 

? Le code peut être :

private OnClickListener lAuditeurDuBouton = new OnClickListener() {     public void onClick(View v) {

      // code lancé lorsque le bouton est cliqué

    } };

protected void onCreate(Bundle savedValues) {

   

    // Récupération du Button à partir de l'IHM en XML

Button button = (Button)findViewById(R.id.leBeauBouton);

    // Enregistrer l'auditeur auprès du bouton     button.setOnClickListener(lAuditeurDuBouton);    

}

Méthodes lancées par les auditeurs d'événements

 

? onClick() (de View.OnClickListener) est lancée lorque l'utilisateur touche le composant graphique, ou après appui sur enter alors que le composant a le focus

? onLongClick() (de View.OnLongClickListener) : idem que si dessus mais après un appui de plus de 1 seconde

? onKey() (de View.OnKeyListener) est lancée après appui et relachement d'un touche clavier

? onTouch() (de View.OnTouchListener) est lancée pour toute action de toucher (appui, relachement, mouvement de l'utilisateur sur l'écran)

? onCreateContextMenu() (de

View.OnCreateContextMenuListener) est lancée après création d'un menu contextuel

"Enchaîner" les écrans (1/3)

 

? Pour passer d'un écran à un autre, il faut écrire le code

Intent i0 = new Intent(this, NouvelleActivity.class); //1 startActivity(i0);

et déclarer la nouvelle activité NouvelleActivity.class (le futur écran) dans

? public void startActivity (Intent intent) est une

méthode de la classe Activity permettant de lancer une autre Activity. intent est l'Intent (l'intention) qui prépare ce lancement

? Remarque : le premier argument du constructeur de l'Intent doit être le Context. Si l'appel est fait dans une Activity, this convient car Activity dérive de Context

? On utilise souvent quand on est dans un listener d'événement. Sinon, la méthode getApplicationContext() convient souvent

"Enchaîner" les écrans (2/3)

?

?

"Enchaîner" les écrans (3/3)

 

? Une nouvelle Activity apparaît dans la liste. Indiquer son nom complet de classe (après Name:). Si cette classe est dans le même paquetage que l'activity qui la lance écrire .NouvelleActivity (ce nom suffixera le nom du paquetage courant)

 

? Vérifier que tout s'est bien passé dans l'onglet . Il doit y avoir la ligne

<activity android:name=".AProposActivity"></activity>

 

? Euh, il suffisait de n'écrire que cela !

Créer une nouvelle activité

 

? Dans un projet, on peut créer une nouvelle activité comme indiqué dans les diapos précédentes : écrire une classe dérivant de

Activity, redéfinir les méthodes onCreate(), et déclarer cette activité dans l'



? Avec le nouvel environnement de développement, si on utilise New | Other , en complétant les écrans qui suivent, l'activité est en partie créée et sa déclaration dans l' aussi !

Passer de données entre activité grâce aux Intent

 

Intent i = new Intent(leContexte, MapStationActivity.class);

i.putExtra("latitude", latitudeDuPointCourant);

i.putExtra("longitude", longitudeDuPointCourant); startActivity(i);

? Les Intent servent parfois d'enveloppes pour passer des informations d'une Activity à une autre. On utilise pour cela une des méthodes public Intent putExtra(String nomDeLExtra, unType valeur) ? Par exemple :

? Dans une Activity, on récupére l'Intent qui a lancé l'Activity par getIntent(). On peut alors récupérer tous les extras de l'Intent par getExtras(), et, par la suite, un extra associé à une entrée par

getTypeEntrée(nomEntrée, valeurParDefaut),

double laLatitudeDeLaStation = getIntent().getExtras().getDouble("latitude", 0);

valeurParDefaut est la valeur retournée si il n'y a pas d'extra associé à nomEntrée dans l'Intent ? Par exemple :

Un simple avertissement :

Toast

 

? Une fenêtre de dialogue qui affiche un message pendant 2

(Toast.LENGTH_SHORT) ou 5 (Toast.LENGTH_LONG) secondes est un composant graphique Android : le Toast

? On le construit et on l'affiche avec le code

Toast leToast = Toast.makeText(leContexte, "texteAAfficher", Toast.LENGTH_LONG); ();

? Les méthodes qui construisent le Toast sont les méthodes statiques : public static Toast makeText (Context context, int resId, int duree) ou

public static Toast makeText (Context context, CharSequence text, int duree)

context est le contexte à utiliser. En général on passe l'activité courante text est la chaîne de caractères à afficher resId est l'id de la chaîne à afficher

(à définir dans ) duree est la durée d'affichage LENGTH_SHORT ou LENGTH_LONG

? Attention construire le Toast ne l'affiche pas : il faut utiliser show() pour cela


Code de "trace" en Android

 

? La classe propose plusieurs méthodes de trace (de Log) hierarchisées. Ces méthodes ont pour nom une seule lettre. Ce sont, dans l'ordre les méthodes v() (verbose), d() (debug), i() (information), w() (warning) et e() (erreur)

? Ces méthodes ont deux arguments : (String tag, String msg)

@Override public boolean onOptionsItemSelected(MenuItem item) {

// Handle item selection switch (item.getItemId()) { case R.id.new_game:

         Log.v("JMF", "Une nouvelle partie ?");        Log.d("JMF", "Une nouvelle partie ?");

Log.i("JMF", "Une nouvelle partie ?");

Log.w("JMF", "Une nouvelle partie ?");

Log.e("JMF", "Une nouvelle partie ?"); return true; //

}

} © JMF (Tous droits réservés)                                                    114

? Elles permettent de visualiser des traces lors de l'exécution en utilisant la perspective DDMS. On peut filtrer ces traces en ne laissant afficher que les log de balise tag

? Par exemple le code :

permet de voir les sorties dans la perspective DDMS

Traces (log) enAndroid

 

? Dans l'onglet LogCat de la perspective DDMS, on peut créer des filtres de balises et ne faire afficher que les traces associées à ces balises

 

? On indique le niveau de trace : le niveau verbose affichera toutes les traces de cette balise (cf. ci dessus), le niveau info n'affichera que les trace info, warning et erreur (cf. ci dessous)

 

Bibliographie pour ce chapitre

 

? Pour ce chapitre

? The Busy Coder's Guide to Android Development, Mark L. Murphy ; editions CommonsWare

? Android Application Development, Rick Rogers, John Lombardo, Zigurd Mednieks and Blake Meike ; editions O'Reilly, 2009 

 

Chapitre 3 bis

Les interfaces utilisateurs avancés avec Android


Composants IHM avancés

 

? Certains composants graphiques permettent d'afficher beaucoup d'items par des mécanismes de défilement. Ce sont :

? les Spinner, les Gallery, les GridView, les ListView

 

? Il y en a d'autres. Voir à Apis Demos | Views

AdapterView et Adapter

? Les composants graphiques qui affichent un ensemble d'items sont des AdapterViews

? Ces composants sont très utiles si les données qu'ils affichent ne sont pas connues à la création du programme mais seront chargées dynamiquement

? Pour fournir les items à ces composants graphiques, on utilise des

Adapter

? Comme AdapterView est en fait AdapterView<T extends android.widget.Adapter>, un AdapterView est toujours associé à un Adapter

? L'Adapter sert de lien avec les données à afficher et l'AdapterView. Bref c'est le design pattern adapter

? Les AdapterView gèrent l’affichage de ces items

AdapterView, Adapter et compagnie! (1/2)

 

? android.widget.AdapterView<T extends

android.widget.Adapter> est une classe abstraite générique

? android.widget.Adapter est une interface. Beaucoup de classes implémentent cette interface : ArrayAdapter<T>, BaseAdapter

? SpinnerAdapter et ListAdapter sont des interfaces qui héritent de Adapter

? Spinner, Gallery, GridView, ListView sont des sous classes concrètes d'AdapterView

? L'association entre un AdapterView et un Adapter est faite à l'aide de la méthode

public void setAdapter (T adapter)

? Question : Où est indiqué que le paramêtre T est un type implémentant Adapter ?

? Réponse : Dans la définition de la classe AdapterView


AdapterView, Adapter et compagnie! (2/2)

?

Tutoriaux pour les

AdapterView

 

? Beaucoup de documentation existe pour les AdapterView

? Dans la documentation "officielle", on a des tutoriaux sur ces composants à partir de la définition de leur classe :

? Spinner :

? Gallery : est, en fait, dépréciée à partir de l'API 16. Il faut utiliser des

HorizontalScrollView et des ViewPager ? GridView :

? ListView :

Le composant ListView

?

?

?

? Une ListView est un AdapterView qui est

"a view whose children are determined by an Adapter." (**)

? sources : (*)

(**) © JMF (Tous droits réservés)        et/AdapterView.ht123 ml


 

Le composant ListView

 

? Il permet d'afficher une (grande) liste d'items, accessible par défilement mais aussi par filtre : l'utilisateur tape les premières lettres, le ListView n'affiche plus que les items qui commencent par ces lettres

? Pour définir un ListView, on commence par indiquer comment sera affiché chaque item du ListView. Par exemple sous forme de

TextView. On construit donc le fichier :

<?xml version="1.0" encoding="utf-8"?>

<TextView xmlns:android="; android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="10dp"     android:textSize="16sp" >

</TextView>

? Une démo : projet HelloListView

L'activité ListActivity

 

? Une ListView peut occuper tout l'écran. Dans ce cas, elle peut être construite à partir d'une .ListActivity (qui hérite de .Activity)

? Lorsqu'on construit une classe qui hérite de ListActivity, on peut alors utiliser plusieurs méthodes de la classe ListActivity :

? public ListView getListView() qui retourne le composant graphique ListView associé à cette activité

? public void setListAdapter(ListAdapter adapter)

positionne le ListAdapter associé à la ListView de cette activité ListActivity

? Et on spécialise la méthode onCreate() (comme d'hab) et on a une

Activity qui présente une ListView

public class HelloListViewActivity extends ListActivity {     /** Called when the activity is first created. */

@Override public void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState); setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, COUNTRIES));

  ListView lv = getListView(); lv.setTextFilterEnabled(true);

lv.setOnItemClickListener(new OnItemClickListener() {     public void onItemClick(AdapterView<?> parent, View view,         int position, long id) {

      // le code lancé lors de la sélection d'un item

    }   }); } static final String[] COUNTRIES = new String[] { }

}

ListView : 1er exemple à l'aide de ListActivity


 

ArrayAdapter<T> pour

ListView

?

?

car :

item

objects est le tableau de données à afficher

? La ListView construite à partir de l'activité et récupérée par getListView(), est sensible à la sélection par préfixe grâce à l'appel

setTextFilterEnabled(true);

Views "standards" pour les items d'une ListView

 

? Le second argument du constructeur ArrayAdapter est l'identificateur du fichier xml décrivant l'aspect de chaque item de la ListView (aspect qui peut être ensuite enrichi par la programmation)

? Certains de ces aspects sont donnés par android lui même ce sont : android.R.layout.simple_list_item_1 et android.R.layout.simple_list_item_2

? Si, dans le programme précédent, on remplace par  R.layout.list_item (notre propre fichier XML)  par android.R.layout.simple_list_item_1

(une des IHM standard d'android), on obtient :

L'aspect

android.R.layout.simple_list_item_1

 

? Il y a peu de différence avec notre

? En fait le fichier associé à l'identificateur

android.R.layout.simple_list_item_1 est :

<TextView xmlns:android="; android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content"     android:textAppearance="?android:attr/textAppearanceLarge" android:gravity="center_vertical" android:paddingLeft="6dip" android:minHeight="?android:attr/listPreferredItemHeight" />

? Voir à REP_INSTALL_ANDROID\android-sdk\platforms\androidXXX\data\res\layout\

? Ce fichier est encodé dans

? Bref les items sont des TextView

La "UI Thread" (1/2)

 

? Lorsqu'une application Android est lancée, un seul processus est créé qui contient une seule thread pour l'application

? Cette thread est dite la thread principale

? Elle s'occupe, entre autre, de l'affichage et de l'interaction sur les divers écrans

? Voilà pourquoi cette thread principale est appelée la UI Thread (User Interface Thread) : "As such, the main thread is also sometimes called the UI thread." ? source :

La "UI Thread" (2/2)

 

? De plus, dans une application Android, il existe une et une seule thread qui gère l'interface graphique : la UI Thread (User Interface Thread)

? Tout ce qui concerne l'affichage est (et doit être) géré par cette Thread. Si une autre Thread s'occupe de faire de l'affichage graphique, il y a erreur à l'exécution

? Lorsqu'un travail demandant du temps est lancé, il faut le faire dans une Thread autre que la UI Thread. Au besoin en créé une !

? Mais lorsque autre thread demande à afficher dans l'IHM, cette autre thread doit contacter l'UI Thread !

? Au lieu de créer de telles threads et de les gérer, Android propose une classe qui gère correctement cela. C'est la classe (générique !)

.AsyncTask<Params, Progress, Result>

La classe

.AsyncTask<Params, Progress, Result>

 

? Elle est faite pour gérer correctement la gestion entre une thread (de traitement long) et la UI Thread

? Elle permet de lancer un traitement en arrière plan et de mettre à jour (éventuellement de temps en temps) l'interface graphique de l'application

? Les paramètres génériques sont utilisés pour :

? Params : le type des paramètres nécessaires à la tâche en arrière plan

? Progress : le type des paramètres reçus par la méthode de mise à jour

? Result : le type du résultat retourné par la tâche en arrière plan

Les méthodes de AsyncTask<Params, Progress, Result> (1/2)

 

? Cette classe contient 4 méthodes dont trois d'entre elles sont exécutées dans la UI Thread. Ce sont :

protected void onPreExecute () protected void onProgressUpdate (Progress values)

protected void onPostExecute (Result result) qui sont exécutées dans la UI Thread et

protected abstract Result doInBackground

(Params params) lancée dans une autre thread

? onPreExecute() est exécutée avant le lancement de la tâche d'arrière plan

Les méthodes de AsyncTask<Params, Progress, Result> (2/2)

 

? doInBackground(Params ) est lancé après onPreExecute() dans une thread autre que la UI Thread : c'est le traitement en arrière plan. Les paramêtres de type Params sont passés à cette méthode. Cette méthode retourne un résultat de type Result (qui sera exploité par onPostExecute(Result))

? Cette méthode peut lancer publishProgress(Progress ) qui permet de lancer onProgressUpdate(Progress ) dans la UI Thread et mettre ainsi à jour l'IHM de l'application, tout en continuant la tâche en arrière plan

? onPostExecute(Result) est lancée après la fin de la tâche en arrière plan. Cette méthode reçoit le paramêtre de type Result qu'a renvoyé doInBackground(Params )

Utilisation de

AsyncTask<Params, Progress, Result>

 

? Pour utiliser cette classe, il faut la sous classer, construire une instance de cette sous-classe et lancer la méthode execute(Params ) sur cette instance

? Il faut au moins redéfinir la méthode doInBackground(Params ) (bon sens !)

? La sous classe créée est souvent une sous-classe interne à une méthode

? La création de l'instance de cette sous classe doit être faite dans la UI

Thread et execute(Params ) doit être lancée sur cette instance une seule fois dans la UI Thread

? Les méthodes onPreExecute(), doInBackground(Params ), onProgressUpdate(Progress ), onPostExecute(Result) ne

doivent pas être lancées explicitement : c'est la méthode execute() qui déclenche le tout

Exemple de code de

AsyncTask<Params, Progress, Result>

 

class ChargementDesStationsTache extends AsyncTask<String, String, String> {       protected void onPreExecute() {

progress = (, getResources().getString(R.string.app_name), getResources().getString(R.string.chargement_message),             true);

      }

protected String doInBackground(String urls) {

        // charger les stations         try {

sp = new StationsParser(getBaseContext());

        } catch (Exception e) { e.printStackTrace(); }

leStationsAdapter = new StationsAdapter(getBaseContext(),

, sp.getArrList()) ;

return null;

}       protected void onProgressUpdate(String aAfficher) { }

protected void onPostExecute(String result) {

        // arréter le progressDialog         progress.dismiss();

// mettre à jour la ListView des stations listing.setAdapter(leStationsAdapter);

      }     } new ChargementDesStationsTache().execute();


Configuration de l'AndroidManifest.xml

? Comme l'application demande à utilliser l'internet, il faut l'indiquer dans le fichier par :

<uses-permission android:name="android.permission.INTERNET" /> fils de l'élément manifest

? Comme l'application va utiliser une nouvelle Activity, il faut l'indiquer dans le fichier par :

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android= >

<uses-permission android:name="android.permission.INTERNET" />    

    <application 

<activity android:name=".ListingDesStationsActivity" />

    </application>

</manifest>

<activity android:name=".ListingDesStationsActivity" /> fils de l'élément application ? Par exemple :

                                                                                                           © JMF (Tous droits réservés)                       138

 

Fin

                                                                                                           © JMF (Tous droits réservés)                       139



6