Android avanzato in Kotlin 04.1: Google Maps per Android

Questo codelab fa parte del corso Advanced Android in Kotlin. Otterrai il massimo valore da questo corso se lavori in sequenza nei codelab, ma non è obbligatorio. Tutti i codelab del corso sono elencati nella pagina di destinazione avanzata per i codelab di Android in Kotlin.

Lo sviluppo di app con Google Maps ti consente di aggiungere funzionalità alla tua app, come immagini satellitari, solidi controlli dell'interfaccia utente per mappe, monitoraggio della posizione e indicatori di posizione. Puoi aggiungere valore al Google Maps standard mostrando le informazioni del tuo set di dati, come le località di zone note per la pesca o l'arrampicata. Puoi anche creare giochi in cui il giocatore esplora il mondo fisico, ad esempio in una caccia al tesoro o persino in giochi di realtà aumentata.

In questa lezione, creerai un'app di Google Maps chiamata Wander che mostra mappe personalizzate e mostra la posizione dell'utente.

Prerequisiti

Conoscenza dei seguenti aspetti:

  • Come creare un'app Android di base ed eseguirla tramite Android Studio.
  • Come creare e gestire risorse, ad esempio le stringhe.
  • Come effettuare il refactoring del codice e rinominare le variabili utilizzando Android Studio.
  • Come utilizzare una mappa Google come utente.
  • Come impostare le autorizzazioni di runtime.

Obiettivi didattici

  • Come ottenere una chiave API dalla console API di Google e registra la chiave nella tua app
  • Come integrare una mappa Google nell'app
  • Come visualizzare diversi tipi di mappa
  • Come applicare stili alla mappa Google
  • Come aggiungere indicatori alla mappa
  • Come consentire all'utente di posizionare un indicatore su un punto di interesse (PDI)
  • Come attivare il monitoraggio della posizione
  • Come creare l'app Wander, che include una mappa Google incorporata
  • Come creare funzionalità personalizzate per la tua app, ad esempio indicatori e stili
  • Come attivare il monitoraggio della posizione nell'app

In questo codelab, crei l'app Wander, che mostra una mappa Google con uno stile personalizzato. L'app Wander ti consente di inserire gli indicatori in posizioni diverse, aggiungere overlay e visualizzare la tua posizione in tempo reale.

L'SDK Maps per Android richiede una chiave API. Per ottenere la chiave API, registra il progetto nella pagina API &Services. La chiave API è associata a un certificato digitale che collega l'app all'autore. Per ulteriori informazioni sull'utilizzo dei certificati digitali e sulla firma della tua app, vedi Firmare l'app.

In questo codelab, utilizzerai la chiave API per il certificato di debug. Il certificato di debug non è sicuro per impostazione predefinita, come descritto in Firmare la build di debug. Le app Android pubblicate che utilizzano l'SDK Maps per Android richiedono una seconda chiave API: la chiave per il certificato di rilascio. Per ulteriori informazioni su come ottenere un certificato di rilascio, consulta Ottenere una chiave API.

Android Studio include un modello di attività di Google Maps, che genera un codice modello utile. Il codice del modello include un file google_maps_api.xml contenente un link che semplifica l'acquisizione di una chiave API.

Passaggio 1: crea il progetto Wander con il modello di Maps

  1. Crea un nuovo progetto Android Studio.
  2. Seleziona il modello Attività di Google Maps.

  1. Assegna al progetto il nome Wander.
  2. Imposta il livello minimo dell'API su API 19. Assicurati che la lingua sia Kotlin.
  3. Fai clic su Fine.
  4. Una volta completata la creazione dell'app, dai un'occhiata al tuo progetto e ai seguenti file relativi a Maps che Android Studio crea per te:

google_maps_api.xml: utilizzi questo file di configurazione per contenere la chiave API. Il modello genera due file google_maps_api.xml: uno per il debug e uno per la versione. Il file per la chiave API per il certificato di debug si trova in src/debug/res/values. Il file per la chiave API del certificato di rilascio si trova in src/release/res/values. In questo codelab, utilizzi solo il certificato di debug.

