Tutoriel pour afficher correctement des Maps Android en développement et en production

KAMTA NIMPA Chris Willer

Dans cet article, nous parlerons de l'utilisation d'Android Google Maps via son API V2. Pour ce faire, nous allons développer une application Android basique pour illustrer cela. Nous mettrons l'accent sur les configurations nécessaires pour son utilisation en développement et les différences à prendre en compte dans ces configurations pour rendre une telle application fonctionnelle en production.

Vous pouvez réagir au contenu de ce tutoriel Commentez

- Titre : Tutoriel pour afficher correctement des Maps Android en développement et en production

- Auteur : KAMTA NIMPA Chris Willer

- Parution : 6 mai 2015

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2015 Chris Willer KAMTA. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC.

Sommaire

- I. Prérequis

- II. Problématique

- III. Objectif

- IV. Présentation de Google Maps API V2

- V. Création de l'application

- V-A. Rappel

- V-B. Créer un projet Android

- V-C. Installer la librairie Google Play services

- V-D. Création de la clé Map API V2

- V-E. Définir les autorisations du projet

- V-F. Code d'affichage de la Map

- V-G. Test de l'application

- VI. Générer l'exécutable (.apk) de l'application

- VI-A. Création de la clé release

- VI-B. Test de l'application avec la clé release

- VII. Pour aller plus loin

- VII-A. Shapes

- VII-B. Location Data

- VII-C. Interaction avec la carte

- VIII. Conclusion

- IX. Code source du projet

- X. Remerciements

- XI. Références

I - Prérequis

Ce tutoriel se veut simple et compréhensible pour tout débutant dans la programmation Android. Son but n'est pas d'initier à la programmation Android, pour cela il existe déjà de très bons tutoriels sur Internet. Cependant, pour une bonne compréhension, il est nécessaire d'avoir les connaissances de base en:

- développement Java ;

- développement Android.

Vous devez également avoir un environnement de développement opérationnel. Vous pouvez utiliser soit l'éditeur Eclipse avec un SDK Android installé (procédure d'installation) ou la solution ADT all in one (ADT Bundle) qui intègre déjà tous les outils nécessaires (disponible ici).

II - Problématique

De nos jours, de plus en plus d'applications pour smartphones utilisent le système de géolocalisation à travers Google Maps, technologie développée par Google permettant entre autres d'embarquer des cartes dans des applications pour mobile. Sa prise en main peut poser quelques difficultés.

- La carte du monde est affichée par votre application au lieu d'un point dont vous aviez spécifié les coordonnées.

- En cours de développement la carte s'affiche, mais en production elle ne s'affiche plus.

Si vous avez déjà été confronté à une de ces difficultés ou vous êtes en train de développer une application Android ou vous avez besoin d'utiliser Android Google Maps et que vous ne savez pas par où commencer, j'espère que vous trouverez des réponses dans ce tutoriel.

III - Objectif

Dans le cadre de ce tutoriel, nous allons développer une application Android qui va permettre d'afficher une position sur une carte. Nous allons par la suite la déployer en production.

IV - Présentation de Google Maps API V2

Google Map API v2 est une bibliothèque fournie par Google pour permettre aux développeurs Android d'embarquer les cartes Google Maps dans leurs applications. Elle fournit les outils permettant de manipuler les cartes. Cette version de l'API est sortie officiellement en fin d'année 2012 notamment en décembre.

L'unique version existante avant l'apparition de Map API v2 était Map API v1 qui était distribuée via l'extension « Google API » et utilisait la Mapview pour afficher les cartes.

Par rapport à la version 1, L'API v2 apporte quelques nouveautés et améliorations :

- les clés utilisées sur l'API v1 ne sont pas compatibles avec cette nouvelle version. De plus, Google ne fournit plus la possibilité de créer des clés pour l'API v1 ;

- le mode de distribution a changé et passe maintenant par le SDK Google Play services ;

- l'apparition des MapFragment qui permettent de faire des interfaces différenciées en fonction des terminaux mobiles utilisés (smartphones, tablettes, etc.) ;

- facilité d'intégration des marqueurs.

V - Création de l'application

