Android für Fortgeschrittene mit Kotlin 04.1: Google Maps für Android

1. Hinweis

Wenn Sie Apps mit Google Maps erstellen, können Sie Ihrer App Funktionen wie Satellitenbilder, zuverlässige UI-Steuerelemente für Karten, Standortverfolgung und Standortmarkierungen hinzufügen. Sie können das standardmäßige Google Maps aufwerten, indem Sie Informationen aus Ihrem eigenen Dataset anzeigen, z. B. die Standorte von bekannten Angel- oder Klettergebieten. Sie können auch Spiele erstellen, in denen der Spieler die physische Welt erkundet, z. B. bei einer Schatzsuche oder sogar Augmented-Reality-Spiele.

In dieser Lektion erstellen Sie eine Google Maps-App namens Wander, die benutzerdefinierte Karten und den Standort des Nutzers anzeigt.

Vorbereitung

Kenntnisse in folgenden Bereichen:

  • Hier erfahren Sie, wie Sie eine einfache Android-App erstellen und mit Android Studio ausführen.
  • Informationen zum Erstellen und Verwalten von Ressourcen wie Strings.
  • Code mit Android Studio refaktorieren und Variablen umbenennen
  • Google Maps-Karten als Nutzer verwenden
  • Festlegen von Laufzeitberechtigungen.

Lerninhalte

  • API-Schlüssel von der Google API Console abrufen und für Ihre App registrieren
  • Eine Google Maps-Karte in Ihre App einbinden
  • Verschiedene Kartentypen anzeigen
  • Google Maps-Karten gestalten
  • Markierungen zur Karte hinzufügen
  • Nutzern ermöglichen, eine Markierung auf einem POI zu platzieren
  • Standortermittlung aktivieren
  • Die Wander-App mit einer eingebetteten Google-Karte erstellen
  • Benutzerdefinierte Funktionen für Ihre App erstellen, z. B. Markierungen und Stile
  • So aktivierst du die Standortermittlung in deiner App

2. App-Übersicht

In diesem Codelab erstellen Sie die Wander-App, mit der eine Google-Karte mit benutzerdefinierten Stilen angezeigt wird. Mit der Wander App kannst du Markierungen auf Orten setzen, Overlays hinzufügen und deinen Standort in Echtzeit sehen.

5b12eda7f467bc2f.png

3. Aufgabe: Projekt einrichten und API-Schlüssel abrufen

Für das Maps SDK for Android ist ein API-Schlüssel erforderlich. Um den API-Schlüssel zu erhalten, registrieren Sie Ihr Projekt in der API & Seite „Dienste“. Der API-Schlüssel ist mit einem digitalen Zertifikat verknüpft, das die App mit dem Autor verknüpft. Weitere Informationen zur Verwendung digitaler Zertifikate und zum Signieren Ihrer App finden Sie unter App signieren.

In diesem Codelab verwenden Sie den API-Schlüssel für das Debug-Zertifikat. Das Debug-Zertifikat ist standardmäßig unsicher, wie unter Debug-Build signieren beschrieben. Für veröffentlichte Android-Apps, die das Maps SDK for Android verwenden, ist ein zweiter API-Schlüssel erforderlich: der Schlüssel für das Freigabezertifikat. Weitere Informationen zum Abrufen eines Freigabezertifikats finden Sie unter API-Schlüssel anfordern.

Android Studio enthält eine Vorlage für Google Maps-Aktivitäten, die hilfreichen Vorlagencode generiert. Der Vorlagencode enthält die Datei google_maps_api.xml mit einem Link, der das Abrufen eines API-Schlüssels vereinfacht.

Schritt 1: Wander-Projekt mit der Kartenvorlage erstellen

  1. Erstellen Sie ein neues Android Studio-Projekt.
  2. Wählen Sie die Vorlage Google Maps Activity (Google Maps-Aktivität) aus.

