Développement Android avancé en Kotlin 04.1 : Google Maps pour Android

Cet atelier de programmation fait partie du cours Développement Android avancé en Kotlin. Vous tirerez pleinement parti de ce cours en suivant les ateliers de programmation dans l'ordre, mais ce n'est pas obligatoire. Tous les ateliers de programmation du cours sont listés sur la page de destination des ateliers de programmation Android avancé en Kotlin.

Créer des applications avec Google Maps vous permet d'ajouter des fonctionnalités à votre application, telles que des images satellite, des commandes d'interface utilisateur robustes pour les cartes, le suivi de la position et les repères de position. Vous pouvez ajouter de la valeur à Google Maps standard en affichant des informations issues de votre propre ensemble de données, comme l'emplacement de zones de pêche ou d'escalade connues. Vous pouvez également créer des jeux dans lesquels le joueur explore le monde physique, comme dans une chasse au trésor ou même des jeux en réalité augmentée.

Dans cet atelier, vous allez créer une application Google Maps appelée Wander qui affiche des cartes personnalisées et la position de l'utilisateur.

Prérequis

Connaissances requises :

  • Découvrez comment créer une application Android de base et l'exécuter à l'aide d'Android Studio.
  • Créer et gérer des ressources, telles que des chaînes.
  • Découvrez comment refactoriser du code et renommer des variables à l'aide d'Android Studio.
  • Utiliser une carte Google en tant qu'utilisateur
  • Comment définir les autorisations d'exécution ?

Points abordés

  • Obtenir une clé API depuis la console Google APIs et l'enregistrer dans votre application
  • Intégrer une carte Google à votre application
  • Afficher différents types de cartes
  • Appliquer un style à la carte Google Maps
  • Ajouter des repères à votre carte
  • Permettre à l'utilisateur de placer un repère sur un point d'intérêt
  • Activer le suivi de la position
  • Créer l'application Wander avec une carte Google intégrée
  • Créer des fonctionnalités personnalisées pour votre application, telles que des repères et des styles
  • Activer le suivi de la position dans votre application

Dans cet atelier de programmation, vous allez créer l'application Wander, qui affiche une carte Google avec un style personnalisé. L'application Wander vous permet de placer des repères sur des lieux, d'ajouter des calques et de voir votre position en temps réel.

Le SDK Maps pour Android nécessite une clé API. Pour obtenir la clé API, enregistrez votre projet sur la page API et services. La clé API est associée à un certificat numérique qui relie l'application à son auteur. Pour en savoir plus sur l'utilisation des certificats numériques et la signature de votre application, consultez Signer votre application.

Dans cet atelier de programmation, vous allez utiliser la clé API pour le certificat de débogage. Le certificat de débogage n'est pas sécurisé par conception, comme décrit dans Signer votre build de débogage. Les applications Android publiées qui utilisent le SDK Maps pour Android nécessitent une deuxième clé API : la clé du certificat de version. Pour en savoir plus sur l'obtention d'un certificat de publication, consultez Obtenir une clé API.

Android Studio inclut un modèle d'activité Google Maps qui génère un code de modèle utile. Le code du modèle inclut un fichier google_maps_api.xml contenant un lien qui simplifie l'obtention d'une clé API.

Étape 1 : Créez le projet Wander avec le modèle de cartes

  1. Créez un projet Android Studio.
  2. Sélectionnez le modèle Activité Google Maps.

  1. Nommez le projet Wander.
  2. Définissez le niveau d'API minimal sur API 19. Assurez-vous que le langage est défini sur Kotlin.
  3. Cliquez sur Terminer.
  4. Une fois l'application créée, examinez votre projet et les fichiers liés à Maps qu'Android Studio a créés pour vous :

google_maps_api.xml : ce fichier de configuration vous permet de stocker votre clé API. Le modèle génère deux fichiers google_maps_api.xml : un pour le débogage et un pour la version finale. Le fichier de la clé API pour le certificat de débogage se trouve dans src/debug/res/values. Le fichier de la clé API du certificat de version se trouve dans src/release/res/values. Dans cet atelier de programmation, vous n'utiliserez que le certificat de débogage.