V-A - Rappel

Depuis le début du tutoriel, je parle des modes développement et production. C'est quoi ces deux modes ?

Le mode développement (debogage) représente l'état d'une application en cours de développement. En effet, c'est un mode de test dans lequel les erreurs survenues pendant l'exécution sont affichées de façon détaillée et dans lequel l'EDI (environnement de développement intégré) permet de faire une exécution pas à pas du code source.

Par contre, le mode production (release) représente la version exécutable d'une application (.apk dans le cas d'une application Android). C'est une version dépourvue de tous les éléments de test par conséquent moins volumineuse.

V-B - Créer un projet Android

Démarrez votre EDI Eclipse, allez au menu « File > New > Android Application Project ». L'interface de création de nouveaux projets Android s'affiche. Renseignez le nom de l'application, le nom du projet et le nom du package. Pour les autres champs, laissez les valeurs par défaut.

Ensuite, cliquez sur « Next » et pour tous les autres écrans laissez les valeurs par défaut puis validez avec « Finish ». Eclipse vous génère un MainActivity et le layout correspondant.

V-C - Installer la librairie Google Play services

Pour afficher une carte avec Maps API V2, il est nécessaire d'inclure dans le projet la librairie Google Play services. Pour l'installer, lancez votre SDK Manager depuis la barre d'outils Eclipse.

Dans la boite de dialogue qui apparaît, déroulez « Extras » et installez  « Google Play services ».

Après l'installation, il faut importer la bibliothèque comme projet dans Eclipse. Allez au menu « File > New > Project », déroulez l'entrée « Android » et choisissez « Android Project from Existing Code » puis « Next ».