d6b874bb19ea68cd.png

  1. Geben Sie dem Projekt den Namen Wander.
  2. Legen Sie als minimales API-Level API 19 fest. Die Sprache muss Kotlin sein.
  3. Klicken Sie auf Fertig.
  4. Nachdem die App erstellt wurde, sehen Sie sich Ihr Projekt und die folgenden kartenbezogenen Dateien an, die von Android Studio für Sie erstellt werden:

google_maps_api.xml: In dieser Konfigurationsdatei wird Ihr API-Schlüssel gespeichert. Die Vorlage generiert zwei Dateien vom Typ google_maps_api.xml: eine für die Fehlerbehebung und eine für die Veröffentlichung. Die Datei für den API-Schlüssel für das Debug-Zertifikat befindet sich unter src/debug/res/values. Die Datei für den API-Schlüssel für das Release-Zertifikat befindet sich unter src/release/res/values. In diesem Codelab verwendest du nur das Debug-Zertifikat.

activity_maps.xml: Diese Layoutdatei enthält ein einzelnes Fragment, das den gesamten Bildschirm ausfüllt. Die Klasse SupportMapFragment ist eine abgeleitete Klasse der Klasse Fragment. SupportMapFragment ist die einfachste Möglichkeit, eine Karte in einer App zu platzieren. Es ist ein Wrapper um eine Ansicht einer Karte, um die notwendigen Lebenszyklusanforderungen automatisch zu erfüllen.

Sie können SupportMapFragment mithilfe eines <fragment>-Tags in einer beliebigen ViewGroup mit einem zusätzlichen name-Attribut in eine Layoutdatei einfügen.

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

MapsActivity.java: Die Datei MapsActivity.java instanziiert die SupportMapFragment in der onCreate()-Methode und verwendet die Klasse getMapAsync(), um das Kartensystem und die Ansicht automatisch zu initialisieren. Die Aktivität, die das SupportMapFragment enthält, muss die OnMapReadyCallback-Schnittstelle und die onMapReady()-Methode dieser Schnittstelle implementieren. Die Methode onMapReady() wird beim Laden der Karte aufgerufen.

Schritt 2: API-Schlüssel abrufen

  1. Öffnen Sie die Debug-Version der Datei google_maps_api.xml.
  2. Suchen Sie in der Datei nach einem Kommentar mit einer langen URL. Die URL-Parameter enthalten spezifische Informationen zu Ihrer App.
  3. Kopieren Sie die URL und fügen Sie sie in einen Browser ein.
  4. Folgen Sie der Anleitung, um ein Projekt auf der Seite APIs und Seite „Dienste“. Aufgrund der Parameter in der angegebenen URL weiß die Seite, dass das Maps SDK for Android automatisch aktiviert werden soll.
  5. Klicken Sie auf API-Schlüssel erstellen.
  6. Wechseln Sie auf der nächsten Seite zum Abschnitt „API-Schlüssel“ und klicken Sie auf den soeben erstellten Schlüssel.
  7. Klicken Sie auf Schlüssel einschränken und wählen Sie Maps SDK for Android aus, um die Verwendung des Schlüssels auf Android-Apps zu beschränken.
  8. Kopieren Sie den generierten API-Schlüssel. Sie beginnt mit „AIza".
  9. Fügen Sie den Schlüssel in der Datei google_maps_api.xml im String google_maps_key an der Stelle YOUR_KEY_HERE ein.
  10. Führen Sie Ihre App aus. In Ihren Aktivitäten sollte nun eine Karte mit einer Markierung in Sydney, Australien, eingebettet sein. Die Sydney-Markierung ist Teil der Vorlage, die Sie später ändern können.

34dc9dd877c90996.png

Schritt 3: mMap umbenennen

MapsActivity hat eine private lateinit var mit dem Namen mMap, die vom Typ GoogleMap ist. Ändern Sie den Namen mMap in map, um die Namenskonventionen von Kotlin zu befolgen.

  1. Klicken Sie in MapsActivity mit der rechten Maustaste auf mMap und dann auf Refaktorieren. > Umbenennen...

e713ccb3384450c6.png

  1. Ändern Sie den Variablennamen in map.