activity_maps.xml: questo file di layout contiene un singolo frammento che riempie l'intero schermo. La classe SupportMapFragment è una sottoclasse della classe Fragment. Un SupportMapFragment è il modo più semplice per inserire una mappa in un'app. È un wrapper attorno a una visualizzazione di una mappa che gestisce automaticamente le esigenze del ciclo di vita necessarie.

Puoi includere SupportMapFragment in un file di layout utilizzando un tag <fragment> in qualsiasi elemento ViewGroup, con un attributo name aggiuntivo.

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

MapsActivity.java: il file MapsActivity.kt crea un'istanza di SupportMapFragment nel metodo onCreate() e utilizza la classe' getMapAsync() per inizializzare automaticamente il sistema Maps e la vista. L'attività che contiene SupportMapFragment deve implementare l'interfaccia di OnMapReadyCallback e il metodo onMapReady() dell'interfaccia. Il metodo onMapReady() viene chiamato quando la mappa viene caricata.

Passaggio 2: ottieni la chiave API

  1. Apri la versione di debug del file google_maps_api.xml.
  2. Nel file, cerca un commento con un URL lungo. I parametri URL includono informazioni specifiche sulla tua app.
  3. Copia e incolla l'URL in un browser.
  4. Segui le istruzioni per creare un progetto nella pagina API e servizi. A causa dei parametri nell'URL fornito, la pagina sa attivare automaticamente l'SDK Maps per Android.
  5. Fai clic su Crea una chiave API.
  6. Nella pagina successiva, vai alla sezione Chiavi API e fai clic sulla chiave appena creata.
  7. Fai clic su Limita la chiave e seleziona SDK Maps per Android per limitare l'utilizzo della chiave alle app Android.
  8. Copia la chiave API generata. Inizia con "AIza"".
  9. Nel file google_maps_api.xml, incolla la chiave nella stringa google_maps_key dove si trova YOUR_KEY_HERE.
  10. Esegui la tua app. Nella tua attività, dovresti visualizzare una mappa incorporata con un indicatore impostato a Sydney, in Australia. L'indicatore di Sydney fa parte del modello e lo modifichi in un secondo momento.

Passaggio 3: rinomina la mappa per mMap

MapsActivity ha un lateinit var privato di tipo mMap, di tipo GoogleMap. Per seguire le convenzioni di denominazione Kotlin, cambia il nome di mMap in map.

  1. In MapsActivity, fai clic con il pulsante destro del mouse su mMap e scegli Refactor> Rinomina...

  1. Cambia il nome della variabile in map.

Nota che anche tutti i riferimenti a mMap nella funzione onMapReady() cambiano in map.

Google Maps offre diversi tipi di mappa: normale, ibrida, satellite, rilievo e "nessuno" (per niente).

Mappa normale

Mappa satellitare

Mappa ibrida

Mappa rilievo

Ogni tipo di mappa fornisce diversi tipi di informazioni. Ad esempio, se utilizzi le mappe per la navigazione in auto, è utile visualizzare i nomi delle strade, quindi puoi utilizzare l'opzione normale. Durante l'escursionismo, la mappa del terreno potrebbe essere utile per decidere quanto altro devi salire per arrivare in cima.

In questa attività:

  1. Aggiungi una barra delle app con un menu opzioni che consente all'utente di modificare il tipo di mappa.
  2. Sposta la posizione iniziale della mappa nella tua posizione di casa.
  3. Aggiungi il supporto per gli indicatori, che indicano singole posizioni su una mappa e possono includere un'etichetta.

Aggiungi menu per i tipi di mappa

In questo passaggio devi aggiungere una barra delle app con un menu opzioni che consente all'utente di modificare il tipo di mappa.

  1. Per creare un nuovo file XML di menu, fai clic con il pulsante destro del mouse sulla directory res e seleziona New > Android Resource File (File di risorse Android).
  2. Nella finestra di dialogo, assegna al file il nome map_options.
  3. Scegli Menu per il tipo di risorsa.
  4. Fai clic su OK.
  5. Nella scheda Codice, sostituisci il codice nel nuovo file con il codice seguente per creare le opzioni del menu mappa. Il tipo di mappa "none" viene omesso perché "none" comporta la mancanza di una mappa. Questo passaggio causa un errore, ma viene risolto nel passaggio successivo.