activity_maps.xml : ce fichier de mise en page contient un seul fragment qui remplit l'intégralité de l'écran. La classe SupportMapFragment est une sous-classe de la classe Fragment. Un SupportMapFragment est le moyen le plus simple de placer une carte dans une application. Il s'agit d'un wrapper autour d'une vue de carte pour gérer automatiquement les besoins de cycle de vie nécessaires.

Vous pouvez inclure SupportMapFragment dans un fichier de mise en page à l'aide d'une balise <fragment> dans n'importe quel ViewGroup, avec un attribut name supplémentaire.

android:name="com.google.android.gms.maps.SupportMapFragment"

MapsActivity.java : le fichier MapsActivity.kt instancie l'SupportMapFragment dans la méthode onCreate() et utilise l'getMapAsync() de la classe pour initialiser automatiquement le système de cartes et la vue. L'activité contenant SupportMapFragment doit implémenter l'interface OnMapReadyCallback et la méthode onMapReady() de cette interface. La méthode onMapReady() est appelée lorsque la carte est chargée.

Étape 2 : Obtenez la clé API

  1. Ouvrez la version de débogage du fichier google_maps_api.xml.
  2. Dans le fichier, recherchez un commentaire contenant une longue URL. Les paramètres de l'URL incluent des informations spécifiques sur votre application.
  3. Copiez et collez l'URL dans un navigateur.
  4. Suivez les instructions pour créer un projet sur la page API et services. Grâce aux paramètres de l'URL fournie, la page sait qu'elle doit activer automatiquement le SDK Maps pour Android.
  5. Cliquez sur Créer une clé API.
  6. Sur la page suivante, accédez à la section "Clés API" et cliquez sur la clé que vous venez de créer.
  7. Cliquez sur Restreindre la clé, puis sélectionnez SDK Maps pour Android pour limiter l'utilisation de la clé aux applications Android.
  8. Copiez la clé API générée. Il commence par "AIza".
  9. Dans le fichier google_maps_api.xml, collez la clé dans la chaîne google_maps_key à l'endroit où il est indiqué YOUR_KEY_HERE.
  10. Exécutez votre application. Vous devriez voir une carte intégrée dans votre activité avec un repère défini à Sydney, en Australie. (Le repère de Sydney fait partie du modèle et vous le modifierez plus tard.)

Étape 3 : Renommez mMap

MapsActivity possède un lateinit privé var appelé mMap, qui est de type GoogleMap. Pour respecter les conventions de dénomination Kotlin, remplacez le nom de mMap par map.

  1. Dans MapsActivity, effectuez un clic droit sur mMap, puis cliquez sur Refactor > Rename... (Refactoriser > Renommer).

  1. Remplacez le nom de la variable par map.

Notez que toutes les références à mMap dans la fonction onMapReady() sont également remplacées par map.