Beachten Sie, wie sich alle Verweise auf mMap in der Funktion onMapReady() ebenfalls in map ändern.

4. Aufgabe: Kartentypen hinzufügen

In Google Maps sind verschiedene Kartentypen verfügbar: „Normal“, „Hybrid“, „Satellit“, „Gelände“ und „Keine“. (für überhaupt keine Karte).

Normale Karte

Satellitenkarte

Hybridkarte

Geländekarte

Jeder Kartentyp stellt unterschiedliche Arten von Informationen bereit. Wenn Sie zum Beispiel Karten zur Navigation in einem Auto verwenden, ist es hilfreich, Straßennamen zu sehen, sodass Sie die Option „Normal“ verwenden können. Wenn Sie wandern, kann die Geländekarte hilfreich bei der Entscheidung sein, wie viel Sie noch klettern müssen, um den Gipfel zu erreichen.

In dieser Aufgabe haben Sie folgende Möglichkeiten:

  1. Fügen Sie eine App-Leiste mit einem Optionsmenü hinzu, über das der Nutzer den Kartentyp ändern kann.
  2. Verschieben Sie die Startposition der Karte zu Ihrem eigenen Zuhause.
  3. Unterstützung für Markierungen hinzugefügt, die einzelne Standorte auf einer Karte angeben und ein Label enthalten können.

Menü "Hinzufügen" für Kartentypen

In diesem Schritt fügen Sie eine App-Leiste mit einem Optionsmenü hinzu, über das der Nutzer den Kartentyp ändern kann.

  1. Klicken Sie mit der rechten Maustaste auf das Verzeichnis res und wählen Sie New > (Neu) aus, um eine neue Menü-XML-Datei zu erstellen. Android Resource File (Android-Ressourcendatei)
  2. Geben Sie der Datei im Dialogfeld den Namen map_options.
  3. Wählen Sie für den Ressourcentyp Menü aus.
  4. Klicken Sie auf OK.
  5. Ersetzen Sie auf dem Tab Code den Code in der neuen Datei durch den folgenden Code, um die Kartenmenüoptionen zu erstellen. Die Option „none“ (keine) Kartentyp ausgelassen, da „keine“ dass es überhaupt keine Karte gibt. Dieser Schritt verursacht einen Fehler, den Sie im nächsten Schritt beheben.
<?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. Fügen Sie in strings.xml Ressourcen für die title-Attribute hinzu, um die Fehler zu beheben.
<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. Überschreibe in MapsActivity die onCreateOptionsMenu()-Methode und blähe das Menü aus der Ressourcendatei map_options auf.
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
   val inflater = menuInflater
   inflater.inflate(R.menu.map_options, menu)
   return true
}
  1. Überschreiben Sie in MapsActivity.kt die Methode onOptionsItemSelected(). Sie können den Kartentyp mithilfe von Kartentyp-Konstanten entsprechend der Auswahl des Nutzers ändern.
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. Starten Sie die App.
  2. Klicken Sie auf 428da163b831115b.png, um den Kartentyp zu ändern. Beachten Sie, wie sich die Darstellung der Karte zwischen den verschiedenen Modi ändert.

6fa42970d87f5dc7.png

5. Aufgabe: Markierungen hinzufügen

Standardmäßig enthält der onMapReady()-Callback Code, der eine Markierung in Sydney, Australien, platziert, wo Google Maps erstellt wurde. Der Standard-Callback animiert die Karte außerdem so, dass sie nach Sydney schwenkt.

In dieser Aufgabe bewegen Sie die Kamera der Karte auf Ihr Zuhause, zoomen auf eine von Ihnen festgelegte Stufe und platzieren dort eine Markierung.

Schritt 1: Zoomen Sie Ihr Zuhause heran und fügen Sie eine Markierung hinzu

  1. Suchen Sie in der Datei MapsActivity.kt nach der Methode onMapReady(). Entfernen Sie den Code, der die Markierung in Sydney platziert und die Kamera bewegt. Ihre Methode sollte jetzt so aussehen.
