TD/TP 1
Introduction au SDK d’Android
1 Introduction
Android est un système d'exploitation pour téléphone portable de nouvelle génération développé par Google.
Celui-ci met à disposition un kit de développement (SDK) basé sur le langage Java. Ce Cours/TD va vous expliquer comment installer ce SDK et vous présenter un exemple d'utilisation au travers le développement d'une application de type "Helloworld" ainsi que d’applications plus complexes.
Démarrer la machine sous Windows7.
Tout ce dont vous avez besoin pour ce TP se trouve sur C:\Android
Dans les sous répertoires, vous trouverez Eclipse prêt à fonctionner, un répertoire « dev » pour faire vos développements et le SDK Android.
Le SDK est déjà installé et à jour !!!! mais voici la démarche à suivre si vous souhaiter l’installer chez vous.
2 Installation
2.1 Installation du SDK
Basé sur le langage Java, le SDK Android nécessite d'avoir un compilateur JAVA. Un JDK (5 ou 6) doit être installé sur sa machine.
JDK disponible :
- http://www.oracle.com/technetwork/java/javase/downloads/index.html
Le SDK Android est disponible :
- http://developer.android.com/sdk/index.html
Sous windows :
Vous n’avez qu’à suivre les instructions de l’installeur
Sous Linux :
Editez votre fichier ~/.bash_profile ou ~/.bashrc et cherchez la ligne définissant le PATH afin d'y ajouter le chemin /tools. Si cette ligne n'existe pas, ajoutez celle-ci : export PATH=${PATH}:/tools. Vous pouvez également taper directement cette commande dans une fenêtre shell mais celle-ci ne sera alors valide que pour ce shell (et ces fils). Il vous faudra donc ressaisir la commande si vous fermez votre shell.
Sous Max :
Je n’ai pas testé.
2.2 Eclipse
Il y a deux solutions pour développer simplement avec les outils fournis par Google pour son SDK Android, soit utiliser l’IDE Eclipse soit utiliser Ant avec ou sans IDE. Netbean utilisant Ant par défaut pour ses différentes tâches (compilation, build, …), il est donc simple d’utiliser également Netbeans pour développer sous Android.
Dans ce TD/TP nous allons nous limiter à Eclipse. Le plugins Eclipse pour Android s’appelle ADT.
2.2.1 Installation d’Eclipse
Eclipse est installé sur votre machine : c:\Android\Eclipse
Sinon, rendez vous à l’adresse http://www.eclipse.org/downloads/ et téléchargez la version « Eclipse IDE for Java Developers ». Extrayez l’archive et exécutez Eclipse.
Attention, afin de passer à travers les proxy avec ou sans authentification vous devez paramétrer Eclipse :
Eclipse/Windows > Preferences > general > Network Connections
Active Provider : Manual
Remplissez les variables HTTP et HTTPS
Proxy by pass : Par example : « *.univ-lr.fr » pour éviter d’utiliser le proxy pour les adresses internes à l’ULR.
Adresse du proxy de l’ULR : http://wwwcache.univ-lr.fr
Port du proxy : 3128
2.3 Plugin Eclipse
Sachez que Google fournit un plugin pour cet IDE nommé Android Development Tools (ADT), sur votre machine, le plugin ADT est déjà installé !!! Mais voici la démarche pour l’installer chez vous :
Voici la marche à suivre pour installer ce plugin sur Eclipse :
• Démarrez Eclipse puis sélectionnez le menu Help > Software Updates
• Dans la fenetre qui vient de s’ouvrir, cliquez sur l’onglet Available Software.
• Cliquez sur Add Site...
• Dans la boite de dialogue qui apparaît, indiquez un nom (par exemple Android Plugin) et l'URL https://dl-ssl.google.com/android/eclipse/ . Appuyez sur le bouton OK. (en cas de problème, utilisez l’adresse http://dl-ssl.google.com/android/eclipse/)
• Dans l’onglet Available Software, sélectionnez Developer Tools et cliquez sur Install...
• Finissez l’installation puis redémarrez Eclipse.
• Une fois Eclipse redémarré, sélectionnez le menu Window > Preferences... (ou Eclipse > Preferences si vous êtes sous Linux).
• Sélectionnez Android dans le panel de gauche.
• Indiquez le chemin où vous avez installé le SDK Android (bouton Browse pour parcourir le système de fichier).
• Appuyez sur le bouton OK.
3 Prise en main de l’émulateur (AVD)
Remarque : Si vous passez à travers un proxy authentifié alors lancer le AVD Manager via Eclipse. Eclipse/Windows > Android SDK et AVD Manager
Attention : Les « add-ons » Google permettant d’utiliser les APIs Google n’ont pas été installés.
Récupérer les « add-ons » sur le serverRX (http://10.192.50.253/android/addons.zip).
Dézipper les add-ons dans /addons/
Explorez les différents menus pour comprendre le fonctionnement des boutons et découvrir les exemples montrant les possibilités de l’API.
Pas dans notre cas : Pour votre gouverne, il est possible de mettre à jour le SDK pour obtenir les dernières versions des APIs android.
3.1 Créer un émulateur : Un Android Virtual Device (AVD)
1°) Cliquer sur new
2°) Paramétrage de l’AVD comme suit :
4. Première application avec Android : Helloworld
4.1 Développement avec le plugin Eclipse
Voici les étapes pour développer la même application avec Eclipse et le plugin Android Development Tools.
Commencez par sélectionner le menu File > New > Project... puis Android > Android project.
Indiquez les propriétés du projet puis appuyez sur le bouton Finish :
Sélectionnez le fichier HelloWorld.java dans l'arborescence de gauche qui contient le code suivant :
Commençons notre Helloworld en modifiant ce fichier afin d'afficher du texte à l'écran (nous détaillerons le code ensuite) :
Dans Android, tous les composants graphiques (bouton, animation, champ texte, etc) sont basés sur la classe View.
Ainsi un champ texte est représenté par la classe TextView.
TextView tv = new TextView(this);
L'argument du constructeur de la classe TextView est une instance de la classe Context qui fournit entre autre des
services tel que la récupération des ressources, des accès base de données et des préférences.
Comme notre classe HelloWorld hérite d'Activity qui elle-même hérite de Context, nous pouvons passer la
référence 'this' au TextView.
Une fois le TextView instancié, il faut lui spécifier le texte à afficher : tv.setText("Hello, Android");
La dernière étape est d'afficher le TextView à l'écran : setContentView(tv);
Pour exécuter l'application, sélectionnez le menu Run > Run Configurations.
Dans la boite de dialogue qui s'ouvre, double cliquez sur l'entrée Android Application.
Un nouveau lanceur nommé New_configuration doit apparaître, sélectionnez le et renseignez le panel de droite :
Regarder l’onglet « Target ».
Il ne vous reste plus qu'à lancer l'application en appuyant sur le bouton Run.
TD/TP 2 : Android
Google Map
I. Obtention de la clé API
I-A. md5 checksum
I-B. Génération de la clé API et insertion dans le projet
II. Application graphique
II-A. Code
II-B. Explications
II-C. Résultat
III. Conclusion
I. Obtention de la clé API
I-A. md5 checksum
Avant de pouvoir insérer une carte Google Maps dans l'interface graphique, il faut obtenir une clé API.
Tout d'abord, il faut créer un md5 checksum du debug certificate car chaque application doit être signée et la clé API est basée justement sur ce certificat.
Pour afficher ce md5, il faut d'abord savoir où se situe ce fichier de debug :
* Vista: C:\Users\\AppData\Local\Android\debug.keystore
* XP: C:\Documents and Settings\\Android\debug.keystore
* Mac, Linux: ~/.android/debug.keystore
Si vous utilisez Eclipse, vous pouvez obtenir le chemin de la façon suivante :
Windows > Prefs > Android > Build
Une fois le chemin connu, il faut taper la commande suivante dans une console :
keytool -list -alias androiddebugkey -keystore .keystore -storepass android -keypass android
Vous devriez obtenir un affichage similaire à celui-ci :
I-B. Génération de la clé API et insertion dans le projet
Une fois cette première clé md5 checksum obtenue, vous pouvez générer la clé API à cette adresse :
http://code.google.com/intl/fr/android/maps-api-signup.html
Un compte Google étant nécessaire. Sinon, demander à votre chargé de TP de vous fournir un fichier debug.keystore et une clé API valides.
Une fois la clé API obtenue,
Créer un nouveau projet Eclipse appelé « Map ».
Ensuite, il faut l'ajouter dans le fichier String.xml de la façon suivante :
Il faut également modifier le fichier AndroidManifest.xml pour lui indiquer que l'API Google Maps est utile ainsi qu'ajouter les autorisations nécessaires pour utiliser internet et la localisation et ceci se fait de la manière suivante :
II. Application graphique
II-A. Code
Une fois cette clé obtenue, nous pouvons enfin nous lancer dans le code.
II-B. Explications
Cette ligne crée la carte en récupérant la clé API qui a été ajoutée dans le fichier String.xml modifié précédemment.
Cette partie se charge de récupérer le contrôleur chargé de positionner la carte à l'endroit indiqué par les coordonnées latitude et longitude (ces données sont multipliées par 1E6 car les coordonnées pour GeoPoint sont exprimées en micro-degré).
Change le zoom pour un zoom rapproché et passe la carte en vue satellitaire. On demande ensuite à redessiner la carte..
II-C. Résultat
Pour avoir accès au Google Maps votre émulateur doit pouvoir avoir accès à internet !!!!.
Pour se faire entrer dand le menu « run configuration » de votre application.
Sélectionner l’onglet Target et préciser le proxy de l’université (additional).
III. Conclusion
Toute cette démarche nous a permis de développer notre première application intégrant une carte Google Maps. Cette carte s'avère très basique mais il est possible d'aller plus loin et de développer des applications à l'instar d'Apple avec son kit Nike+ Ipod.
IV. Remerciements
Je tiens à remercier Michel Dirix pour son article sur la création et l’utilisation d’une Google Map.
TD/TP 3 : Android
Géolocalisation
I. Objectif
A partir du TP précédent faire les points suivants :
A°) Faire le suivi de sa propre position GPS.
B°) Positionner sur une carte les stations Yélo (Vélo) de La Rochelle.
II°) GPS Tracking
A°) Il vous faut instancier un « LocationManager »
//---use the LocationManager class to obtain GPS locations---
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE) ;
B°) Ensuite, il vous faut choisir le fournisseur(provider) de la géolocalisation
Par exemple, vous pouvez utiliser le GPS pour vous fournir votre positions :
String provider =lm.GPS_PROVIDER
Note : Il existe des méthodes beaucoup plus propres pour faire cela (getBestProviders)
C°) Un listener : Un listener écoute les changements d’état d’un composant. Dans notre cas, il nous faut un listener pour écouter les changemement d’état de notre LocationManager.
Instanciation du listener de position :
locationListener = new MyLocationListener();
Association du listener de position avec avec le LocationManager
lm.requestLocationUpdates(
provider,
20000,
100,
locationListener);
Expliquer les paramètres de la méthode : requestLocationUpdates
D°) Définition de la classe MyLocationListener
private class MyLocationListener implements LocationListener
{
@Override
public void onLocationChanged(Location loc) {
if (loc != null) {
Toast.makeText(getBaseContext(),
"Location changed : Lat: " + loc.getLatitude() +
" Lng: " + loc.getLongitude(),
Toast.LENGTH_SHORT).show();
p = new GeoPoint(
(int) (loc.getLatitude() * 1E6),
(int) (loc.getLongitude() * 1E6));
mc.animateTo(p);
mapView.invalidate();
}
}
To be continued…
Tester est faire fonctionner le GPS Tracking.
Utiliser DDMS pour tester votre GPS avec le fichier « Canal_de_Marans.gpx ». Ce fichier est sur Moodle (Cours PM4).
III°) Signaler les stations Yélos et sa position GPS
Maintenant on vous demande d’afficher sur la carte votre position GPS courante ainsi que les stations Yélo.
Votre position sera représentée par un marqueur bleu et les stations Yélo par des marqueurs verts. Ces images de marqueurs sont placées sur moodle (Cours PM4).
Pour mener à bien ce TP, il vous faudra les coordonnées GPS des stations Yélo. Ces coordonnées sont sur Moodle (Cours PM4).
Les stations Yélo seront chargées une fois seulement lors de la création de l’application.
Votre position GPS sera réactualisée à chaque « onLocationChanged »
A°) Il faut charger les ressources.
Dans notre cas, nous utiliserons deux ressources, les deux images de marqueurs.
Déterminer dans quel répertoire placer vos ressources ?
Charger les ressources :
bluepin = BitmapFactory.decodeResource(
getResources(), R.drawable.bluepin);
greenpin = BitmapFactory.decodeResource(
getResources(), R.drawable.greenpin);
B°) Créer un tableau de points GPS
stations = new ArrayList();
C°) Ajouter tous les points « Yélo » dans ce tableau
D°) Les marqueurs Yélo doivent être sur-imprimés sur la carte (OverLay en anglais)
Créer une classe StationOverlay qui héritera de com.google.android.maps.Overlay
E°) Dans la méthode « Draw » de cette classe
@Override
public boolean draw(Canvas canvas, MapView mapView,
boolean shadow, long when)
{
super.draw(canvas, mapView, shadow);
return true;
}
//---translate the GeoPoint to screen pixels---
Point screenPts = new Point();
//---add the marker---
for(GeoPoint pi: stations){
mapView.getProjection().toPixels(pi, screenPts);
canvas.drawBitmap(greenpin, screenPts.x, screenPts.y-32, null);
}
Que fait cette méthode ?
F°) Associer la classe StationOverlay à la MapView
listOfOverlays = mapView.getOverlays();
listOfOverlays.add(mapOverlayim);
StationOverlay mapOverlayim = new StationOverlay();
listOfOverlays.add(mapOverlayim);
Attention : Les stations Yélo seront chargées une fois seulement lors de la création de l’application.
Tester sur l’émulateur que tout fonctionne.
G°) Créer la classe MeOverlay qui afficher votre position courante avec le marqueur bleu.
MeOverlay sera instancié et ajouté à listOfOverlays lors de l’appel de la fonction onLocationChanged.
Attention : supprimer la position précédente du listOfOverlays pour ne pas surcharger la mémoire.
H°) Tester sur l’émulateur que tout fonctionne.
TD Android
Les Intents
Pour faire suite à un “Hello World” un peu atypique façon Google Maps, nous abordons un système important et même essentiel à Android : les Intents.
Android offre un système de communication trés ingénieux permettant de faire passer l’information entre Activitys ou plus généralement composants applicatifs . Ce système, déjà mentionné dans une partie précédente, est connu sous le nom d’Intent. Nous verrons donc dans ce TD comment transmettre l’information d’une Activity à une autre à l’aide de ce mécanisme d’Intents. Nous défricherons aussi la différence subtile entre Activity et View seront probablement éclairé par la lecture des lignes suivantes.
Introduction
Android sandbox les applications. Le mot “sandbox” est un anglicisme qui signifie simplement “bac à sable”. Il peu sembler étrange de parler de “bac à sable” dans un problème d’informatique mais c’est pourtant bel et bien la traduction adéquate dans le contexte. Le sandboxing est une pratique de plus en plus courante dans la téléphonie mobile qui consiste à séparer presque totalement les applications entre elles. Lorsque Android exécute une application, il restreint cette dernière à des actions bien définies (accès mémoire, accès sur les capteurs, etc…). Cette pratique permet de protéger le système au maximum en évitant de laisser des applications faire comme bon leurs semble.
Malgré l’énorme apport sur la sécurité, le sandoxing restreint fortement la communication entre applications. C’est dans l’optique de contourner ce “problème”, que les Intents ont été conçus. Pour faire simple, un Intent est un ensemble de données qui peut être passé à un autre composant applicatif (de la même application ou non) de façon implicite (requête pour une action – lire de la musique ou scanner un code barre par exemple) ou explicite (lancement d’une classe précise).
Démarrage d’une Activity grâce aux Intents
Pour bien décrire le système des Intents, nous allons créer une petite application (sans aucun but réel, je l’accorde) composée de 2 écrans : le premier dispose d’un bouton permettant de démarrer une nouvelle Activity de façon explicite. La seconde Activity affichera simplement un champ de recherche permettant d’effectuer une recherche sur Google. Le code de cette application est disponible dans ce dossier zippé.
Démarrage d’une activité de façon explicite
Pour commencer, créons une première Activity qui affichera un unique bouton central. Le code XML ci-dessous est composé d’une unique balise Button. Cette simplicité de l’interface graphique provient du fait que l’espace disponible au développeur pour afficher son application (l’intégralité de l’écran moins la barre de tâches et la barre de nom) est disponible sous la forme d’un FrameLayout. L’image ci-dessous montre la hiérarchie des vues générées avec ce fichier XML. On aperçoit facilement (en bleu) un FrameLayout.
Les paramètres android:layout_gravity="center" et android:text="Cliquez ici pour démarrer" permettent respectivement de centrer le bouton dans sa vue parente et de définir le texte du bouton.
Notre interface graphique étant prête, il suffit maintenant de créer notre première Activity. Pour faciliter la compréhension, j’ai préféré directement commenter le code. N’oubliez pas d’inclure cette nouvelle Activity dans le fichier Manifest.xml pour qu’Android autorise son exécution.
Le manifest :
Le code de la première activity :
package fr.pm4.android.HelloIntent;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
/*
* La classe EntryPoint implémente l'interface View.OnClickListener. Cela permet ainsi
* d'enregistrer l'activité auprès des vues pour qu'elle puisse recevoir les évènements de "clic".
*/
public class EntryPoint extends Activity implements View.OnClickListener {
/*
* Cette variable permettra de conserver une référence sur le bouton
* de l'interface
*/
private Button mButton;
/*
* La redéfinition de la méthode onCreate(Bundle) permet d'effectuer des actions
* supplémentaires à l'Activity de base.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*
* On créé l'interface graphique en utilisant le fichier entry.xml.
* Ce dernier étant disponible comme ressource (dans /res/layout), il suffit d'utiliser
* le fichier R.java et sa sous-classe layout.
*/
setContentView(R.layout.entry);
/*
* Récupère une référence sur le bouton en utilisant son identifiant
*/
mButton = (Button)findViewById(R.id.button);
/*
* On enregistre l'activité auprès du bouton pour recevoir les évènements
* "clic" provoqué par l'utilisateur.
*/
mButton.setOnClickListener(this);
}
/*
* La méthode onClick(View) provient de l'interface View.OnClickListener.
*/
@Override
public void onClick(View v) {
if (v == mButton) {
/*
* Nous sommes maintenant sûr que la vue ayant été cliquée est le bouton
* de notre interface. Il suffit donc de créer un nouvel Intent pour démarrer
* la seconde activité.
*/
Intent intent = new Intent(EntryPoint.this, GoogleSearch.class);
startActivity(intent);
}
}
}
Notre première Activity est maintenant terminée. Le lancement d’une nouvelle Activity de façon explicite s’effectue en deux lignes. La première, Intent intent = new Intent(EntryPoint.this, GoogleSearch.class); crée simplement un nouvel Intent dont le contexte de départ est l’Activity courante (EntryPoint.this) et l’Activity de destination se nomme GoogleSearch.
Démarrage d’une activité de façon implicite
Il ne nous reste maintenant plus qu’à définir l’Activity GoogleSearch en utilisant des principes similaires à ceux précédemment décrits. Commençons, tout d’abord par créer l’interface graphique :
Il ne me semble pas très important de décrire le fichier XML précédent car il peut être considéré comme classique. Il est à noter, tout de même, une légère différence avec les fichiers XML de notre HelloWorld : les ressources de type chaines de caractères, dimensions, etc. ne sont pas externalisés dans un fichier externe. Dans notre cas cela n’a pas réellement d’impact puisque nous n’allons pas internationaliser l’application.
package fr.pm4.android.HelloIntent;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
public class GoogleSearch extends Activity implements View.OnClickListener {
private ImageButton mImageButton;
private EditText mEditText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.google);
mImageButton = (ImageButton)findViewById(R.id.imageButton);
mEditText = (EditText)findViewById(R.id.editText);
mImageButton.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if (view == mImageButton) {
final String requete = "http://www.google.fr/search?q=" + mEditText.getText();
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(requete));
startActivity(intent);
}
}
}
Un clic sur le bouton “Google” créé un nouvel Intent à l’aide du constructeur Intent(String,Uri). La chaine de caractère passée en paramètre est une action à effectuer (ici ACTION_VIEW : action définie par le framework qui consiste à démarrer un navigateur web sur l’Uri donnée). On démarre enfin l’activité par un simple startActivity(Intent). Une action ne définissant pas une application en particulier, Android va tenter de chercher une application s’étant définie comme capable de répondre à l’action ACTION_VIEW. C’est cette “non certitude” sur l’application à ouvrir qui explique le nom de cette méthode : implicite. Généralement le navigateur utilisé est celui inclus de base dans le téléphone.
Conclusion
Les Intents sont des composants essentiels de l’architecture Android. Le démarrage explicite ou implicite d’une Activity à l’aide d’Intents n’est qu’une petite infime partie des possibilités de ce mécanisme. Cette partie fait donc office d’introduction aux Intents et vous permet de mieux comprendre la communication entre composants applicatifs Android. Vous êtes maintenant prêts à coder vos premiers programmes à écrans multiples !
Remerciement
Ce TD a pu voir le jour grâce à l’aide de Cyril Mottier et de son livre. Développez pour Android de Cyril Mottier et Ludovic Perrier
TD Android
Les Intents avec passage de variables
Passer des variables entre Activity sous android
Souvent quand on développe une application sous android, au début on a tendance à tout mettre dans la même classe. Le problème avec cette méthode de réalisation d’appli c’est le bouton retour du téléphone, quand on l’utilise on sort complètement de l’application au lieu de revenir à la fenêtre précèdente.
Pour éviter cela il faut utiliser une Activity pour chaque fenêtre.
Dans ce TD, une petite application permettant de naviguer entre deux fenêtres à l’aide d’Activity, en passant également une variable entre ces deux fenêtres.
Dans chaque fenêtre, un bouton et un champ de texte.
public class FenetreClass1 extends Activity{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fenetre);
//récupération du text dans le champ de saisie
final TextView textchampsaisie = (TextView) findViewById(R.id.text);
Button btaction = (Button) findViewById(R.id. btecrire);
//action sur le bouton click appelle de la nouvelle activité
btaction .setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
//création de notre item
Intent defineIntent = new Intent(lecontext, FenetreClass2.class);
// objet qui vas nous permettre de passe des variables ici la variable passInfo
Bundle objetbunble = new Bundle();
objetbunble .putString("passInfo",textchampsaisie..getText().toString());
// on passe notre objet a notre activities
defineIntent.putExtras(objetbunble );
// on appelle notre activité
lecontext.startActivity(defineIntent);
}
});
}
}
Récupération des informations passées par la classe FenetreClass1.class à la classe FenetreClass2.class
public class FenetreClass1 extends Activity{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fenetre);
//récupération du text dans le champ de saisie
final TextView textchampsaisie = (TextView) findViewById(R.id.text);
Bundle objetbunble = this.getIntent().getExtras();
// récupération de la valeur
String InfoPasse= objetbunble .getString("passInfo");
// on afffiche l'information dans l'edittext
textchampsaisie .setText(ingredient);
Ensuite le plus important, déclarer ces différentes activity dans le fichier AndroidManifest.xml