Google Maps inclut plusieurs types de cartes : normal, hybride, satellite, relief et "aucun" (pour n'afficher aucune carte).

Carte normale

Carte satellite

Carte hybride

Carte du relief

Chaque type de carte fournit des informations différentes. Par exemple, lorsque vous utilisez Maps pour la navigation en voiture, il est utile de voir les noms de rue. Vous pouvez donc utiliser l'option "Normal". Lorsque vous faites de la randonnée, la carte du relief peut vous aider à déterminer la distance qu'il vous reste à parcourir pour atteindre le sommet.

Dans cette tâche, vous allez :

  1. Ajoutez une barre d'application avec un menu d'options qui permet à l'utilisateur de modifier le type de carte.
  2. Déplacez le point de départ de la carte jusqu'à votre domicile.
  3. Ajoutez la prise en charge des repères, qui indiquent des emplacements uniques sur une carte et peuvent inclure un libellé.

Ajouter un menu pour les types de cartes

Dans cette étape, vous allez ajouter une barre d'application avec un menu d'options qui permet à l'utilisateur de modifier le type de carte.

  1. Pour créer un fichier XML de menu, effectuez un clic droit sur votre répertoire res, puis sélectionnez New > Android Resource File (Nouveau > Fichier de ressources Android).
  2. Dans la boîte de dialogue, nommez le fichier map_options.
  3. Sélectionnez Menu pour le type de ressource.
  4. Cliquez sur OK.
  5. Dans l'onglet Code, remplacez le code du nouveau fichier par le code suivant pour créer les options du menu de la carte. Le type de carte "none" (aucun) est omis, car il n'affiche aucune carte. Cette étape génère une erreur, mais vous la résoudrez à l'étape suivante.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto">
   <item
       android:id="@+id/normal_map"
       android:title="@string/normal_map"
       app:showAsAction="never" />
   <item
       android:id="@+id/hybrid_map"
       android:title="@string/hybrid_map"
       app:showAsAction="never" />
   <item
       android:id="@+id/satellite_map"
       android:title="@string/satellite_map"
       app:showAsAction="never" />
   <item
       android:id="@+id/terrain_map"
       android:title="@string/terrain_map"
       app:showAsAction="never" />
</menu>
  1. Dans strings.xml, ajoutez des ressources pour les attributs title afin de résoudre les erreurs.
<resources>
   ...
   <string name="normal_map">Normal Map</string>
   <string name="hybrid_map">Hybrid Map</string>
   <string name="satellite_map">Satellite Map</string>
   <string name="terrain_map">Terrain Map</string>
   <string name="lat_long_snippet">Lat: %1$.5f, Long: %2$.5f</string>
   <string name="dropped_pin">Dropped Pin</string>
   <string name="poi">poi</string>
</resources>
  1. Dans MapsActivity, remplacez la méthode onCreateOptionsMenu() et développez le menu à partir du fichier de ressources map_options.
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
   val inflater = menuInflater
   inflater.inflate(R.menu.map_options, menu)
   return true
}
  1. Dans MapsActivity.kt, remplacez la méthode onOptionsItemSelected(). Modifiez le type de carte à l'aide des constantes map-type pour refléter la sélection de l'utilisateur.
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
   // Change the map type based on the user's selection.
   R.id.normal_map -> {
       map.mapType = GoogleMap.MAP_TYPE_NORMAL
       true
   }
   R.id.hybrid_map -> {
       map.mapType = GoogleMap.MAP_TYPE_HYBRID
       true
   }
   R.id.satellite_map -> {
       map.mapType = GoogleMap.MAP_TYPE_SATELLITE
       true
   }
   R.id.terrain_map -> {
       map.mapType = GoogleMap.MAP_TYPE_TERRAIN
       true
   }
   else -> super.onOptionsItemSelected(item)
}
  1. Exécutez l'application.
  2. Cliquez sur pour modifier le type de carte. Remarquez comment l'apparence de la carte change entre les différents modes.

Par défaut, le rappel onMapReady() inclut du code qui place un repère à Sydney, en Australie, où Google Maps a été créé. Le rappel par défaut anime également la carte pour la faire défiler jusqu'à Sydney.

Dans cette tâche, vous allez faire en sorte que la caméra de la carte se déplace vers votre maison, effectue un zoom au niveau que vous spécifiez et y place un repère.

Étape 1 : Zoomez sur votre maison et ajoutez un repère

  1. Dans le fichier MapsActivity.kt, recherchez la méthode onMapReady(). Supprimez le code qui place le repère à Sydney et déplace la caméra. Votre méthode devrait désormais se présenter comme suit.
override fun onMapReady(googleMap: GoogleMap) {
   map = googleMap

}
  1. Pour trouver la latitude et la longitude de votre domicile, suivez ces instructions.
  2. Créez une valeur pour la latitude et une valeur pour la longitude, puis saisissez leurs valeurs flottantes.
val latitude = 37.422160
val longitude = -122.084270
  1. Créez un objet LatLng appelé homeLatLng. Dans l'objet homeLatLng, transmettez les valeurs que vous venez de créer.
val homeLatLng = LatLng(latitude, longitude)
  1. Créez un val pour définir le niveau de zoom souhaité sur la carte. Utilisez le niveau de zoom 15f.
val zoomLevel = 15f

Le niveau de zoom détermine le niveau d'agrandissement de la carte. La liste suivante vous donne une idée du niveau de détail affiché à chaque niveau de zoom :

  • 1 : Monde
  • 5 : Masse continentale/Continent
  • 10 : Ville
  • 15 : Rues
  • 20 : Bâtiments
  1. Déplacez la caméra sur homeLatLng en appelant la fonction moveCamera() sur l'objet map et en transmettant un objet CameraUpdate à l'aide de CameraUpdateFactory.newLatLngZoom(). Transmettez l'objet homeLatLng et le zoomLevel.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
  1. Ajoutez un repère à la carte à homeLatLng.
