Android avancé en langage Kotlin 04.1: Android Google Maps

Cet atelier de programmation fait partie du cours "Advanced Android" en langage Kotlin. Vous tirerez pleinement parti de ce cours si vous suivez les ateliers en séquence, mais ce n'est pas obligatoire. Tous les ateliers de programmation du cours sont répertoriés sur la page de destination des ateliers de programmation Android avancés sur Kotlin.

En créant des applications avec Google Maps, vous pouvez y ajouter des fonctionnalités telles que des images satellite, des commandes d'interface utilisateur robustes pour les cartes, le suivi de la position et des repères de position. Vous pouvez ajouter de la valeur à l'interface Google Maps standard en affichant des informations issues de votre propre ensemble de données, comme les lieux où il est possible de pratiquer l'escalade ou la pêche. Vous pouvez également créer des jeux dans lesquels le joueur explore le monde physique, comme une chasse au trésor ou même des jeux en 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 affiche la position de l'utilisateur.

Prerequisites

Connaissances suivantes:

  • Créer une application Android de base et l'exécuter avec Android Studio
  • Créer et gérer des ressources, telles que des chaînes
  • Refactoriser le code et renommer les variables dans Android Studio
  • Découvrez comment utiliser une carte Google en tant qu'utilisateur.
  • Comment définir des autorisations d'exécution

Points abordés

  • Obtenir une clé API dans la console Google APIs et l'enregistrer dans votre application
  • Intégrer une carte Google Maps à votre application
  • Afficher différents types de cartes
  • 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
  • Activer le suivi de la position
  • Créer l'application Wander, qui intègre un Google Maps
  • Créer des fonctionnalités personnalisées pour votre application, comme 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 à des emplacements, d'ajouter des superpositions 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 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 allez utiliser la clé API pour le certificat de débogage. Le certificat de débogage n'est pas sécurisé par nature, comme décrit dans la section Signer le 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 savoir comment obtenir un certificat de version, consultez Obtenir une clé API.

Android Studio inclut un modèle Google Maps Activity généré, 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éer le projet Wander avec le modèle de carte

  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 minimal d'API sur API 19. Assurez-vous que le langage est Kotlin.
  3. Cliquez sur Terminer.
  4. Une fois l'application créée, consultez votre projet et les fichiers Maps suivants créés par Android Studio:

google_maps_api.xml : ce fichier de configuration contient votre clé API. Le modèle génère deux fichiers google_maps_api.xml: un pour le débogage et l'autre pour la version. 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'utilisez 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. SupportMapFragment est le moyen le plus simple de placer une carte dans une application. Il s'agit d'un wrapper autour d'une 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 la SupportMapFragment dans la méthode onCreate() et utilise la classe getMapAsync() pour initialiser automatiquement le système de cartes et la vue. L'activité contenant la SupportMapFragment doit implémenter l'interface OnMapReadyCallback et la méthode onMapReady() correspondante. 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 dont l'URL est longue. Les paramètres d'URL comprennent 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. En raison des 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", puis cliquez sur la clé que vous venez de créer.
  7. Cliquez sur Restreindre la clé et 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_keyYOUR_KEY_HERE apparaît.
  10. Exécutez votre application. Une carte intégrée devrait s'afficher 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 modifiez ultérieurement.)

Étape 3: Renommez l'application mMap

MapsActivity dispose d'une lateinitvar mMap privée, de type GoogleMap. Pour respecter les conventions d'attribution des noms Kotlin, remplacez le nom mMap par map.

  1. Dans MapsActivity, faites un clic droit sur mMap, puis cliquez sur Refactoriser&gt ; Renommer

  1. Attribuez-lui le nom 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 carte: normale, hybride, satellite, relief et &nott (aucune carte).

Carte normale

Plan satellite

Carte hybride

Carte du relief

Chaque type de carte fournit différents types d'informations. Par exemple, lorsque vous utilisez la navigation dans une voiture, il est utile de voir les noms des rues. Vous pouvez donc utiliser cette option. Pendant la randonnée, la carte de relief peut vous aider à déterminer combien d'étages vous devez gravir 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. Placez le point de départ de la carte à votre adresse personnelle.
  3. Ajoutez la prise en charge des repères, qui indiquent des emplacements spécifiques sur une carte et peuvent inclure un libellé.