override fun onMapReady(googleMap: GoogleMap) {
   map = googleMap

}
  1. Folgen Sie dieser Anleitung, um den Breiten- und Längengrad Ihres Zuhauses zu ermitteln.
  2. Erstellen Sie einen Wert für den Breitengrad und einen Wert für den Längengrad und geben Sie deren Gleitkommawerte ein.
val latitude = 37.422160
val longitude = -122.084270
  1. Erstellen Sie ein neues LatLng-Objekt mit dem Namen homeLatLng. Übergeben Sie im homeLatLng-Objekt die soeben erstellten Werte.
val homeLatLng = LatLng(latitude, longitude)
  1. Erstellen Sie eine val für die gewünschte Vergrößerung auf der Karte. Verwenden Sie Zoomstufe 15f.
val zoomLevel = 15f

Die Zoomstufe bestimmt, wie herangezoomt Sie auf der Karte sehen. Die folgende Liste gibt Ihnen einen Eindruck davon, welche Detailstufe jede Zoomstufe darstellt:

  • 1: Welt
  • 5: Landmasse/Kontinent
  • 10: Stadt
  • 15: Straßen
  • 20: Gebäude
  1. Bewegen Sie die Kamera auf homeLatLng, indem Sie die Funktion moveCamera() für das map-Objekt aufrufen und mit CameraUpdateFactory.newLatLngZoom() ein CameraUpdate-Objekt übergeben. Übergeben Sie das homeLatLng-Objekt und das zoomLevel-Objekt.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
  1. Fügen Sie der Karte bei homeLatLng eine Markierung hinzu.
map.addMarker(MarkerOptions().position(homeLatLng))

Die endgültige Methode sollte so aussehen:

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. Führen Sie Ihre App aus. Die Karte sollte zu Ihrem Zuhause geschwenkt, auf die gewünschte Stufe herangezoomt und eine Markierung auf Ihrem Zuhause platziert werden.

fc939024778ee76.png

Schritt 2: Nutzern erlauben, durch einen langen Klick eine Markierung hinzuzufügen

In diesem Schritt fügen Sie eine Markierung hinzu, wenn der Nutzer einen Standort auf der Karte berührt und hält.

  1. Erstellen Sie in MapsActivity einen Methoden-Stub mit dem Namen setMapLongClick(), der GoogleMap als Argument verwendet.
  2. Hängen Sie einen setOnMapLongClickListener-Listener an das Kartenobjekt an.
private fun setMapLongClick(map:GoogleMap) {
   map.setOnMapLongClickListener { }
}
  1. Rufen Sie in setOnMapLongClickListener() die Methode addMarker() auf. Übergeben Sie ein neues MarkerOptions-Objekt, dessen Position auf die übergebene LatLng festgelegt ist.
private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       map.addMarker(
           MarkerOptions()
               .position(latLng)
       )
   }
}
  1. Rufen Sie am Ende der Methode onMapReady() setMapLongClick() mit map auf.
override fun onMapReady(googleMap: GoogleMap) {
   ...
  
   setMapLongClick(map)
}
  1. Führen Sie Ihre App aus.
  2. Halten Sie die Karte gedrückt, um eine Markierung an einem Ort zu setzen.
  3. Tippen Sie auf die Markierung, sodass sie in der Mitte des Bildschirms angezeigt wird.

4ff8d1c1db3bca9e.png

Schritt 3: Infofenster für die Markierung hinzufügen

In diesem Schritt fügen Sie einen InfoWindow hinzu, der die Koordinaten der Markierung anzeigt, wenn auf die Markierung getippt wird.

  1. Erstellen Sie in setMapLongClick()setOnMapLongClickListener() eine val für snippet. Ein Ausschnitt ist zusätzlicher Text, der nach dem Titel angezeigt wird. Im Snippet werden Breiten- und Längengrad einer Markierung angezeigt.
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. Setzen Sie in addMarker() den title der Markierung auf „Dropped Pin“. Verwenden Sie dazu die Stringressource R.string.dropped_pin.
  2. Setzen Sie den snippet der Markierung auf snippet.