map.addMarker(MarkerOptions().position(homeLatLng))

La méthode finale devrait se présenter comme suit :

override fun onMapReady(googleMap: GoogleMap) {
   map = googleMap

   //These coordinates represent the latitude and longitude of the Googleplex.
   val latitude = 37.422160
   val longitude = -122.084270
   val zoomLevel = 15f

   val homeLatLng = LatLng(latitude, longitude)
   map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
   map.addMarker(MarkerOptions().position(homeLatLng))
}
  1. Exécutez votre application. La carte doit effectuer un panoramique sur votre domicile, zoomer au niveau souhaité et placer un repère sur votre domicile.

Étape 2 : Autoriser les utilisateurs à ajouter un repère en effectuant un appui long

Lors de cette étape, vous allez ajouter un repère lorsque l'utilisateur appuie de manière prolongée sur un lieu de la carte.

  1. Créez un stub de méthode dans MapsActivity appelé setMapLongClick() qui accepte un GoogleMap comme argument.
  2. Associez un écouteur setOnMapLongClickListener à l'objet de carte.
private fun setMapLongClick(map:GoogleMap) {
   map.setOnMapLongClickListener { }
}
  1. Dans setOnMapLongClickListener(), appelez la méthode addMarker(). Transmettez un nouvel objet MarkerOptions avec la position définie sur le LatLng transmis.
private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       map.addMarker(
           MarkerOptions()
               .position(latLng)
       )
   }
}
  1. À la fin de la méthode onMapReady(), appelez setMapLongClick() avec map.
override fun onMapReady(googleMap: GoogleMap) {
   ...
  
   setMapLongClick(map)
}
  1. Exécutez votre application.
  2. Appuyez de manière prolongée sur la carte pour placer un repère à un endroit.
  3. Appuyez sur le repère pour le centrer sur l'écran.

Étape 3 : Ajoutez une fenêtre d'informations pour le repère

Au cours de cette étape, vous allez ajouter un InfoWindow qui affiche les coordonnées du repère lorsque l'utilisateur appuie dessus.

  1. Dans setMapLongClick()setOnMapLongClickListener(), créez un val pour snippet. Un extrait est un texte supplémentaire affiché après le titre. Votre extrait affiche la latitude et la longitude d'un repère.
private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       // A snippet is additional text that's displayed after the title.
       val snippet = String.format(
           Locale.getDefault(),
           "Lat: %1$.5f, Long: %2$.5f",
           latLng.latitude,
           latLng.longitude
       )
       map.addMarker(
           MarkerOptions()
               .position(latLng)
       )
   }
}
  1. Dans addMarker(), définissez le title du repère sur "Épingle déposée" à l'aide d'une ressource de chaîne R.string.dropped_pin.
  2. Définissez le snippet du repère sur snippet.

La fonction terminée ressemble à ceci :

private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       // A Snippet is Additional text that's displayed below the title.
       val snippet = String.format(
           Locale.getDefault(),
           "Lat: %1$.5f, Long: %2$.5f",
           latLng.latitude,
           latLng.longitude
       )
       map.addMarker(
           MarkerOptions()
               .position(latLng)
               .title(getString(R.string.dropped_pin))
               .snippet(snippet)
              
       )
   }
}
  1. Exécutez votre application.
  2. Appuyez de manière prolongée sur la carte pour placer un repère de position.
  3. Appuyez sur le repère pour afficher la fenêtre d'informations.

Étape 4 : Ajouter un écouteur de POI

Par défaut, les points d'intérêt (POI) s'affichent sur la carte avec les icônes correspondantes. Les POI incluent les parcs, les écoles, les bâtiments administratifs, etc. Lorsque le type de carte est défini sur normal, les POI commerciaux s'affichent également sur la carte. Ces POI représentent des établissements tels que des magasins, des restaurants et des hôtels.