<?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. In strings.xml, aggiungi risorse per gli attributi title per risolvere gli errori.
<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. In MapsActivity, sostituisci il metodo onCreateOptionsMenu() e gonfia il menu dal file della risorsa map_options.
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
   val inflater = menuInflater
   inflater.inflate(R.menu.map_options, menu)
   return true
}
  1. In MapsActivity.kt, sostituisci il metodo onOptionsItemSelected(). Modifica il tipo di mappa utilizzando le costanti dei tipi di mappa per riflettere la selezione dell'utente.
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. Esegui l'app.
  2. Fai clic su per modificare il tipo di mappa. Nota come l'aspetto della mappa cambia tra le diverse modalità.

Per impostazione predefinita, il callback onMapReady() include codice che posiziona un indicatore a Sydney, in Australia, dove è stato creato Google Maps. Il callback predefinito anima la mappa anche per una panoramica su Sydney.

In questa attività, fai in modo che la fotocamera della mappa si sposti sulla tua casa, esegui lo zoom sul livello da te specificato e inserisci lì un indicatore.

Passaggio 1: esegui lo zoom a casa e aggiungi un indicatore

  1. Nel file MapsActivity.kt, trova il metodo onMapReady(). Rimuovi il codice al suo interno che posiziona l'indicatore a Sydney e sposta la videocamera. Ecco come dovrebbe apparire il metodo.
override fun onMapReady(googleMap: GoogleMap) {
   map = googleMap

}
  1. Trova le coordinate di latitudine e longitudine della tua casa seguendo queste istruzioni.
  2. Crea un valore per la latitudine e un valore per la longitudine e inserisci i valori in virgola mobile.
val latitude = 37.422160
val longitude = -122.084270
  1. Crea un nuovo oggetto LatLng chiamato homeLatLng. Nell'oggetto homeLatLng, trasmetti i valori appena creati.
val homeLatLng = LatLng(latitude, longitude)
  1. Crea un val per definire lo zoom desiderato per comparire sulla mappa. Utilizza il livello di zoom 15f.
val zoomLevel = 15f

Il livello di zoom controlla lo zoom aumentato sulla mappa. Il seguente elenco ti dà un'idea del livello di dettaglio che mostra ogni livello di zoom:

  • 1: mondo
  • 5: terra/continente
  • 10: città
  • 15: strade
  • 20: edifici
  1. Sposta la fotocamera in homeLatLng chiamando la funzione moveCamera() sull'oggetto map e passando un oggetto CameraUpdate utilizzando CameraUpdateFactory.newLatLngZoom(). Passa l'oggetto homeLatLng e l'elemento zoomLevel.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
  1. Aggiungi un indicatore alla mappa presso homeLatLng.
map.addMarker(MarkerOptions().position(homeLatLng))

Il metodo finale dovrebbe avere il seguente aspetto:

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. Esegui l'app. La mappa deve spostarti sulla tua casa, aumentare lo zoom fino al livello desiderato e posizionare un indicatore sulla casa.

Passaggio 2: consenti agli utenti di aggiungere un indicatore utilizzando un clic lungo

In questo passaggio devi aggiungere un indicatore quando l'utente tocca e tiene premuto un punto sulla mappa,

  1. Crea in un MapsActivity il metodo stub, denominato setMapLongClick(), che utilizza GoogleMap come argomento.
  2. Allega un listener setOnMapLongClickListener all'oggetto mappa.
private fun setMapLongClick(map:GoogleMap) {
   map.setOnMapLongClickListener { }
}
  1. In setOnMapLongClickListener(), chiama il metodo addMarker(). Trasmetti un nuovo oggetto MarkerOptions con la posizione impostata nel valore LatLng passato.
private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       map.addMarker(
           MarkerOptions()
               .position(latLng)
       )
   }
}
  1. Alla fine del metodo onMapReady(), chiama setMapLongClick() con map.
override fun onMapReady(googleMap: GoogleMap) {
   ...
  
   setMapLongClick(map)
}
  1. Esegui la tua app.
  2. Tocca e tieni premuta la mappa per posizionare un indicatore in un luogo,
  3. Tocca l'indicatore al centro dello schermo.

