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

1. Avant de commencer

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

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

Prérequis

Connaissance des éléments suivants:

  • 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
  • Refactoriser le code et renommer les variables à l'aide d'Android Studio
  • Utiliser une carte Google en tant qu'utilisateur
  • Définir des autorisations d'exécution

Points abordés

  • Comment obtenir une clé API à partir de la console Google APIs et l'enregistrer dans votre application
  • Intégrer une carte Google Maps à votre application
  • Afficher différents types de carte
  • Appliquer un style à la carte Google
  • Ajouter des repères à votre carte
  • Permettre à l'utilisateur de placer un repère sur un point d'intérêt (POI)
  • Activer le suivi de la position
  • Créer l'application Wander, qui intègre une carte Google
  • 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 superpositions 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 dans le dossier API et la page "Services". La clé API est liée à un certificat numérique qui associe l'application à son auteur. Pour en savoir plus sur l'utilisation de certificats numériques et la signature de votre application, consultez Signer votre application.

Dans cet atelier de programmation, vous utiliserez la clé API pour le certificat de débogage. La conception du certificat de débogage n'est pas sécurisée, comme décrit dans la section Signer votre version 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 plus d'informations 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 carte

  1. Créez un projet Android Studio.
  2. Sélectionnez le modèle Google Maps Activity (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 Kotlin.
  3. Cliquez sur Terminer.
  4. Une fois la compilation de l'application terminée, examinez votre projet et les fichiers de mappage suivants qu'Android Studio crée pour vous:

google_maps_api.xml : ce fichier de configuration sert à 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 publication. 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 pour le 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 occupe la totalité de l'écran. La classe SupportMapFragment est une sous-classe de Fragment. 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 permettant de gérer automatiquement les besoins liés au 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.java instancie SupportMapFragment dans la méthode onCreate() et utilise la classe getMapAsync() pour initialiser automatiquement le système Google Maps 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 lors du chargement de la carte.

É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 avec une URL longue. 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 la page "Services". Grâce aux paramètres de l'URL fournie, la page sait qu'il faut 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", puis cliquez sur la clé que vous venez de créer.
  7. Cliquez sur Restreindre la clé, puis sélectionnez SDK Maps pour Android afin de 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'emplacement 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 marqueur de Sydney fait partie du modèle et vous le modifierez ultérieurement.)

34dc9dd877c90996.png

Étape 3: Renommez le fichier mMap

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

  1. Dans MapsActivity, effectuez un clic droit sur mMap, puis cliquez sur Refactor (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 carte

Google Maps propose plusieurs types de cartes: normale, hybride, satellite, relief et "aucun". (aucune carte du tout).

Carte de normales

Carte satellite

Carte hybride

Carte en relief

Chaque type de carte fournit différents types d'informations. Par exemple, lorsque vous utilisez des cartes pour la navigation dans une voiture, il est utile de voir les noms des rues. Vous pouvez donc utiliser l'option normale. Lorsque vous faites de la randonnée, la carte du relief peut vous aider à déterminer combien de points vous devez encore grimper pour atteindre le sommet.

Dans cette tâche, vous allez:

  1. Ajoutez une barre d'application avec un menu d'options permettant à l'utilisateur de modifier le type de carte.
  2. Déplacez le point de départ de la carte vers votre propre emplacement.
  3. Ajoutez la prise en charge des repères, qui indiquent des lieux spécifiques sur une carte et peuvent inclure un libellé.

Menu "Ajouter" pour les types de carte

Au cours de cette étape, vous allez ajouter une barre d'application avec un menu d'options permettant à 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 (Nouveau) > Fichier de ressources Android
  2. Dans la boîte de dialogue, nommez le fichier map_options.
  3. Choisissez Menu comme 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. La commande "none" type de carte est omis, car "aucun" se traduit par l'absence totale de 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 gonflez 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 de constantes de type map pour refléter le choix 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 que l'apparence de la carte change selon les différents modes.

6fa42970d87f5dc7.png

5. Tâche: Ajouter des repères

Par défaut, le rappel onMapReady() inclut un 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 effectuer un panoramique sur Sydney.

Dans cette tâche, vous allez déplacer la caméra de la carte vers votre domicile, zoomer au niveau de votre choix et placer un repère à cet endroit.

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

  1. Dans le fichier MapsActivity.kt, recherchez la méthode onMapReady(). Supprimez-y 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 connaître 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 correspondant au niveau de zoom avant que vous souhaitez appliquer à la carte. Utiliser le niveau de zoom 15f.
val zoomLevel = 15f

Le niveau de zoom contrôle le niveau de zoom avant sur la carte. La liste suivante vous donne une idée du niveau de détail affiché par chaque niveau de zoom:

  • 1: monde
  • 5: masse continentale/continent
  • 10: ville
  • 15: rues
  • 20: bâtiments
  1. Déplacez la caméra vers 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 sur la carte à l'adresse 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 se déplacer vers votre domicile, zoomer au niveau souhaité et placer un repère sur votre maison.

fc939024778ee76.png

Étape 2: Autorisez les utilisateurs à ajouter un repère à l'aide d'un clic long

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

  1. Créez un bouchon de méthode dans MapsActivity appelé setMapLongClick() qui accepte un GoogleMap comme argument.
  2. Associez un écouteur setOnMapLongClickListener à l'objet map.
private fun setMapLongClick(map:GoogleMap) {
   map.setOnMapLongClickListener { }
}
  1. Dans setOnMapLongClickListener(), appelez la méthode addMarker(). Transmettez un nouvel objet MarkerOptions dont la position est définie sur la valeur LatLng transmise.
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 à l'endroit souhaité.
  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 "Repère placé" à 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) sont affichés 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 dès que l'utilisateur clique sur un POI. L'écouteur de clics affiche également une fenêtre d'informations contenant le nom du POI.

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

   }
}
  1. Dans 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 en définissant title sur le nom du POI.
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()