Au cours de cette étape, vous allez ajouter un GoogleMap.OnPoiClickListener à la carte. Cet écouteur de clics place un repère sur la carte immédiatement lorsque l'utilisateur clique sur un POI. L'écouteur de clics affiche également une fenêtre d'informations contenant le nom du point d'intérêt.

  1. Créez un stub de méthode dans MapsActivity appelé setPoiClick() qui accepte un GoogleMap comme argument.
  2. Dans la méthode setPoiClick(), définissez un OnPoiClickListener sur le GoogleMap transmis.
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->

   }
}
  1. Dans le setOnPoiClickListener(), créez un val poiMarker pour le repère .
  2. Définissez-le sur un repère à l'aide de map.addMarker(), avec MarkerOptions définissant title sur le nom du point d'intérêt.
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->
       val poiMarker = map.addMarker(
           MarkerOptions()
               .position(poi.latLng)
               .title(poi.name)
       )
   }
}
  1. Dans la fonction setOnPoiClickListener(), appelez showInfoWindow() sur poiMarker pour afficher immédiatement la fenêtre d'informations.
poiMarker.showInfoWindow()

Votre code final pour la fonction setPoiClick() devrait se présenter comme suit.

private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->
       val poiMarker = map.addMarker(
           MarkerOptions()
               .position(poi.latLng)
               .title(poi.name)
       )
       poiMarker.showInfoWindow()
   }
}
  1. À la fin de onMapReady(), appelez setPoiClick() et transmettez map.
override fun onMapReady(googleMap: GoogleMap) {
   ...

   setPoiClick(map)
}
  1. Exécutez votre application et trouvez un point d'intérêt, comme un parc ou un café.
  2. Appuyez sur le point d'intérêt pour y placer un repère et afficher son nom dans une fenêtre d'informations.

Vous pouvez personnaliser Google Maps de nombreuses façons pour donner à votre carte une apparence unique.

Vous pouvez personnaliser un objet MapFragment à l'aide des attributs XML disponibles, comme vous le feriez pour n'importe quel autre fragment. Toutefois, dans cette étape, vous allez personnaliser l'apparence du contenu de MapFragment à l'aide de méthodes sur l'objet GoogleMap.

Pour créer un style personnalisé pour votre carte, générez un fichier JSON qui spécifie comment les éléments de la carte sont affichés. Vous n'avez pas besoin de créer ce fichier JSON manuellement. Google fournit l'assistant Maps Platform Styling Wizard, qui génère le code JSON pour vous après que vous avez défini le style de votre carte. Dans cette tâche, vous allez appliquer un style rétro à la carte, ce qui signifie que vous allez utiliser des couleurs vintage et ajouter des routes colorées.

Étape 1 : Créez un style pour votre carte

  1. Accédez à https://mapstyle.withgoogle.com/ dans votre navigateur.
  2. Sélectionnez Créer un style.
  3. Sélectionnez Rétro.

  1. Cliquez sur Plus d'options.

  1. Dans la liste Type de fonctionnalité, sélectionnez Route> Remplir.
  2. Changez la couleur des routes pour celle de votre choix (par exemple, le rose).

  1. Cliquez sur Terminer.

  1. Copiez le code JSON à partir de la boîte de dialogue qui s'affiche et, si vous le souhaitez, stockez-le dans une note en texte brut pour l'utiliser à l'étape suivante.

Étape 2 : Ajoutez le style à votre carte

  1. Dans Android Studio, dans le répertoire res , créez un répertoire de ressources et nommez-le raw. Vous utilisez les ressources de répertoire raw comme du code JSON.
  2. Créez un fichier nommé map_style.json dans res/raw.
  3. Collez votre code JSON mis en cache dans le nouveau fichier de ressources.
  4. Dans MapsActivity, créez une variable de classe TAG au-dessus de la méthode onCreate(). Cela sert à la journalisation.
private val TAG = MapsActivity::class.java.simpleName
  1. Toujours dans MapsActivity, créez une fonction setMapStyle() qui accepte un GoogleMap.
  2. Dans setMapStyle(), ajoutez un bloc try{}.
  3. Dans le bloc try{}, créez un val success pour la réussite du style. (Ajoutez le bloc catch suivant.)
  4. Dans le bloc try{}, définissez le style JSON sur la carte en appelant setMapStyle() sur l'objet GoogleMap. Transmettez un objet MapStyleOptions, qui charge le fichier JSON.
  5. Attribuez le résultat à success. La méthode setMapStyle() renvoie une valeur booléenne indiquant l'état de réussite de l'analyse du fichier de style et de la définition du style.