Die fertige Funktion sieht so aus:

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. Führen Sie Ihre App aus.
  2. Halten Sie die Karte gedrückt, um eine Standortmarkierung zu setzen.
  3. Tippen Sie auf die Markierung, um das Infofenster einzublenden.

63f210e6e47dfa29.png

Schritt 4: POI-Listener hinzufügen

Standardmäßig werden Points of Interest (POIs) zusammen mit den entsprechenden Symbolen auf der Karte angezeigt. POIs sind beispielsweise Parks, Schulen und Behördengebäude. Wenn der Kartentyp auf normal festgelegt ist, werden auch Unternehmens-POIs auf der Karte angezeigt. Unternehmens-POIs sind beispielsweise Geschäfte, Restaurants und Hotels.

In diesem Schritt fügen Sie der Karte ein GoogleMap.OnPoiClickListener hinzu. Mit diesem Klick-Listener wird sofort eine Markierung auf der Karte platziert, wenn der Nutzer auf einen POI klickt. Der Klick-Listener zeigt außerdem ein Infofenster an, das den Namen des POI enthält.

  1. Erstellen Sie in MapsActivity einen Methoden-Stub mit dem Namen setPoiClick(), der GoogleMap als Argument verwendet.
  2. Legen Sie in der Methode setPoiClick() eine OnPoiClickListener für die übergebene GoogleMap fest.
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->

   }
}
  1. Erstellen Sie in der setOnPoiClickListener() eine val poiMarker für die Markierung .
  2. Legen Sie die Markierung mithilfe von map.addMarker() fest und MarkerOptions setzen Sie den title auf den Namen des POI.
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->
       val poiMarker = map.addMarker(
           MarkerOptions()
               .position(poi.latLng)
               .title(poi.name)
       )
   }
}
  1. Rufen Sie in der Funktion setOnPoiClickListener() showInfoWindow() für poiMarker auf, um das Infofenster sofort aufzurufen.
poiMarker.showInfoWindow()

Der endgültige Code für die Funktion setPoiClick() sollte so aussehen.

private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->
       val poiMarker = map.addMarker(
           MarkerOptions()
               .position(poi.latLng)
               .title(poi.name)
       )
       poiMarker.showInfoWindow()
   }
}
  1. Rufen Sie am Ende von onMapReady() setPoiClick() auf und übergeben Sie map.
override fun onMapReady(googleMap: GoogleMap) {
   ...

   setPoiClick(map)
}
  1. Führen Sie Ihre App aus und suchen Sie einen POI, z. B. einen Park oder ein Café.
  2. Tippen Sie auf den POI, um eine Markierung darauf zu setzen und den Namen des POI in einem Infofenster anzeigen zu lassen.

f4b0972c75d5fa5f.png

6. Aufgabe: Karte gestalten

Sie können Google Maps auf viele Arten anpassen, um Ihrer Karte ein einzigartiges Design zu verleihen.

Sie können ein MapFragment-Objekt mithilfe der verfügbaren XML-Attribute genau wie jedes andere Fragment anpassen. In diesem Schritt passen Sie jedoch mithilfe von Methoden für das GoogleMap-Objekt das Design des Contents von MapFragment an.

Um einen benutzerdefinierten Stil für Ihre Karte zu erstellen, generieren Sie eine JSON-Datei, die angibt, wie Elemente in der Karte angezeigt werden. Sie müssen diese JSON-Datei nicht manuell erstellen. Google bietet den Maps Platform Styling Wizard, der den JSON-Code für Sie erstellt, nachdem Sie Ihre Karte visuell gestaltet haben. In dieser Aufgabe gestalten Sie die Karte im Retrodesign, d. h., für die Karte werden alte Farben verwendet und Sie fügen farbige Straßen hinzu.

Schritt 1: Einen Stil für die Karte erstellen

  1. Rufen Sie im Browser https://mapstyle.withgoogle.com/ auf.
  2. Wählen Sie Stil erstellen aus.
  3. Wähle Retro aus.