Passaggio 3: aggiungi una finestra informativa per l'indicatore

In questo passaggio devi aggiungere un InfoWindow che visualizza le coordinate dell'indicatore quando viene toccato.

  1. In setMapLongClick()setOnMapLongClickListener(), crea un val per snippet. Uno snippet è il testo aggiuntivo visualizzato dopo il titolo. Lo snippet mostra la latitudine e la longitudine di un indicatore.
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. In addMarker(), imposta title dell'indicatore su Segnaposto inserito utilizzando una risorsa stringa R.string.dropped_pin.
  2. Imposta snippet per l'indicatore su snippet.

La funzione completata ha il seguente aspetto:

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. Esegui la tua app.
  2. Tocca e tieni premuta la mappa per inserire un indicatore di posizione.
  3. Tocca l'indicatore per visualizzare la finestra informativa.

Passaggio 4: aggiungi il listener dei PDI

Per impostazione predefinita, i punti di interesse vengono visualizzati sulla mappa insieme alle icone corrispondenti. I PDI includono parchi, scuole, edifici governativi e altro ancora. Se il tipo di mappa è impostato su normal, i PDI aziendali vengono visualizzati anche sulla mappa. I PDI aziendali rappresentano attività, come negozi, ristoranti e hotel.

In questo passaggio devi aggiungere una GoogleMap.OnPoiClickListener alla mappa. Questo listener di clic posiziona un indicatore sulla mappa immediatamente quando l'utente fa clic su un PDI. Il listener di clic mostra anche una finestra informativa contenente il nome del PDI.

  1. Crea in un MapsActivity il metodo stub, denominato setPoiClick(), che utilizza GoogleMap come argomento.
  2. Nel metodo setPoiClick(), imposta un OnPoiClickListener nel GoogleMap inviato.
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->

   }
}
  1. In setOnPoiClickListener(), crea un val poiMarker per l'indicatore .
  2. Imposta il valore di PDI su map.addMarker() utilizzando MarkerOptions impostando title sul nome del PDI.
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->
       val poiMarker = map.addMarker(
           MarkerOptions()
               .position(poi.latLng)
               .title(poi.name)
       )
   }
}
  1. Nella funzione setOnPoiClickListener(), chiama showInfoWindow() al numero poiMarker per visualizzare immediatamente la finestra informativa.
poiMarker.showInfoWindow()

Il codice finale per la funzione setPoiClick() dovrebbe essere simile al seguente.

private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->
       val poiMarker = map.addMarker(
           MarkerOptions()
               .position(poi.latLng)
               .title(poi.name)
       )
       poiMarker.showInfoWindow()
   }
}
  1. Alla fine di onMapReady(), chiama setPoiClick() e passa tra map.
override fun onMapReady(googleMap: GoogleMap) {
   ...

   setPoiClick(map)
}
  1. Esegui l'app e trova un PDI, ad esempio un parco o una caffetteria.
  2. Tocca il PDI per posizionare un indicatore e visualizzare il nome del PDI in una finestra informativa.

Puoi personalizzare Google Maps in diversi modi, garantendo un aspetto unico alla tua mappa.

Puoi personalizzare un oggetto MapFragment utilizzando gli attributi XML disponibili, come faresti per qualsiasi altro frammento. Tuttavia, in questo passaggio puoi personalizzare l'aspetto e il design dei contenuti di MapFragment utilizzando i metodi presenti nell'oggetto GoogleMap.

Per creare uno stile personalizzato per la mappa, devi generare un file JSON che specifichi la modalità di visualizzazione delle funzionalità nella mappa. Non devi creare questo file JSON manualmente. Google fornisce la procedura guidata per l'applicazione di stili di Maps Platform, che genera il file JSON per te dopo che hai definito visivamente la mappa. In questa attività puoi assegnare alla mappa uno stile retrò, ovvero utilizzare colori vintage e aggiungere strade colorate.