private fun setMapStyle(map: GoogleMap) {
   try {
       // Customize the styling of the base map using a JSON object defined
       // in a raw resource file.
       val success = map.setMapStyle(
           MapStyleOptions.loadRawResourceStyle(
               this,
               R.raw.map_style
           )
       )
   }
}
  1. Ajoutez une instruction if pour que success soit défini sur "false". Si le style ne fonctionne pas, imprimez un journal indiquant que l'analyse a échoué.
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
       if (!success) {
           Log.e(TAG, "Style parsing failed.")
       }
   }
}
  1. Ajoutez un bloc catch{} pour gérer la situation d'un fichier de style manquant. Dans le bloc catch, si le fichier ne peut pas être chargé, générez une Resources.NotFoundException.
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
   } catch (e: Resources.NotFoundException) {
       Log.e(TAG, "Can't find style. Error: ", e)
   }
}

Une fois terminée, la méthode doit se présenter comme suit :

private fun setMapStyle(map: GoogleMap) {
   try {
       // Customize the styling of the base map using a JSON object defined
       // in a raw resource file.
       val success = map.setMapStyle(
           MapStyleOptions.loadRawResourceStyle(
               this,
               R.raw.map_style
           )
       )

       if (!success) {
           Log.e(TAG, "Style parsing failed.")
       }
   } catch (e: Resources.NotFoundException) {
       Log.e(TAG, "Can't find style. Error: ", e)
   }
}
  1. Enfin, appelez la méthode setMapStyle() dans la méthode onMapReady() en transmettant votre objet GoogleMap.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   setMapStyle(map)
}
  1. Exécutez votre application.
  2. Définissez le mode de la carte sur normal. Le nouveau style devrait être visible, avec un thème rétro et des routes de la couleur de votre choix.

Étape 3 : Mettez en forme votre repère

Vous pouvez personnaliser davantage votre carte en stylisant les repères. Dans cette étape, vous allez remplacer les repères rouges par défaut par quelque chose de plus cool.

  1. Dans la méthode onMapLongClick(), ajoutez la ligne de code suivante au MarkerOptions() du constructeur pour utiliser le repère par défaut, mais en changeant la couleur en bleu.
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))

onMapLongClickListener() se présente maintenant comme suit :

map.setOnMapLongClickListener { latLng ->
   // A snippet is additional text that's displayed after the title.
   val snippet = String.format(
       Locale.getDefault(),
       "Lat: %1$.5f, Long: %2$.5f",
       latLng.latitude,
       latLng.longitude
   )
   map.addMarker(
       MarkerOptions()
           .position(latLng)
           .title(getString(R.string.dropped_pin))
           .snippet(snippet)
         .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
   )
}
  1. Exécutez l'application. Les repères qui s'affichent après un appui prolongé sont désormais bleus. Notez que les repères de POI sont toujours rouges, car vous n'avez pas ajouté de style à la méthode onPoiClick().

Pour personnaliser la carte Google, vous pouvez dessiner dessus. Cette technique est utile si vous souhaitez mettre en avant un type de lieu particulier, comme les lieux de pêche prisés.

  • Formes : vous pouvez ajouter des polylignes, des polygones et des cercles à la carte.
  • Objets GroundOverlay : une superposition au sol est une image fixée sur une carte. Contrairement aux repères, les superpositions au sol sont orientées vers la surface de la Terre plutôt que vers l'écran. Une rotation, une inclinaison ou un zoom sur la carte modifient l'orientation de l'image. Les superpositions au sol sont utiles lorsque vous souhaitez fixer une seule image sur une zone de la carte.

Étape : Ajouter une superposition au sol

Dans cette tâche, vous allez ajouter une superposition au sol en forme d'Android à votre position de départ.

  1. Téléchargez cette image Android et enregistrez-la dans votre dossier res/drawable. (Assurez-vous que le nom du fichier est android.png.)

  1. Dans onMapReady(), après l'appel pour déplacer la caméra vers la position de votre maison, créez un objet GroundOverlayOptions.
  2. Attribuez l'objet à une variable appelée androidOverlay.