Cliquez sur « Browse » pour rechercher la bibliothèque Google Play services (vous la trouverez à l'emplacement : chemin de votre sdk/extras/google/google_play_services/libproject.

Une fois la bibliothèque importée, il faut l'ajouter comme dépendance dans votre projet. Pour cela, sélectionnez le projet mapv2 ensuite allez dans le menu « Prroject > Properties », dans le panneau de gauche choisissez « Android ». À droite apparaît un panneau avec un bloc Library, cliquez sur le bouton « Add » et choisissez comme bibliothèque à importer googleplay services puis validez.

En principe si vous avez bien suivi les instructions, la structure de votre projet dans l'explorateur de paquets d'Eclipse devra ressembler à ceci:

À ce stade vous pouvez déjà utiliser les outils Maps API V2. Cependant vous ne pouvez pas encore afficher votre carte, car pour que ce soit possible il vous faut obtenir une API key de votre projet auprès de Google et donner les autorisations nécessaires dans votre fichier Manifest.

V-D - Création de la clé Map API V2

Pour obtenir cette clé, allez dans votre console Google Développeur Console Google.

Pour utiliser cette console, vous devez posséder un compte Gmail.

Créez un projet au niveau de la console, une fois votre projet créé, allez dans le panneau de gauche de votre console sous le Menu « APIs & auth », choisissez  « APIs ».

Dans la liste de services qui se chargent, recherchez « Google Maps Android API V2 », vous trouverez une ligne semblable à celle-ci :

Cliquez sur le bouton « Off » pour l'activer, une fois activé il apparaît tout en haut de la liste comme ci-dessous.

Revenez dans le panneau de gauche et cliquez sur « Credentials ».

C'est ici que vous allez générer une clé pour votre application. Choisissez « Create new Key », ensuite dans la Popup qui s'affiche choisissez « Android Key ». Vous remarquerez que Google demande de donner l'empreinte SHA1 de votre clé. Pour la retrouver, revenez dans l'EDI Eclipse dans le menu « Window > preferences ». Dans le panneau de gauche, déroulez « Android » puis cliquez sur « Build ». Dans le panneau de droite, vous voyez apparaître un contenu, le bloc qui vous intéresse est celui de la capture suivante.

Copiez la valeur dont la clé est SHA1 fingerprint et collez-la dans l'espace indiqué dans votre console suivi du nom de package de votre application séparé par un point-virgule. Vous obtenez quelque chose comme sur la figure ci-contre:

Validez pour générer votre clé.

La clé étant générée, il vous faut définir les autorisations dans le fichier de configuration Manifest de votre projet.

V-E - Définir les autorisations du projet

Pour afficher votre Map, l'application a besoin de certaines autorisations en plus de l'API key. Ces permissions sont à mettre avant la balise application du fichier Manifest.

1. <!-- on crée une permission pour notre application -->

2. <permission android:name="com.abyster.tuto.mapv2.permission.MAPS_RECEIVE"

3. android:protectionLevel="signature"/>

4. <!-- on ajoute notre permission à la liste de permissions requises par l'API -->

5. <uses-permission android:name="com.abyster.tuto.mapv2.permission.MAPS_RECEIVE"

6. android:protectionLevel="signature"/>

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

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

10. <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>

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

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

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

15. <!-- la librairie Maps V2 nécessite openGL pour son bon fonctionnement -->

16. <uses-feature android:glEsVersion="0x00020000" android:required="true"/>

Dans la balise application du même fichier Manifest, insérez les deux instructions du code ci-dessous. La première définit la clé de l'API générée précédemment (vous remarquerez que j'ai mis ma clé dans le fichier de déclaration de chaîne de caractères strings.xml avec pour nom api_debug_key et je l'appelle juste dans le Manifest) et la seconde définit la version de l'API Google Play services utilisée.

1. <meta-data android:name="com.google.android.maps.v2.API_KEY"

2. android:value="@string/api_debug_key"/>

3. <meta-data android:name="com.google.android.gms.version"

4. android:value="@integer/google_play_services_version" />

Le fichier manifest final devrait ressembler à ceci:

AndroidManifest.xml

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

2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"

3. package="com.abyster.tuto.mapv2"

4. android:versionCode="1"

5. android:versionName="1.0" >

7. <uses-sdk

8. android:minSdkVersion="8"

9. android:targetSdkVersion="19" />

11. <!-- on crée une permission pour notre application -->

12. <permission android:name="com.abyster.tuto.mapv2.permission.MAPS_RECEIVE"

13. android:protectionLevel="signature"/>

14. <!-- on ajoute notre permission à la liste de permissions requises par l'API -->

15. <uses-permission android:name="com.abyster.tuto.mapv2.permission.MAPS_RECEIVE"

16. android:protectionLevel="signature"/>

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

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

20. <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>

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

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

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

25. <!-- la librairie Maps V2 nécessite openGL pour son bon fonctionnement -->

26. <uses-feature android:glEsVersion="0x00020000" android:required="true"/>

28. <application

29. android:allowBackup="true"

30. android:icon="@drawable/ic_launcher"

31. android:label="@string/app_name"

32. android:theme="@style/AppTheme" >

34. <meta-data android:name="com.google.android.maps.v2.API_KEY"

35. android:value="@string/api_debug_key"/>

36. <meta-data android:name="com.google.android.gms.version"

37. android:value="@integer/google_play_services_version" />

39. <activity

40. android:name="com.abyster.tuto.mapv2.MainActivity"

41. android:label="@string/app_name" >

42. <intent-filter>

43. <action android:name="android.intent.action.MAIN" />

44. <category android:name="android.intent.category.LAUNCHER" />

45. </intent-filter>

46. </activity>

47. </application>

48. </manifest>

V-F - Code d'affichage de la Map

Remplacez le code de votre activity_main.xml par celui-ci :

activity_main.xml

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

2. <fragment xmlns:android="http://schemas.android.com/apk/res/android"

3. android:id="@+id/map"

4. android:layout_width="match_parent"

5. android:layout_height="match_parent"

6. android:name="com.google.android.gms.maps.SupportMapFragment"/>

Au niveau de la ligne android:name, nous avons utilisé SupportMapFragment pour que notre carte puisse s'afficher sur tous les téléphones quelle que soit la version d'Android utilisée par ceux-ci. On aurait pu utiliser MapFragment, alors la carte ne se serait pas affichée sur des téléphones possédant des versions d'Android inférieures à Android 3.0.

MainActivity doit étendre FragmentActivity au lieu d'Activity.

Définissons le code de l'activité pour afficher un point sur la carte. Les explications sont en commentaire dans le code.

MainActivity.java

1. package com.abyster.tuto.mapv2;

2. import com.google.android.gms.maps.CameraUpdateFactory;

3. import com.google.android.gms.maps.GoogleMap;

4. import com.google.android.gms.maps.SupportMapFragment;

5. import com.google.android.gms.maps.model.BitmapDescriptorFactory;

6. import com.google.android.gms.maps.model.LatLng;

7. import com.google.android.gms.maps.model.MarkerOptions;

8. import android.os.Bundle;

9. import android.support.v4.app.FragmentActivity;

10. import android.view.Menu;

12. public class MainActivity extends FragmentActivity {

14. private GoogleMap GMap;

15. private LatLng yaounde=new LatLng(3.881501,11.50818);

17. @Override

18. protected void onCreate(Bundle savedInstanceState) {

19. super.onCreate(savedInstanceState);

20. setContentView(R.layout.activity_main);

22. //on récupère le fragment définit dans le layout qui va contenir la carte

23. GMap= ((SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map)).getMap();

25. //on s'assure que l'objet map n'est pas vide

26. if(GMap!=null){

27. //mode d'affichage de la carte

28. GMap.setTrafficEnabled(true);

29. //on autorise l'api à afficher le bouton pour accéder à notre position courante

30. GMap.setMyLocationEnabled(true);

32. //définition du marqueur qui va se positionner sur le point qu'on désire afficher

33. MarkerOptions markerOptions = new MarkerOptions();

34. markerOptions.title("YAOUNDE");

35. markerOptions.visible(true);

36. markerOptions.position(yaounde);

37. markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_YELLOW));

39. //ajout du marqueur sur la carte

40. GMap.addMarker(markerOptions);

41. //zoom de la caméra sur la position qu'on désire afficher

42. GMap.moveCamera(CameraUpdateFactory.newLatLngZoom(yaounde, 16));

43. //animation le zoom toute les 2000ms

44. GMap.animateCamera(CameraUpdateFactory.zoomTo(15), 2000, null);

45. }

46. }