Ajouter un menu pour les types de carte

Lors de 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, faites un clic droit sur votre répertoire res, puis sélectionnez New > Android Resource File (Fichier de ressource Android).
  2. Dans la boîte de dialogue, nommez le fichier map_options.
  3. Choisissez le type de ressource Menu.
  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 n'y a pas du tout de carte. Cette étape provoque une erreur, mais vous la résolvez à 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, ignorez 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, ignorez la méthode onOptionsItemSelected(). Modifiez le type de carte à l'aide de constantes de type de carte 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. Notez que l'apparence de la carte change selon les différents modes.

Par défaut, le rappel onMapReady() inclut le code qui place un repère à Sydney, en Australie, où Google Maps a été créé. Le rappel par défaut anime également la vue panoramique de Sydney.

Dans cette tâche, vous allez déplacer la caméra sur la carte jusqu'à votre domicile, faire un zoom avant sur le niveau de votre choix, puis placer un repère.

Étape 1: Faire un zoom avant sur votre domicile et ajouter 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 longitude, puis saisissez une valeur flottante.
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 indiquer le niveau de zoom sur la carte. Utiliser le niveau de zoom 15f
val zoomLevel = 15f

Le niveau de zoom vous permet de déterminer le niveau de zoom sur la carte. La liste suivante vous donne une idée du niveau de détail associé à 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 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 sur la carte à l'adresse homeLatLng.
map.addMarker(MarkerOptions().position(homeLatLng))

Votre 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, faire un zoom avant jusqu'au niveau souhaité et placer un repère sur votre maison.

Étape 2: Autorisez les utilisateurs à ajouter un repère en effectuant un clic 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 bouchon de méthode dans MapsActivity appelé setMapLongClick() qui utilise 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 dont la position est définie sur l'élément 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 qui le centre à l'écran.

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

À 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 l'option title du repère sur "Repère placé" à l'aide d'une ressource de chaîne R.string.dropped_pin.
  2. Définissez le repère snippet 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: Ajoutez 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 (magasins, restaurants, hôtels, etc.).

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

  1. Créez un bouchon de méthode dans MapsActivity appelé setPoiClick() qui utilise 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 setOnPoiClickListener(), créez un val poiMarker pour le repère .
  2. Marquez-le sur un repère à l'aide de map.addMarker()MarkerOptionsettitle.
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 tel qu'un parc ou un café.
  2. Appuyez sur le POI 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, ce qui donne à votre carte une apparence unique.

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

Pour créer un style personnalisé pour votre carte, vous générez un fichier JSON qui indique la manière dont les éléments géographiques de la carte s'affichent. 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 après avoir stylisé visuellement votre carte. Dans cette tâche, vous allez appliquer un style rétro à la carte, ce qui signifie qu'elle utilise des couleurs vintage et que vous ajoutez des routes colorées.

Étape 1: Créer 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. Modifier la couleur des routes dans l'une des couleurs de votre choix (rose, par exemple)

  1. Cliquez sur Terminer.

  1. Copiez le code JSON obtenu à partir de la boîte de dialogue obtenue. Si vous le souhaitez, placez-le dans une note en texte brut pour l'utiliser à l'étape suivante.

Étape 2: Ajoutez un style à la carte

  1. Dans le répertoire res Android Studio, créez un répertoire de ressources et nommez-le raw. Vous utilisez les ressources d'annuaire raw comme le code JSON.
  2. Dans res/raw, créez un fichier nommé map_style.json.
  3. Collez votre code JSON bloqué dans le nouveau fichier de ressources.
  4. Dans MapsActivity, créez une variable de classe TAG au-dessus de la méthode onCreate(). Ces informations sont utilisées à des fins de journalisation.
private val TAG = MapsActivity::class.java.simpleName
  1. Toujours dans MapsActivity, créez une fonction setMapStyle() qui utilise un GoogleMap.
  2. Dans setMapStyle(), ajoutez un bloc try{}.
  3. Dans le bloc try{}, créez un val success pour assurer le succès du style. (Vous allez ajouter 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 l'état 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 si la valeur de success est"false". Si le 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 dans un fichier de style manquant. Dans le bloc catch, si le fichier ne peut pas être chargé, générez un élément Resources.NotFoundException.
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
   } catch (e: Resources.NotFoundException) {
       Log.e(TAG, "Can't find style. Error: ", e)
   }
}