Passaggio 1: crea uno stile per la mappa

  1. Vai all'indirizzo https://mapstyle.withgoogle.com/ nel browser.
  2. Seleziona Crea uno stile.
  3. Seleziona Retro.

  1. Fai clic su Altre opzioni.

  1. Nell'elenco Tipo di elemento seleziona Strada> Riempimento.
  2. Modifica il colore delle strade con il colore che preferisci (ad esempio il rosa).

  1. Fai clic su Fine.

  1. Copia il codice JSON dalla finestra di dialogo risultante e, se vuoi, mettilo in una nota di testo normale da usare nel passaggio successivo.

Passaggio 2: aggiungi lo stile alla mappa

  1. In Android Studio, nella directory res , crea una directory delle risorse e assegnale il nome raw. Utilizzi le risorse di directory raw come il codice JSON.
  2. Crea un file in map_style.json denominato res/raw.
  3. Incolla il codice JSON nascosto nel nuovo file di risorse.
  4. In MapsActivity, crea una variabile di classe TAG sopra il metodo onCreate(). utilizzato per il logging.
private val TAG = MapsActivity::class.java.simpleName
  1. Sempre in MapsActivity, crea una funzione setMapStyle() che acquisisca un GoogleMap.
  2. In setMapStyle(), aggiungi un blocco try{}.
  3. Nel blocco try{}, crea un val success per il successo dello stile. Aggiungi il seguente blocco.
  4. Nel blocco try{}, imposta lo stile JSON sulla mappa, chiama setMapStyle() sull'oggetto GoogleMap. Passa un oggetto MapStyleOptions che carica il file JSON.
  5. Assegna il risultato a success. Il metodo setMapStyle() restituisce un valore booleano che indica lo stato di analisi del file di stile e dell'impostazione dello stile.
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. Aggiungi un'istruzione if per success. Se lo stile non è riuscito, stampa un log che non è stato possibile analizzare.
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
       if (!success) {
           Log.e(TAG, "Style parsing failed.")
       }
   }
}
  1. Aggiungi un blocco catch{} per gestire la situazione di un file di stile mancante. Nel blocco catch, se non è possibile caricare il file, genera un elemento Resources.NotFoundException.
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
   } catch (e: Resources.NotFoundException) {
       Log.e(TAG, "Can't find style. Error: ", e)
   }
}

Il metodo finito dovrebbe essere simile al seguente snippet di codice:

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. Infine, chiama il metodo setMapStyle() nel metodo onMapReady() che passa nell'oggetto GoogleMap.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   setMapStyle(map)
}
  1. Esegui la tua app.
  2. Imposta la mappa sulla modalità normal e il nuovo stile deve essere visibile con il tema rétro e le strade del colore che hai scelto.

Passaggio 3: definisci lo stile dell'indicatore

Puoi personalizzare ulteriormente la mappa modificando gli indicatori. In questo passaggio devi modificare gli indicatori predefiniti in qualcosa di più accattivante.

  1. Nel metodo onMapLongClick(), aggiungi la seguente riga di codice a MarkerOptions() del costruttore per utilizzare l'indicatore predefinito, ma cambia il colore in blu.
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))

Adesso onMapLongClickListener() ha il seguente aspetto:

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. Esegui l'app. Gli indicatori che vengono visualizzati dopo un clic prolungato ora sono blu. Tieni presente che gli indicatori dei PDI sono ancora rossi perché non hai aggiunto uno stile al metodo onPoiClick().

Puoi personalizzare la mappa di Google tracciandola sopra. Questa tecnica è utile se vuoi mettere in evidenza un particolare tipo di località, ad esempio i popolari punti di pesca.

  • Forme: puoi aggiungere polilinee, poligoni e cerchi alla mappa.
  • GroundOverlay oggetti: un overlay del suolo è un'immagine fissata a una mappa. A differenza degli indicatori, gli overlay del suolo sono orientati alla superficie di Earth anziché allo schermo. La rotazione, l'inclinazione o lo zoom della mappa modificano l'orientamento dell'immagine. Gli overlay del suolo sono utili quando si desidera correggere una singola immagine su un'area della mappa.

Passaggio: aggiungi un overlay del suolo