47. }

Le niveau de zoom est très important, si vous définissez une mauvaise valeur votre Map n'affichera que la carte du monde. Les deux dernières lignes de code (ligne 40 et 42) vont de paires. La carte ne s'afficherait pas bien sans ces deux instructions. Vous pouvez faire varier la valeur du zoom pour voir les différents effets que cela produit.

V-G - Test de l'application

Faites un clic droit sur le projet puis « Run As > Android Application », vous devriez obtenir ceci :

Pour afficher votre position, cliquez sur le bouton représenté par une boussole et la carte se déplace et signale votre position avec un point bleu.

Ce test est fait sur un vrai téléphone et non sur un émulateur, car l'application installée directement sur l'émulateur n'affiche pas la carte.

Cependant, après quelques recherches sur la toile, il se pourrait que cela soit possible moyennant certaines configurations préalables sur l'émulateur.

Consultez ces deux liens qui expliquent la procédure à suivre :

- http://hmkcode.com ;

- http://javamvp.blogspot.com.

Si quelqu'un a déjà eu à le faire autrement, ce serait généreux de sa part de le partager avec nous.

VI - Générer l'exécutable (.apk) de l'application

Pour mettre l'application en production, il faut créer l'exécutable. Faites un clic droit sur le projet > Android Tools >Exported Signed Application package, vous avez la boîte de dialogue ci-contre :

Sur l'écran suivant, nous allons créer la clé avec laquelle on va signer notre application en production. Cochez le bouton radio « Create new keystore » et remplissez les champs. Utilisez un mot de passe que vous n'allez pas oublier.

Pour l'écran suivant, entrez les informations de signature. Les quatre premiers champs sont obligatoires. Pour le Password, utilisez le même que celui de l'écran précédent.

Maintenant vous pouvez générer votre exécutable.

Installez cet exécutable dans votre mobile et lancez l'application : elle affiche résolument un écran vide juste avec le marqueur. La carte de tout à l'heure ne s'affiche plus.

Pourquoi ?