La méthode finale doit 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. Configurez la carte en mode normal. Le nouveau style doit être visible avec des thèmes rétro et des routes de la couleur de votre choix.

Étape 3: Définissez le style de 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 un aspect plus stylé.

  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 définissez la couleur sur 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 lorsque vous appuyez de manière prolongée 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 Maps, vous pouvez dessiner sur celle-ci. Cette technique est utile si vous souhaitez mettre en évidence un type de lieu particulier (par exemple des sites de pêche populaires).

  • 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 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 domicile.

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

  1. Dans onMapReady(), après l'appel pour déplacer la caméra à 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 dans 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 de l'objet GroundOverlayOptions en appelant la méthode position() et 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 l'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.

Les utilisateurs se servent souvent de Google Maps pour vérifier 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 est centrée sur l'appareil. Cette position est représentée par un point bleu si l'appareil est fixe, et par un chevron bleu si l'appareil est en mouvement.

Dans cette tâche, vous allez activer le calque de données de localisation.

Étape: Demandez l'autorisation de géolocalisation

L'activation du suivi de la position dans Google Maps ne nécessite qu'une seule ligne de code. Vous devez toutefois vérifier que l'utilisateur a accordé des autorisations d'accéder à la position (à l'aide du modèle d'autorisations d'exécution).

Cette étape consiste à 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 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 n'accepte aucun argument et ne renvoie rien. Dans ce dossier, recherchez l'autorisation ACCESS_FINE_LOCATION. Si l'autorisation est accordée, activez le calque de zone géographique. 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 position.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   enableMyLocation()
}
  1. Ignorez la méthode onRequestPermissionsResult(). Si l'autorisation requestCode est égale à REQUEST_LOCATION_PERMISSION, et si le tableau grantResults n'est pas vide et que PackageManager.PERMISSION_GRANTED est vide 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 appli. Une boîte de dialogue doit s'afficher pour demander l'accès à la position de l'appareil. Demandez l'autorisation.

La position actuelle de l'appareil est représentée par un point bleu sur la carte. Notez qu'il existe un bouton d'emplacement. Si vous éloignez la carte de votre position et cliquez sur ce bouton, la carte est centrée sur l'appareil.

Téléchargez le code pour 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 Google 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 la OnMapReadyCallback dans votre activité et remplace la méthode onMapReady() requise.

Pour modifier le type de carte d'un élément GoogleMap au moment de l'exécution, utilisez la méthode GoogleMap.setMapType(). Les types de carte Google Maps sont les suivants:

  • Normal : 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.
  • Hybride : 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 photo. 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 carte de base.

À propos de Google Maps:

  • Un repère est un indicateur d'emplacement géographique spécifique.
  • Lorsque l'utilisateur appuie dessus, le comportement par défaut du repère 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.
  • Par ailleurs, les POI commerciaux (magasins, restaurants, hôtels, etc.) s'affichent par défaut sur la carte lorsque le type de la carte est normal.
  • Vous pouvez capturer les clics sur des POI à l'aide de la OnPoiClickListener.
  • Vous pouvez modifier l'apparence de presque tous les éléments d'une carte Google Maps à 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().
  • Pour personnaliser vos repères, vous pouvez modifier la couleur par défaut ou remplacer l'icône par défaut par une image personnalisée.

Autres informations importantes :

  • Utilisez une superposition au sol pour corriger une image dans un emplacement géographique.
  • Utilisez un objet GroundOverlayOptions pour spécifier l'image, la taille de l'image en mètres et sa position. Transmettez cet objet à la méthode GoogleMap.addGroundOverlay() pour définir la superposition sur la carte.
  • Si votre appli dispose de l'autorisation ACCESS_FINE_LOCATION, vous pouvez activer le suivi de la position en définissant map.isMyLocationEnabled = true.
  • Nous n'en parlerons pas dans cet atelier de programmation, mais vous pouvez fournir des informations supplémentaires sur un lieu à l'aide de Google Street View, une photo panoramique avec vue d'un lieu donné.

Documentation pour les développeurs Android:

Documentation de référence:

Pour obtenir des liens vers d'autres ateliers de programmation dans ce cours, consultez la page de destination Advanced Android dans Kotlin.