In questa attività aggiungi un overlay del suolo sotto forma di un dispositivo Android nella posizione della tua casa.

  1. Scarica questa immagine Android e salvala nella tua cartella res/drawable. Assicurati che il nome del file sia android.png.

  1. In onMapReady(), dopo la chiamata per spostare la videocamera nella posizione di casa tua, crea un oggetto GroundOverlayOptions.
  2. Assegna l'oggetto a una variabile chiamata androidOverlay.
val androidOverlay = GroundOverlayOptions()
  1. Utilizza il metodo BitmapDescriptorFactory.fromResource() per creare un oggetto BitmapDescriptor dalla risorsa immagine scaricata.
  2. Passa l'oggetto BitmapDescriptor risultante nel metodo image() dell'oggetto GroundOverlayOptions.
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
  1. Crea un float overlaySize per la larghezza in metri dell'overlay desiderato. Per questo esempio, una larghezza di 100f funziona bene.

Imposta la proprietà position per l'oggetto GroundOverlayOptions chiamando il metodo position() e trasmetti l'oggetto homeLatLng e overlaySize.

val overlaySize = 100f
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
   .position(homeLatLng, overlaySize)
  1. Chiama addGroundOverlay() nell'oggetto GoogleMap e passa nell'oggetto GroundOverlayOptions.
map.addGroundOverlay(androidOverlay)
  1. Esegui l'app.
  2. Modifica il valore di zoomLevel a 18f per visualizzare l'immagine Android come overlay.

Gli utenti spesso utilizzano Google Maps per vedere la loro posizione attuale. Per visualizzare la posizione del dispositivo sulla mappa, puoi utilizzare il livello dati sulla località.

Il livello dati sulla posizione aggiunge La mia posizione alla mappa. Quando l'utente tocca il pulsante, la mappa viene centrata sulla posizione del dispositivo. La posizione viene mostrata come un punto blu se il dispositivo è fermo e come freccia di espansione blu se il dispositivo è in movimento.

In questa attività, attiverai il livello dati sulla posizione.

Passaggio: Richiedere le autorizzazioni di accesso alla posizione

L'attivazione del monitoraggio della posizione in Google Maps richiede una singola riga di codice. Tuttavia, devi assicurarti che l'utente abbia concesso le autorizzazioni di accesso alla posizione (utilizzando il modello di autorizzazioni di runtime).

In questo passaggio, devi richiedere le autorizzazioni di accesso alla posizione e attivare il monitoraggio della posizione.

  1. Nel file AndroidManifest.xml, verifica che l'autorizzazione FINE_LOCATION sia già presente. Android Studio ha inserito questa autorizzazione quando hai selezionato il modello Google Maps.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  1. In MapsActivity, crea una variabile REQUEST_LOCATION_PERMISSION per la classe.
private val REQUEST_LOCATION_PERMISSION = 1
  1. Per verificare se vengono concesse autorizzazioni, crea un metodo nella isPermissionGranted() di nome MapsActivity. Con questo metodo, controlla se l'utente ha concesso l'autorizzazione.