208b3d3aeab0d9b6.png

  1. Klicke auf Weitere Optionen.

4a35faaf9535ee82.png

  1. Wählen Sie Straße > Ausfüllen:
  2. Ändern Sie die Farbe der Straßen in eine beliebige Farbe, zum Beispiel Rosa.

92c3293749293a4c.png

  1. Klicken Sie auf Fertig.

f1bfe8585eb69480.png

  1. Kopieren Sie den JSON-Code aus dem angezeigten Dialogfeld und legen Sie ihn bei Bedarf in einer Nur-Text-Notiz für den nächsten Schritt fest.

3c32168b299d6420.png

Schritt 2: Stil zur Karte hinzufügen

  1. Erstellen Sie in Android Studio im Verzeichnis res ein Ressourcenverzeichnis und nennen Sie es raw. Sie verwenden die raw-Verzeichnisressourcen wie JSON-Code.
  2. Erstellen Sie in res/raw eine Datei namens map_style.json.
  3. Fügen Sie den gesteckten JSON-Code in die neue Ressourcendatei ein.
  4. Erstellen Sie in MapsActivity eine TAG-Klassenvariable über der onCreate()-Methode. Dies wird zu Protokollierungszwecken verwendet.
private val TAG = MapsActivity::class.java.simpleName
  1. Erstellen Sie außerdem in MapsActivity eine setMapStyle()-Funktion, die eine GoogleMap annimmt.
  2. Fügen Sie in setMapStyle() einen try{}-Block hinzu.
  3. Erstellen Sie im try{}-Block eine val success für eine erfolgreiche Gestaltung. (Sie fügen den folgenden Catch-Block hinzu.)
  4. Legen Sie im try{}-Block den JSON-Stil für die Karte fest und rufen Sie setMapStyle() für das GoogleMap-Objekt auf. Übergeben Sie ein MapStyleOptions-Objekt, das die JSON-Datei lädt.
  5. Weisen Sie das Ergebnis success zu. Die Methode setMapStyle() gibt einen booleschen Wert zurück, der den Erfolgsstatus beim Parsen der Stildatei und Festlegen des Stils angibt.
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. Fügen Sie eine if-Anweisung hinzu, wenn success falsch ist. Wenn der Stil nicht erfolgreich war, geben Sie ein Protokoll aus, dass beim Parsen ein Fehler aufgetreten ist.
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
       if (!success) {
           Log.e(TAG, "Style parsing failed.")
       }
   }
}
  1. Fügen Sie einen catch{}-Block hinzu, um den Fall einer fehlenden Stildatei zu handhaben. Wenn die Datei im Block catch nicht geladen werden kann, wird Resources.NotFoundException ausgelöst.
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
   } catch (e: Resources.NotFoundException) {
       Log.e(TAG, "Can't find style. Error: ", e)
   }
}

Die fertige Methode sollte wie das folgende Code-Snippet aussehen:

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. Rufen Sie schließlich die Methode setMapStyle() in der Methode onMapReady() auf und übergeben Sie Ihr GoogleMap-Objekt.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   setMapStyle(map)
}
  1. Führen Sie Ihre App aus.
  2. Wenn du die Karte auf den normal-Modus setzt, sollte der neue Stil mit Retro-Motiven und Straßen in der ausgewählten Farbe zu sehen sein.

b59d6cb81f02a14f.png

Schritt 3: Markierung gestalten

Sie können Ihre Karte weiter personalisieren, indem Sie die Kartenmarkierungen gestalten. In diesem Schritt ändern Sie die roten Standardmarkierungen in etwas Grooves.

  1. Fügen Sie in der Methode onMapLongClick() die folgende Codezeile zum MarkerOptions() des Konstruktors hinzu, um die Standardmarkierung zu verwenden, aber die Farbe in Blau zu ändern.
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))

onMapLongClickListener() sieht jetzt so aus:

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. Führen Sie die App aus. Die Markierungen, die nach einem langen Klick angezeigt werden, sind jetzt blau schattiert. Beachten Sie, dass POI-Markierungen immer noch rot sind, weil Sie der onPoiClick()-Methode keinen Stil hinzugefügt haben.

