Explorer les Livres électroniques
Catégories
Explorer les Livres audio
Catégories
Explorer les Magazines
Catégories
Explorer les Documents
Catégories
Objectif : A la fin de ce TP, les étudiants seront capables de développer une application simple
qui sera déployer sur un PDA ou un Smartphone doté du système d'exploitation linux embarqué
« Android 1», plus spécifiquement ce TP permettra à l'étudiant de découvrir certains concepts
inhérents au développement sous Android.
Il s'agit de développer un service qui consiste à présenter à l'utilisateur un écran comportant trois
boutons, chacun correspondant à un rayon (en km) de recherche. Lorsque l'utilisateur clique sur un
de ces boutons, l'application géolocalise l'appareil et affiche une google Map comportant les
emplacements des (hôtels, restaurants, ou autres cibles) dans le rayon souhaité.
Dans la première partie l'étudiant mettra en place son environnement de développement, par la suite
il réalisera l'interface Homme/Machine (IHM) de l'application telle que présentée à la figure 1. Ce
premier volet permettra d'introduire les concepts de layout, d'activité et d'intent et aussi le passage
d'un écran à l'autre au sein de l'application.
La seconde partie du TP portera sur l'interrogation d'un service web à l'aide de la méthode SAX et
sur le positionnement des objets recherchés sur une carte Google Map.
PARTIE I
pour tester l'application avant son déploiement plutard dans un PDA ou un smartphone
l'environnement de développement intègre un émulateur qu'il est nécessaire de créer en suivants les
instructions suivantes.
1) Sélectionnez Windows>>Android SDK and AVD Manager
2) Sélectionnez Virtual Devices dans le panneau gauche de la boîte de Dialogue
3) Cliquez sur New, renseignez le champ Name: par exemple My_AVD et sélectionnez pour le
champ Target : Google APIs(Google Inc.)-API Level 4
4) Cliquez enfin sur le bouton Create AVD
Maintenant l'environnement est installé et nous allons aborder la première partie du TP qui consiste
à réaliser l'IHM de l'application.
Nous allons d'abord créer un projet, pour ce faire nous exécutons l'environnement eclipse et on
clique sur File>>New>>Project...>>Android>>Android Project. Cliquez sur Next.
On appelle le projet « MonApp » (champ project name). Dans Build Target on sélectionne
« Google API » dans sa version 1.6. On remplit le champ Application name avec « Mon
Application » et Min SDK version avec la valeur « 4 » qui indique le niveau minimum d'API
requis pour notre application et le champ Package name avec « com.android.monapp ». On laisse
cochée l'option Create activity et on remplit le champ adjacent avec « MyFirstActivity » et on
clique sur Finish. Le projet est créé.
Dans le Package Explorer, on peut voir que ce projet comporte- outre les fichiers .jar de l'API
Google, trois dossiers.
Le dossier src/ contient les sources java notamment la première classe MyFirstActivity.java
de l'application.
Le dossier res/ contient les ressources (icônes, layout,..) liées au projet.
Le répertoire gen/ contient des fichiers sources Java mis à jour automatiquement par
l'environnement de développement Android.
I.3)Réalisation de l'IHM
Dans un projet Android, un écran d'action correspond à une activité. Notre application comprend
deux écrans (l'affichage du Menu et l'affichage de la carte) et donc deux activités. Une activité est
une classe héritant de la classe Activity. La classe MyFirstActivity est la première activité de notre
programme.
La classe MyFirstActivity comporte une méthode publique onCreate() qui est appelée
implicitement lors de la création de l'activité, elle s'exécute automatiquement lorsque l'écran
correspondant à l'activité apparaît à l'utilisateur.
La méthode onCreate() appelle d'abord la méthode onCreate() de la classe mère Activity pour
initialiser certains attributs internes de la classe fille MyFirstActivity
(super.onCreate(savedInstanceState)). On remarque par ailleurs que cette méthode
comporte un argument de type Bundle qui correspond à un tableau associatif évolué permettant de
transmettre des paramètres entre activités.
La méthode suivante setContentView(R.layout.main) indique au système qu'il doit utiliser le
« layout » main pour cette activité. Le layout d'une activité est un fichier XML permettant de
spécifier l'organisation des composants graphiques de l'écran correspondant. Pour savoir quel
layout utiliser dans une activité on passe un identifiant (int) à setContentView. La valeur de cet
entier se trouve dans une classe R (voir fichier gen/R.java) générée automatiquement. L'ajout de cet
identifiant à la classe R a été réalisé lorsque le layout main a été créé à l'initialisation du projet. Il
est décrit sous la forme d'un fichier XML à l'emplacement res/layout/main.xml.
Le fichier main.xml décrit au stade actuel l'interface par défaut ci-après :
Cette interface doit être modifiée en vue d'obtenir l'interface ci-dessous:
Figure 1
Question 1: Trouvez les autres types de layout disponibles dans l'environnement Android et
donnez leurs caractéristiques principales.
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
Chaque application Android possède des chaînes de caractères constantes qui sont listées dans le
fichier res/values/strings.xml. En ouvrant ce fichier on découvre le contenu ci-après:
4
Comme en CSS, les objets sont placés en position absolute ou relative , on trouve un AbsoluteLayout, un
RelativeLayout ,Etc .., Le LinearLayout à orientation verticale indique que tous les objets qu'il contient sont placés à
la suite les uns en dessous des autres.
Pour simplifier, on commence par vider main.xml de tout son contenu et on le remplace par le code
ci-après:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:id="@+id/titre"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="10sp"
android:text="@string/app_name"
android:textColor="#0f0"
android:textSize="28sp">
</TextView>
</RelativeLayout>
Les attributs :
android:layout_width="fill_parent"
android:layout_height="fill_parent"
Notamment fill_parent indique que le layout doit remplir le composant parent en l'occurence, il
s'agit du layout Android de base. Dans le RelativeLayout, on commence par afficher le titre. Pour
cela on utilise un composant TextView, on lui donne un id titre (android:id="@+id/titre"). On
précise que la largeur et la hauteur du TextView doivent s'adapter à son contenu.
android:layout_width="wrap_content"
android:layout_height="wrap_content"
On poursuit avec le texte situé entre le titre « Mon Application » et les boutons . Pour cela on insère
le composant TextView ci-après:
<TextView android:id="@+id/texteRayon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Localisation à moins de :"
android:layout_below="@+id/titre"
android:layout_marginBottom="12sp"
android:textStyle="bold"
android:layout_marginTop="20sp"
>
</TextView>
<Button android:id="@+id/btn10km"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="10 km"
android:textColor="#7f0"
android:layout_below="@+id/texteRayon"
android:width="30pt"
>
</Button>
Ensuite on place un texte explicatif à côté du bouton.
<TextView android:id="@+id/texte10km"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/btn10km"
android:text="Vous pouvez presque y aller à pied"
android:layout_toRightOf="@+id/btn10km"
android:textSize="13sp"
>
</TextView>
Nous allons maintenant mettre en oeuvre l'activité associé à l'écran que nous venons de réaliser, cela
se fait dans la classe de l'activité notamment la classe MyFirstActivity.java. On commence tout
d'abord par créer les attributs de la classe qui seront nécessaires.
On ajoute les trois boutons de l'écran et un LocationManager pour les fonctionnalités de
géolocalisation.
private LocationManager lm; /** Location Manager */
private Button btn10km;
private Button btn30km;
private Button btn50km;
private class MyLocationListener
implements LocationListener {
}
on ajoute une classe privée MyLocationListener servant à recevoir les notifications de la part du
Locationmanager lors des changements de position. Une fois les import correspondants ajoutés, il
reste une erreur . Cliquez dessous et selectionnez add unimplemented methods. Pour faciliter la
compréhension du TP, au stade actuel nous ne nous servirons de ces méthodes et nous allons les
laisser vides.
Nous allons maintenant créer un Listener sur les boutons de manière à réagir aux clics sur les
boutons de l'interface. Pour cela on crée une classe OnClickListener (ajoutez cette classe dans
classe principale ; et non dans la classe privée MyLocationListener).
}
Pour cette classe l'environnement Android signale une erreur qui résolu en cliquant sur l'erreur et en
sélectionnant add unimplemented methods. Une méthode onClick() est ajoutée automatiquement
qui s'éxécutera lors des clics utilisateurs sur les boutons. Laissons-la vide pour l'instant, nous y
reviendrons par la suite.
Il nous faut maintenant une méthode (à la classe principale *Activity) qui, à partir du bouton sur
lequel on a cliqué, retourne la rayon (nombre de kilomètres) correspondant. Cette méthode prend la
forme:
Les préliminaires sont terminés: on passe à l'mplémentation de la méthode onCreate(), sous l'appel à
setContentView().
On initialise les attributs de classe:
btn10km = (Button) findViewById(R.id.btn10km);
btn10km.setOnClickListener(btnListener);
btn30km = (Button) findViewById(R.id.btn30km);
btn30km.setOnClickListener(btnListener);
btn50km = (Button) findViewById(R.id.btn50km);
btn50km.setOnClickListener(btnListener);
Le squelette de notre application est maintenant en place, il faut maintenant implémenter le contenu
de la méthode onClick() . On remplace la ligne par :
Location loc;
loc = MyFirstActivity.this.lm.getLastKnownLocation("gps");
if (loc==null){
loc =
MyFirstActivity.this.lm.getLastKnownLocation("network");
Cet extrait de code a pour objectif de réupérer la dernière position connue du terminal Android. On
utilise pour cela la méthode getLastKnownLocation() du LocationManager défini précédemment.
Cette position est en général obtenue par le service de GPS, mais en cas de défaillance de ce
dernier, elle peut l'être depuis le service réseau.
A la suite du code précédent, on ajoute les lignes qui suivent:
if (loc != null){
Intent intent;
intent = new Intent(MyFirstActivity.this,MyMap.class);
Bundle bundle = new Bundle();
bundle.putDouble("Latitude", loc.getLatitude());
bundle.putDouble("Longitude", loc.getLongitude());
bundle.putInt("Rayon", getRayon(v));
intent.putExtras(bundle);
startActivity(intent);
}else{
Toast.makeText(MyFirstActivity.this,
"Impossible de récupérer la position",
Toast.LENGTH_SHORT).show();
}
Ici, on teste une nouvelle fois si on a finalement pu récupérer la position. Si ce n'est pas le cas, on
affiche un court message à l'utilisateur, lui indiquant qu'il n'a pas été possible de le faire. En
revanche, si la géolocalisation a fonctionné, on poursuit l'éxécution et on passe à l'activité suivante.
Concrètement comment se déroule cette dernière phase? On crée un intent 5 qui correspond à une
action à éxécuter, ce qui correspond ici au lancement d'une nouvelle activité. Comme cette dernière
n'est pas encore créée, on décide de l'appeler « MyMap » (MyMap.class). A cet intent, on fournit
des paramètres qui seront transmis à MyMap. Ces paramètres sont stockées dans un objet Bundle et
par la méthode putExtras() à l'intent, par la suite on lance la nouvelle activité en appelant
startActivity().
La première activité de notre projet est terminée. Notre projet comporte maintenant une erreur. Elle
se trouve sur la reférence à la classe MyMap.class qui correspond à la seconde activité de notre
application qui n'est pas encore implémentée. Nous allons passer à la création de la seconde activité.
5
Consulter la documentation en ligne http://developer.android.com/reference/android/content/Intent.html
On copie le code suivant dans le fichier nouvellement créé (res/layout/map.xml):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<com.google.android.maps.MapView
android:id="@+id/gmapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:enabled="true"
android:clickable="true"
android:apiKey="PUT_HERE_THE_KEY"/>
</RelativeLayout>
Ce second layout est uniquement composé d'un MapView permettant la visualisation de la Google
Map. Le seul élément nouveau ici concerne l'attribut android:apikey. La classe MapView donne
accès à des données fournies par Google Maps. Pour nous en servir, il faut accepter les Terms of
service de Google, sans quoi le MapView ne présentera qu'un écran vide. L'API key sert à vous
identifier en tant développeur ayant bien accepter les conditions d'utilisation du service. Pour
récupérer votre API key, la procédure est décrite sur la page:
http://code.google.com/intl/en/android/add-ons/google-apis/mapkey.html
Une fois obtenue, on l'utilise pour remplacer PUT_HERE_THE_KEY.
package com.android.monapp;
public class MyMap extends MapActivity {
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
}
Ajoutez les import et sauvegardez votre fichier. Comme la première activité, celle-ci comporte une
méthode onCreate(). En revanche cette classe n'hérite pas d'Activity mais de MapActivity. Cela
oblige à redéfinir la méthode isRouteDisplayed() (voir les spécifications de la classe MapActivity) à
l'adresse :
http://code.google.com/intl/en/android/add-
ons/googleapis/reference/google/android/maps/MapActivity.html
on précise dans ce code qu'on veut utiliser le layout map pour cette activité (1). On associe la vue
gmapview à l'objet mapview de type MapView (2). On recupère également le contrôleur de l'objet
mapview (3).
N.B: L'étudiant devra répondre aux questions posées dans le texte et envoyez ses réponses à
l'enseignant.
En coordonnées GPS, cela donne 2.35 et 48.86 à fournir dans cet ordre à la commen geo fix de
telnet.
Bon travail !!!