Le code final de 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 recherchez un POI, comme un parc ou un café.
  2. Appuyez sur un POI pour y placer un repère et afficher son nom dans une fenêtre d'informations.

f4b0972c75d5fa5f.png

6. Tâche: Appliquer un style à la 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 tout autre fragment. Toutefois, au cours de 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, vous devez générer un fichier JSON qui spécifie la façon dont les éléments géographiques 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 fichier JSON une fois que vous avez appliqué un style visuel à votre carte. Dans cette tâche, vous allez appliquer un style rétro à la carte, ce qui signifie qu'elle utilise des couleurs d'époque et que vous ajoutez des routes en couleur.

É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. Modifiez la couleur des routes en choisissant la couleur de votre choix (rose, par exemple).

92c3293749293a4c.png

  1. Cliquez sur Terminer.

f1bfe8585eb69480.png

  1. Copiez le code JSON de la boîte de dialogue qui s'affiche et, si vous le souhaitez, placez-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 le code JSON.
  2. Dans res/raw, créez un fichier appelé map_style.json.
  3. Collez le code JSON stocké 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 reçoit un GoogleMap.
  2. Dans setMapStyle(), ajoutez un bloc try{}.
  3. Dans le bloc try{}, créez un val success pour que le style réussisse. (Vous ajoutez le bloc "catch" suivant.)
  4. Dans le bloc try{}, définissez le style JSON sur la carte, appelez 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 si l'analyse du fichier de style et la définition du style ont réussi.
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 indiquer que success est "false". Si l'application du style échoue, 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 exception 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 devrait ressembler à l'extrait de code suivant:

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 normal sur la carte pour que le nouveau style soit visible avec un thème rétro et des routes de la couleur choisie.

b59d6cb81f02a14f.png

Étape 3: Appliquez un style à votre repère

Vous pouvez personnaliser davantage votre carte en appliquant un style à ses repères. Au cours de cette étape, vous allez modifier les repères rouges par défaut pour leur donner un style plus groovy.

  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 changez 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 clic long s'affichent désormais en bleu. 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

Vous pouvez personnaliser la carte Google en dessinant dessus. Cette technique est utile si vous souhaitez mettre en évidence un type de lieu particulier, comme des lieux de pêche populaires.

  • Formes:vous pouvez ajouter des polylignes, des polygones et des cercles à la carte.
  • GroundOverlay objets: 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 et non vers l'écran. Faire pivoter, incliner ou zoomer sur la carte modifie 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: Ajoutez une superposition au sol

Dans cette tâche, vous allez ajouter une superposition au sol de la forme d'un Android à votre domicile.

  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 visant à déplacer la caméra sur 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 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 une float overlaySize pour la largeur en mètres de la superposition souhaitée. Dans cet exemple, une largeur de 100f convient bien.

Définissez la propriété position de 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. Définissez la valeur de zoomLevel sur 18f pour afficher l'image Android en superposition.

b1b25b0acd6a9807.png

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

Les utilisateurs se servent souvent de 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 est centrée sur la position de l'appareil. La position est affichée sous la forme d'un point bleu si l'appareil est fixe et d'un chevron bleu si l'appareil est en mouvement.

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

Étape: Demandez 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 autorisé l'accès à sa position (à l'aide du modèle d'autorisation d'exécution).

Au cours de cette étape, vous allez demander l'autorisation d'accéder à la position et activer 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 dans MapsActivity appelée isPermissionGranted(). Avec 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 n'accepte aucun argument et ne renvoie rien. Dans cette section, 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 c'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 doit s'afficher pour demander l'accès à la position de l'appareil. Allez-y et accordez l'autorisation.

da7e23e00ec762c1.png

La position actuelle de l'appareil est maintenant affichée à l'aide d'un point bleu sur la carte. Vous remarquerez qu'il y a un bouton de localisation. Si vous éloignez la carte de votre position et cliquez sur ce bouton, la carte est centré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 en Kotlin et lui avez appliqué un style.

11. En savoir plus

Documentation pour les développeurs Android :

Documentation de référence:

12. Atelier de programmation suivant

Pour obtenir des liens vers d'autres ateliers de ce cours, consultez la page de destination des ateliers de programmation avancés pour Android en Kotlin.