val androidOverlay = GroundOverlayOptions()
  1. Utilisez la méthode BitmapDescriptorFactory.fromResource() pour créer un objet BitmapDescriptor à partir de la ressource d'image téléchargée.
  2. Transmettez l'objet BitmapDescriptor obtenu à la méthode image() de l'objet GroundOverlayOptions.
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
  1. Créez un float overlaySize pour la largeur en mètres de l'incrustation souhaitée. Dans cet exemple, une largeur de 100f fonctionne bien.

Définissez la propriété position pour l'objet GroundOverlayOptions en appelant la méthode position(), puis transmettez l'objet homeLatLng et le overlaySize.

val overlaySize = 100f
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
   .position(homeLatLng, overlaySize)
  1. Appelez addGroundOverlay() sur l'objet GoogleMap et transmettez votre objet GroundOverlayOptions.
map.addGroundOverlay(androidOverlay)
  1. Exécutez l'application.
  2. Remplacez la valeur de zoomLevel par 18f pour afficher l'image Android en superposition.

Les utilisateurs utilisent souvent Google Maps pour connaître leur position actuelle. Pour afficher la position de l'appareil sur votre carte, vous pouvez utiliser le calque de données de localisation.

Le calque de données de localisation ajoute Ma position à la carte. Lorsque l'utilisateur appuie sur le bouton, la carte se centre sur la position de l'appareil. Cette position est indiquée par un point bleu si l'appareil est fixe, ou par un chevron bleu si l'appareil est en mouvement.

Dans cette tâche, vous allez activer la couche de données de localisation.

Étape : Demander l'autorisation d'accéder à la position

L'activation du suivi de la position dans Google Maps ne nécessite qu'une seule ligne de code. Toutefois, vous devez vous assurer que l'utilisateur a accordé les autorisations de localisation (à l'aide du modèle d'autorisation d'exécution).

Dans cette étape, vous demandez l'autorisation d'accéder à la position et activez le suivi de la position.

  1. Dans le fichier AndroidManifest.xml, vérifiez que l'autorisation FINE_LOCATION est déjà présente. Android Studio a inséré cette autorisation lorsque vous avez sélectionné le modèle Google Maps.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  1. Dans MapsActivity, créez une variable de classe REQUEST_LOCATION_PERMISSION.
private val REQUEST_LOCATION_PERMISSION = 1
  1. Pour vérifier si les autorisations sont accordées, créez une méthode appelée isPermissionGranted() dans MapsActivity. Dans cette méthode, vérifiez si l'utilisateur a accordé l'autorisation.
