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

1. Avant de commencer

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 de 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, qui contient 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

2. Présentation de l'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.

5b12eda7f467bc2f.png

3. Tâche : Configurer le projet et obtenir une clé API

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 version, 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.

d6b874bb19ea68cd.png

  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 nécessaires du cycle de vie.

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é qui contient 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 ultérieurement.)

34dc9dd877c90996.png

É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).

e713ccb3384450c6.png

  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.

4. Tâche : Ajouter des types de cartes

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 en 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" est omis, car il ne permet d'afficher 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 428da163b831115b.png pour modifier le type de carte. Notez comment l'apparence de la carte change entre les différents modes.

6fa42970d87f5dc7.png

5. Tâche : Ajouter des repères

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 maintenant 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 contrôle 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 transmettez 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.

fc939024778ee76.png

É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.

4ff8d1c1db3bca9e.png

É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.

63f210e6e47dfa29.png

É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 immédiatement un repère sur la carte 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.

f4b0972c75d5fa5f.png

6. Tâche : Appliquer un style à votre carte

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 la façon dont 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 de style Maps Platform, 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.

208b3d3aeab0d9b6.png

  1. Cliquez sur Plus d'options.

4a35faaf9535ee82.png

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

92c3293749293a4c.png

  1. Cliquez sur Terminer.

f1bfe8585eb69480.png

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

3c32168b299d6420.png

É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(). Il est utilisé à des fins de 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.

b59d6cb81f02a14f.png

É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 à 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().

b9916bca3c367e3.png

7. Tâche : Ajouter une superposition

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.
  • GroundOverlay objects : 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 corriger 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.)

61fabd56a0841b44.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 la superposition 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 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.

b1b25b0acd6a9807.png

8. Tâche : Activer le suivi de la position

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 l'icône Ma position à la carte.

f317f84dcb3ac3a1.png

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 des autorisations ont été 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(). Vérifiez si requestCode est égal à REQUEST_LOCATION_PERMISSION. Si c'est le cas, cela signifie que l'autorisation est accordée. Si l'autorisation est accordée, vérifiez également si le tableau grantResults contient PackageManager.PERMISSION_GRANTED dans son premier emplacement. Si tel est le cas, 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.

da7e23e00ec762c1.png

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

5b12eda7f467bc2f.png

9. Code de solution

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.

10. Résumé

Félicitations ! Vous avez ajouté une carte Google à une application Android Kotlin et l'avez stylisée.

11. En savoir plus

Documentation pour les développeurs Android :

Documentation de référence :

12. Atelier de programmation suivant

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