C'est simple, la clé que nous venons d'utiliser pour signer notre APK est une clé de production que nous avons créée nous-mêmes donc celle-ci est liée au certificat que nous avons créé. Or la clé que nous avons générée au niveau de la console API Google n'est pas liée à ce certificat, mais plutôt à l'empreinte SHA-1 de notre certificat de debogage (l'android.debug que nous avons copié depuis Eclipse).

VI-A - Création de la clé release

Pour résoudre ce problème, il faut donc générer une autre clé depuis la console API Google, mais cette fois-ci avec l'empreinte SHA-1 du certificat que nous avons créé pour signer notre APK. Pour le faire, lancez l'invite de commande et positionnez-vous dans le répertoire d'installation de votre JDK.

Saisissez la commande : keytool -list -kystore « chemin vers votre keystore ».

Ensuite il vous est demandé de donner le mot de passe de votre certificat (c'est celui utilisé pour créer votre keystore).

Copiez l'empreinte SHA-1 et générez une nouvelle API Key dans la console Google.

Une fois cette tâche accomplie, copiez cette nouvelle clé dans le Manifest pour remplacer la clé de debogage ci-dessous.

<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="@string/api_debug_key"/>

VI-B - Test de l'application avec la clé release

Regénérez votre APK cette fois en utilisant le keystore créé précédemment (Use existing keystore). Votre Map devrait s'afficher très bien cette fois-ci.

VII - Pour aller plus loin

Dans ce qui précède, nous avons utilisé les fonctionnalités de base pour l'intégration des Google maps : ultilisation des fragments, ajout des marqueurs, etc.

Mais ces éléments ne sont pas les seuls fournis par l'API v2. Nous allons présenter quelques autres fonctionnalités principales.

VII-A - Shapes

Ce sont des formes ou schémas fournis par l'API qu'on peut ajouter à une carte en vue de la personnaliser. On distingue :

- Polyline : c'est une classe fournissant des segments d'interconnexions de coordonnées(LatLng) successives sur une carte, elle peut par exemple permettre de représenter un chemin ;

- Polygon : elle fournit à la base la même fonctionnalité que Polyline sauf qu'ici elle interconnecte des coordonnées successives dans un espace fermé, c'est-à-dire que le point d'arrivée rejoint le point de départ ;

- Circle : permet d'ajouter un cercle sur la carte, cercle centré autour d'une coordonnée spécifique et d'un rayon défini.

VII-B - Location Data

Les données de localisation fournissent les informations de localisation d'un appareil Android, elles le font via des fournisseurs de position tels que le GPS et Internet. Cela va de la localisation de l'emplacement actuel de l'appareil à la direction et à la méthode de mouvement. Selon les besoins d'une application, vous pouvez choisir entre plusieurs façons de travailler avec des données de localisation.

- La couche MyLocation : fournit les outils pour afficher la position d'un appareil sur la carte.

- Google Play Services Location API : est utilisé dans la programmation pour toutes les requêtes sur les données de localisation.

- LocationSource : interface permettant à l'utilisateur de définir son propre fournisseur de position.

VII-C - Interaction avec la carte

Maps API V2 permet de personnaliser les actions qu'un utilisateur peut réaliser. Cela va de l'ajout de composants d'interface graphique sur la carte à l'ajout des événements autorisés à l'utilisateur et quels comportements adoptés quand ces derniers surviennent.

VIII - Conclusion

C'est ici que s'achève ce tutoriel sur l'utilisation de Google Maps Android API V2. J'espère avoir pu aider ceux qui avaient quelques difficultés pour la prise en main de cette API.

IX - Code source du projet

Téléchargez le code source de l'exemple ici.

X - Remerciements

Je tiens à remercier:

- la société AByster qui m'a permis de travailler sur le projet qui a donné l'idée de ce tutoriel ;

- Feanorin et Mickael Baron pour la relecture de ce tutoriel, également leurs remarques et conseils apportés lors de sa rédaction ;

- Milkoseck pour sa relecture orthographique.

XI - Références

- Google Maps API V2 documentation.

- Tutoriel AndroidGoogleMapsVogella.