private fun isPermissionGranted() : Boolean {
  return ContextCompat.checkSelfPermission(
       this,
      Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
  1. Pour activer le suivi de la position dans votre application, créez une méthode dans MapsActivity appelée enableMyLocation() qui ne prend aucun argument et ne renvoie rien. Recherchez l'autorisation ACCESS_FINE_LOCATION. Si l'autorisation est accordée, activez le calque de localisation. Sinon, demandez l'autorisation.
private fun enableMyLocation() {
   if (isPermissionGranted()) {
       map.isMyLocationEnabled = true 
   }
   else {
       ActivityCompat.requestPermissions(
           this,
           arrayOf<String>(Manifest.permission.ACCESS_FINE_LOCATION),
           REQUEST_LOCATION_PERMISSION
       )
   }
}
  1. Appelez enableMyLocation() à partir du rappel onMapReady() pour activer le calque de localisation.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   enableMyLocation()
}
  1. Remplacez la méthode onRequestPermissionsResult(). Si requestCode est égal à REQUEST_LOCATION_PERMISSION, l'autorisation est accordée. Si le tableau grantResults n'est pas vide et que PackageManager.PERMISSION_GRANTED se trouve dans son premier emplacement, appelez enableMyLocation().
override fun onRequestPermissionsResult(
   requestCode: Int,
   permissions: Array<String>,
   grantResults: IntArray) {
   if (requestCode == REQUEST_LOCATION_PERMISSION) {
       if (grantResults.contains(PackageManager.PERMISSION_GRANTED)) {
           enableMyLocation()
       }
   }
}
  1. Exécutez votre application. Une boîte de dialogue devrait s'afficher pour demander l'accès à la position de l'appareil. N'hésitez pas à accorder l'autorisation.

La carte affiche désormais la position actuelle de l'appareil à l'aide d'un point bleu. Notez la présence d'un bouton de localisation. Si vous déplacez la carte loin de votre position et que vous cliquez sur ce bouton, la carte est recentrée sur la position de l'appareil.

Téléchargez le code de l'atelier de programmation terminé.

$  git clone https://github.com/googlecodelabs/android-kotlin-geo-maps


Vous pouvez également télécharger le dépôt sous forme de fichier ZIP, le décompresser et l'ouvrir dans Android Studio.

Télécharger le fichier ZIP

  • Pour utiliser l'API Maps, vous avez besoin d'une clé API provenant de la console Google APIs.
  • Dans Android Studio, l'utilisation du modèle d'activité Google Maps génère un Activity avec un seul SupportMapFragment dans la mise en page de l'application. Le modèle ajoute également ACCESS_FINE_PERMISSION au fichier manifeste de l'application, implémente OnMapReadyCallback dans votre activité et remplace la méthode onMapReady() requise.

Pour modifier le type de carte d'un GoogleMap au moment de l'exécution, utilisez la méthode GoogleMap.setMapType(). Une carte Google peut être l'un des types de cartes suivants :

  • Normale : carte routière classique. Affiche les routes, certains ouvrages construits par l'homme et les éléments naturels importants comme les rivières. Les libellés des routes et des éléments géographiques sont également visibles.
  • Mixte : données de photographies satellite avec l'ajout de cartes routières. Les libellés des routes et des éléments géographiques sont également visibles.
  • Satellite : données photographiques. Les libellés des cartes et des éléments géographiques ne sont pas visibles.
  • Relief : données topographiques. La carte inclut des couleurs, des lignes de contour, des libellés et des ombres pour la perspective. Certaines routes et certains libellés sont également visibles.
  • Aucune  : aucune tuile de carte de base.

À propos de Google Maps :

  • Un repère est un indicateur pour un emplacement géographique spécifique.
  • Lorsque l'utilisateur appuie sur le repère, le comportement par défaut est d'afficher une fenêtre d'informations sur le lieu.
  • Par défaut, les points d'intérêt (POI) sont affichés sur la carte de base avec les icônes qui leur correspond. Les POI incluent les parcs, les écoles, les bâtiments administratifs, etc.
  • De plus, les POI commerciaux (magasins, restaurants, hôtels, etc.) s'affichent par défaut sur la carte lorsque le type de carte est défini sur normal.
  • Vous pouvez capturer les clics sur les POI à l'aide de OnPoiClickListener.
  • Vous pouvez modifier l'apparence visuelle de presque tous les éléments d'une carte Google à l'aide de l'assistant de style. L'assistant de style génère un fichier JSON que vous transmettez à Google Maps à l'aide de la méthode setMapStyle().
  • Vous pouvez personnaliser vos repères en changeant la couleur par défaut ou en remplaçant l'icône du repère par défaut par une image personnalisée.

Autres informations importantes :

  • Utilisez une superposition au sol pour fixer une image à un emplacement géographique.
  • Utilisez un objet GroundOverlayOptions pour spécifier l'image, sa taille en mètres et sa position. Transmettez cet objet à la méthode GoogleMap.addGroundOverlay() pour définir la superposition sur la carte.
  • À condition que votre application dispose de l'autorisation ACCESS_FINE_LOCATION, vous pouvez activer le suivi de la position en définissant map.isMyLocationEnabled = true.
  • Cet atelier de programmation ne traite pas de cette fonctionnalité, mais vous pouvez fournir des informations supplémentaires sur un lieu à l'aide de Google Street View, qui est une photo panoramique navigable d'un lieu donné.

Documentation pour les développeurs Android :

Documentation de référence :

Pour accéder aux autres ateliers de programmation de ce cours, consultez la page de destination des ateliers de programmation Android avancé en Kotlin.