b9916bca3c367e3.png

7. Aufgabe: Overlay hinzufügen

Eine Möglichkeit, eine Google-Karte anzupassen, besteht darin, darauf zu zeichnen. Diese Technik ist nützlich, wenn Sie einen bestimmten Ortstyp hervorheben möchten, z. B. beliebte Angelplätze.

  • Formen:Sie können der Karte Polylinien, Polygone und Kreise hinzufügen.
  • GroundOverlay-Objekte:Ein Boden-Overlay ist ein Bild, das auf einer Karte fixiert ist. Im Gegensatz zu Markierungen sind Boden-Overlays an der Erdoberfläche und nicht am Bildschirm ausgerichtet. Durch Drehen, Neigen oder Zoomen der Karte ändert sich die Ausrichtung des Bildes. Boden-Overlays sind nützlich, wenn Sie ein einzelnes Bild in einem Bereich der Karte fixieren möchten.

Schritt: Boden-Overlay hinzufügen

In dieser Aufgabe fügen Sie Ihrem Zuhause ein Boden-Overlay in Form eines Android-Smartphones hinzu.

  1. Laden Sie dieses Android-Bild herunter und speichern Sie es im Ordner res/drawable. Der Dateiname muss android.png lauten.

61fabd56a0841b44.png

  1. Erstellen Sie in onMapReady() nach dem Aufruf zum Bewegen der Kamera auf die Position Ihres Zuhauses ein GroundOverlayOptions-Objekt.
  2. Weisen Sie das Objekt einer Variablen namens androidOverlay zu.
val androidOverlay = GroundOverlayOptions()
  1. Verwenden Sie die Methode BitmapDescriptorFactory.fromResource(), um ein BitmapDescriptor-Objekt aus der heruntergeladenen Bildressource zu erstellen.
  2. Übergeben Sie das resultierende BitmapDescriptor-Objekt an die image()-Methode des GroundOverlayOptions-Objekts.
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
  1. Erstellen Sie einen float overlaySize für die Breite des gewünschten Overlays in Metern. In diesem Beispiel ist eine Breite von 100f gut geeignet.

Legen Sie die position-Eigenschaft für das GroundOverlayOptions-Objekt fest, indem Sie die Methode position() aufrufen und das homeLatLng-Objekt sowie das overlaySize-Objekt übergeben.

val overlaySize = 100f
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
   .position(homeLatLng, overlaySize)
  1. Rufen Sie addGroundOverlay() für das GoogleMap-Objekt auf und übergeben Sie das GroundOverlayOptions-Objekt.
map.addGroundOverlay(androidOverlay)
  1. Starten Sie die App.
  2. Ändern Sie den Wert von zoomLevel in 18f, damit das Android-Bild als Overlay angezeigt wird.

b1b25b0acd6a9807.png

8. Aufgabe: Standortermittlung aktivieren

Nutzer verwenden häufig Google Maps, um ihren aktuellen Standort zu sehen. Wenn Sie den Gerätestandort auf der Karte anzeigen lassen möchten, können Sie die Standort-Datenebene verwenden.

Durch die Standortdatenebene wird das Symbol Mein Standort zur Karte hinzugefügt.

f317f84dcb3ac3a1.png

Wenn der Nutzer auf die Schaltfläche tippt, wird auf der Karte der Standort des Geräts in der Mitte angezeigt. Der Standort wird als blauer Punkt angezeigt, wenn das Gerät nicht bewegt wird, und als blauer Chevron, wenn das Gerät in Bewegung ist.

In dieser Aufgabe aktivieren Sie die Standortdatenebene.

Schritt: Berechtigungen zur Standortermittlung anfordern

Die Aktivierung des Standort-Trackings in Google Maps erfordert eine einzige Codezeile. Sie müssen jedoch sicherstellen, dass der Nutzer die Berechtigung zur Standortermittlung erteilt hat (mithilfe des Laufzeitberechtigungsmodells).