private fun isPermissionGranted() : Boolean {
  return ContextCompat.checkSelfPermission(
       this,
      Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
  1. Per attivare il monitoraggio della posizione nell'app, crea in MapsActivity un metodo denominato enableMyLocation() che non prenda alcun argomento e non restituisca nulla. All'interno, controlla l'autorizzazione ACCESS_FINE_LOCATION. Se l'autorizzazione viene concessa, attiva il livello località. Altrimenti, richiedi l'autorizzazione.
private fun enableMyLocation() {
   if (isPermissionGranted()) {
       map.isMyLocationEnabled = true 
   }
   else {
       ActivityCompat.requestPermissions(
           this,
           arrayOf<String>(Manifest.permission.ACCESS_FINE_LOCATION),
           REQUEST_LOCATION_PERMISSION
       )
   }
}
  1. Chiama enableMyLocation() dal callback onMapReady() per attivare il livello località.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   enableMyLocation()
}
  1. Sostituisci il metodo onRequestPermissionsResult(). Se requestCode è uguale all'autorizzazione REQUEST_LOCATION_PERMISSION e l'array grantResults non è vuoto con PackageManager.PERMISSION_GRANTED nel primo slot, chiama enableMyLocation().
override fun onRequestPermissionsResult(
   requestCode: Int,
   permissions: Array<String>,
   grantResults: IntArray) {
   if (requestCode == REQUEST_LOCATION_PERMISSION) {
       if (grantResults.contains(PackageManager.PERMISSION_GRANTED)) {
           enableMyLocation()
       }
   }
}
  1. Esegui l'app. Dovrebbe essere visualizzata una finestra di dialogo che richiede l'accesso alla posizione del dispositivo. Autorizza.

La mappa ora mostra la posizione corrente del dispositivo utilizzando un punto blu. Tieni presente che è presente un pulsante Posizione. Se lo allontani dalla posizione e fai clic su questo pulsante, la mappa viene centrata sulla posizione del dispositivo.

Scarica il codice per il codelab finito.

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


In alternativa, puoi scaricare il repository come file ZIP, decomprimerlo e aprirlo in Android Studio.

Scarica zip

  • Per utilizzare l'API di Google Maps, è necessaria una chiave API della console API di Google.
  • In Android Studio, l'utilizzo del modello Attività di Google Maps genera un Activity con un singolo SupportMapFragment nel layout dell'app. Il modello aggiunge anche il ACCESS_FINE_PERMISSION al manifest dell'app, implementa il OnMapReadyCallback nella tua attività e sostituisce il metodo onMapReady() richiesto.

Per modificare il tipo di mappa di una GoogleMap in fase di esecuzione, utilizza il metodo GoogleMap.setMapType(). Uno dei seguenti tipi di mappa di Google Maps è:

  • Normale: roadmap normale. Mostra strade, alcuni elementi costruiti dall'uomo ed elementi naturali importanti come i fiumi. Sono visibili anche le etichette stradali e di elementi.
  • Ibrida: dati fotografie fotografie con mappe stradali aggiunte. Sono visibili anche le etichette stradali e di elementi.
  • Satellite: dati delle fotografie. Le etichette di strade e elementi non sono visibili.
  • Rilievo: dati topografici. La mappa include colori, linee e contorni di contorno e ombreggiatura della prospettiva. Sono visibili anche strade ed etichette.
  • Nessuna: nessun riquadro della mappa di base.

Informazioni su Google Maps:

  • Un indicatore è un indicatore per una località geografica specifica.
  • Quando viene toccato, il comportamento predefinito dell'indicatore prevede la visualizzazione di una finestra informativa con informazioni sul luogo.
  • Per impostazione predefinita, i punti di interesse (PDI) vengono visualizzati sulla mappa di base insieme alle icone corrispondenti. I PDI includono parchi, scuole, edifici governativi e altro ancora.
  • Inoltre, i PDI di attività commerciali (negozi, ristoranti, hotel e altro) vengono visualizzati per impostazione predefinita sulla mappa quando il tipo di mappa è normal.
  • Puoi acquisire i clic sui PDI utilizzando OnPoiClickListener.
  • Puoi modificare l'aspetto visivo di quasi tutti gli elementi di una mappa Google utilizzando la procedura guidata Stili. Durante la procedura guidata Styling viene generato un file JSON da trasferire nella Google Maps utilizzando il metodo setMapStyle().
  • Puoi personalizzare i tuoi indicatori modificando il colore predefinito o sostituendo la relativa icona con un'immagine personalizzata.

Altre informazioni importanti

  • Utilizza un overlay del suolo per correggere un'immagine in una posizione geografica.
  • Utilizza un oggetto GroundOverlayOptions per specificare le immagini, le dimensioni dell'immagine in metri e la posizione dell'immagine. Passa questo oggetto al metodo GoogleMap.addGroundOverlay() per impostare l'overlay sulla mappa.
  • Se la tua app è autorizzata a ACCESS_FINE_LOCATION, puoi attivare il monitoraggio della posizione impostando map.isMyLocationEnabled = true.
  • Non trattati in questo codelab, ma puoi fornire ulteriori informazioni su una località utilizzando Google Street View, una foto panoramica per una determinata località.

Documentazione per gli sviluppatori Android:

Documentazione di riferimento:

Per i link ad altri codelab in questo corso, consulta la pagina di destinazione avanzata per Android in codelab in Kotlin.