In diesem Schritt fordern Sie die Berechtigung zur Standortermittlung an und aktivieren die Standortermittlung.

  1. Prüfen Sie in der Datei AndroidManifest.xml, ob die Berechtigung FINE_LOCATION bereits vorhanden ist. Android Studio hat diese Berechtigung eingefügt, als Sie die Google Maps-Vorlage ausgewählt haben.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  1. Erstellen Sie in MapsActivity eine REQUEST_LOCATION_PERMISSION-Klassenvariable.
private val REQUEST_LOCATION_PERMISSION = 1
  1. Erstellen Sie im MapsActivity eine Methode namens isPermissionGranted(), um zu prüfen, ob Berechtigungen gewährt wurden. Prüfen Sie bei dieser Methode, ob der Nutzer die Berechtigung erteilt hat.
private fun isPermissionGranted() : Boolean {
  return ContextCompat.checkSelfPermission(
       this,
      Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
  1. Um das Standort-Tracking in Ihrer App zu aktivieren, erstellen Sie in MapsActivity eine Methode namens enableMyLocation(), die keine Argumente annimmt und nichts zurückgibt. Prüfe darin, ob die Berechtigung ACCESS_FINE_LOCATION vorhanden ist. Wenn die Berechtigung erteilt wurde, aktivieren Sie die Standortebene. Andernfalls fordern Sie die Berechtigung an.
private fun enableMyLocation() {
   if (isPermissionGranted()) {
       map.isMyLocationEnabled = true 
   }
   else {
       ActivityCompat.requestPermissions(
           this,
           arrayOf<String>(Manifest.permission.ACCESS_FINE_LOCATION),
           REQUEST_LOCATION_PERMISSION
       )
   }
}
  1. Rufe enableMyLocation() über den onMapReady()-Callback auf, um die Standortebene zu aktivieren.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   enableMyLocation()
}
  1. Überschreiben Sie die Methode onRequestPermissionsResult(). Prüfen Sie, ob requestCode gleich REQUEST_LOCATION_PERMISSION ist. Ist dies der Fall, wird die Berechtigung erteilt. Wenn die Berechtigung gewährt wird, prüfen Sie auch, ob das Array grantResults im ersten Slot PackageManager.PERMISSION_GRANTED enthält. Wenn dies der Fall ist, rufen Sie enableMyLocation() auf.
override fun onRequestPermissionsResult(
   requestCode: Int,
   permissions: Array<String>,
   grantResults: IntArray) {
   if (requestCode == REQUEST_LOCATION_PERMISSION) {
       if (grantResults.contains(PackageManager.PERMISSION_GRANTED)) {
           enableMyLocation()
       }
   }
}
  1. Führen Sie Ihre App aus. Es sollte ein Dialogfeld angezeigt werden, in dem Zugriff auf den Standort des Geräts angefordert wird. Lass die Berechtigung zu.

da7e23e00ec762c1.png

Auf der Karte wird jetzt der aktuelle Standort des Geräts mit einem blauen Punkt angezeigt. Beachten Sie, dass es eine Schaltfläche für den Standort gibt. Wenn Sie die Karte von Ihrem Standort wegbewegen und auf diese Schaltfläche klicken, wird die Karte wieder auf den Standort des Geräts zentriert.

5b12eda7f467bc2f.png

9. Lösungscode

Laden Sie den Code für das fertige Codelab herunter.

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

Alternativ können Sie das Repository als ZIP-Datei herunterladen, entpacken und in Android Studio öffnen.

10. Zusammenfassung

Glückwunsch! Sie haben einer Android Kotlin-App eine Google-Karte hinzugefügt und einen Stil dafür eingerichtet.

11. Weitere Informationen

Dokumentation für Android-Entwickler:

Referenzdokumentation:

12. Nächstes Codelab

Links zu anderen Codelabs in diesem Kurs finden Sie auf der Landingpage zu den Codelabs für Fortgeschrittene mit Android in Kotlin.