Erweiterte Android-Funktionen in Kotlin 04.1: Google Maps für Android

Dieses Codelab ist Teil des Kurses „Advanced Android in Kotlin“. Sie profitieren von diesem Kurs, wenn Sie die Codelabs nacheinander durcharbeiten. Das ist aber nicht zwingend erforderlich. Alle Kurs-Codelabs finden Sie auf der Landingpage für Codelabs auf Android-Geräten für Fortgeschrittene.

Mithilfe von Google Maps-Apps können Sie Ihrer App Funktionen hinzufügen, z. B. Satellitenbilder, robuste UI-Steuerelemente für Karten, Standorttracking und Standortmarkierungen. Sie können den Standard in Google Maps weiter optimieren, indem Sie Informationen aus Ihrem Datensatz verwenden, etwa Orte bekannter Angel- oder Kletterbereiche. Außerdem kannst du Spiele erstellen, in denen Spieler die physische Welt entdecken, etwa eine Schatzsuche oder Augmented-Reality-Spiele.

In dieser Lektion erstellen Sie eine Google Maps App mit dem Namen „Wandern“, auf der benutzerdefinierte Karten mit dem Standort des Nutzers angezeigt werden.

Vorbereitung

Informiere dich über Folgendes:

  • Einfache Android-App erstellen und mit Android Studio ausführen
  • Ressourcen wie Strings erstellen und verwalten
  • Mit Android Studio Code refaktorieren und Variablen umbenennen.
  • Google-Karten als Nutzer verwenden
  • Laufzeitberechtigungen festlegen

Lerninhalte

  • API-Schlüssel über die Google API Console abrufen und Schlüssel in der App registrieren
  • Google Maps-Karte in Ihre App einbinden
  • Verschiedene Kartentypen einblenden
  • Stile von Google Maps-Karten
  • Markierungen in eine Karte einfügen
  • Nutzer aktivieren, eine Markierung an einem POI zu platzieren
  • Standortermittlung aktivieren
  • So erstellst du die App"Wander"mit einer eingebetteten Google-Karte
  • Benutzerdefinierte Funktionen für Ihre App erstellen, z. B. Markierungen oder Stile
  • Standortermittlung in der App aktivieren

In diesem Codelab erstellen Sie die Wander-App, auf der eine Google-Karte mit benutzerdefinierten Stilen angezeigt wird. Mit der Wander App können Sie Markierungen auf Ihren Standorten setzen, Overlays hinzufügen und Ihren Standort in Echtzeit sehen.

Für das Maps SDK for Android ist ein API-Schlüssel erforderlich. Registrieren Sie Ihr Projekt auf der Seite API &Dienste, um den API-Schlüssel abzurufen. Der API-Schlüssel ist mit einem digitalen Zertifikat verknüpft, das die App mit dem Autor verknüpft. Weitere Informationen zum Verwenden digitaler Zertifikate und zum Signieren Ihrer App finden Sie unter App signieren.

In diesem Codelab nutzen Sie den API-Schlüssel für das Debug-Zertifikat. Das Debugzertifikat ist von Grund auf 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 Release-Zertifikats findest du unter API-Schlüssel anfordern.

Android Studio enthält eine Vorlage für die Google Maps-Aktivität, die einen hilfreichen Vorlagencode generiert. Der Vorlagencode enthält eine google_maps_api.xml-Datei, die einen Link enthält, der den Abruf eines API-Schlüssels vereinfacht.

Schritt 1: Wanderprojekt mit der Kartenvorlage erstellen

  1. Erstelle ein neues Android Studio-Projekt.
  2. Wählen Sie die Vorlage Google Maps Activity aus.

  1. Nennen Sie das Projekt Wander.
  2. Legen Sie das Mindest-API-Level auf API 19 fest. Die Sprache muss Kotlin lauten.
  3. Klicken Sie auf Fertig.
  4. Wenn die App fertig erstellt ist, sehen Sie sich Ihr Projekt und die folgenden kartenbezogenen Dateien an, die Android Studio für Sie erstellt:

google_maps_api.xml: Sie verwenden diese Konfigurationsdatei, um Ihren API-Schlüssel zu speichern. Mit der Vorlage werden zwei Dateien vom Typ google_maps_api.xml generiert: eine für das Debugging und eine für die Veröffentlichung. Die Datei für den API-Schlüssel für das Debugzertifikat befindet sich unter src/debug/res/values. Die Datei für den API-Schlüssel für das Freigabezertifikat befindet sich in src/release/res/values. In diesem Codelab nutzen Sie 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 Unterklasse der Fragment-Klasse. Ein SupportMapFragment ist die einfachste Möglichkeit, eine Karte in eine App zu platzieren. Ein Wrapper um die Ansicht einer Karte, um die erforderlichen Lebenszyklusanforderungen automatisch zu erfüllen.

Sie können SupportMapFragment mithilfe eines <fragment>-Tags in einem 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.kt instanziiert SupportMapFragment in der Methode onCreate() und verwendet die Klasse getMapAsync(), um das Kartensystem und die Ansicht automatisch zu initialisieren. In der Aktivität, die SupportMapFragment enthält, muss die OnMapReadyCallback-Schnittstelle und die onMapReady()-Methode implementiert werden. Die Methode onMapReady() wird beim Laden der Karte aufgerufen.

Schritt 2: API-Schlüssel abrufen

  1. Öffnen Sie die Debugging-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 auf der Seite APIs &Dienste, um ein Projekt zu erstellen. Aufgrund der Parameter in der angegebenen URL weiß die Seite, dass das Maps SDK for Android automatisch aktiviert werden muss.
  5. Klicke auf API-Schlüssel erstellen.
  6. Gehen Sie auf der nächsten Seite zum Abschnitt „API-Schlüssel“ und klicken Sie auf den Schlüssel, den Sie gerade erstellt haben.
  7. Klicke auf Schlüssel einschränken und wähle Maps SDK for Android aus, um die Verwendung von Schlüsseln auf Android-Apps einzuschrä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 in den String google_maps_key ein, in dem er YOUR_KEY_HERE steht.
  10. Führe deine App aus. Es sollte eine eingebettete Karte mit deinen Aktivitäten in Sydney, Australien, angezeigt werden. Die Sydney-Markierung ist Teil der Vorlage und Sie ändern sie später.

Schritt 3: mMap umbenennen

MapsActivity hat ein privates lateinit-var namens mMap, das vom Typ GoogleMap ist. Um die Kotlin-Namenskonventionen zu befolgen, ändern Sie den Namen von mMap zu map.

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

  1. Ändern Sie den Variablennamen in map.

Beachten Sie, dass alle Verweise auf mMap in der Funktion onMapReady() auch in map geändert werden.

Google Maps enthält die Kartentypen „Normal“, „Hybrid“, „Satellit“, „Gelände“ und „Nichts“ (keine Karte).

Normale Karte

Satellitenkarte

Hybridkarte

Geländekarte

Die verschiedenen Kartentypen bieten unterschiedliche Arten von Informationen. Wenn Sie z. B. Karten zur Navigation in einem Auto verwenden, ist es hilfreich, Straßennamen zu sehen, sodass Sie die normale Option verwenden können. Beim Wandern kannst du mit der Geländekarte entscheiden, wie viel du noch benötigst, um zum Gipfel zu kommen.

Dabei haben Sie folgende Möglichkeiten:

  1. Fügen Sie eine App-Leiste mit einem Optionsmenü hinzu, mit dem Nutzer den Kartentyp ändern können.
  2. Verschieben Sie die Startposition der Karte an Ihren eigenen Standort.
  3. Unterstützung für Markierungen hinzugefügt, die einzelne Standorte auf einer Karte anzeigen und ein Label beinhalten können.

Menü für Kartentypen hinzufügen

In diesem Schritt fügen Sie eine App-Leiste mit einem Optionsmenü hinzu, mit dem der Kartentyp des Nutzers geändert werden kann.

  1. Klicken Sie mit der rechten Maustaste auf das Verzeichnis res und wählen Sie New > Android Resource File aus, um eine neue XML-Menüdatei zu erstellen.
  2. Benennen Sie im Dialogfeld die Datei map_options.
  3. Wählen Sie als 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. Der Kartentyp „&none“ wird ausgelassen, da „Karten“ überhaupt nicht vorhanden ist. Dieser Schritt verursacht einen Fehler. Sie müssen ihn jedoch 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 Methode onCreateOptionsMenu() und überblende das Menü aus der map_options-Ressourcendatei.
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
   val inflater = menuInflater
   inflater.inflate(R.menu.map_options, menu)
   return true
}
  1. Überschreibe in „MapsActivity.kt“ die Methode „onOptionsItemSelected()“. Den Kartentyp mithilfe von Kartentypkonstanten ändern, um die Auswahl des Nutzers widerzuspiegeln
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. Führen Sie die App aus.
  2. Klicke auf , um den Kartentyp zu ändern. Die Darstellung der Karte ändert sich zwischen den verschiedenen Modi.

Standardmäßig enthält der onMapReady()-Callback Code, der eine Markierung in Sydney (Australien), wo Google Maps erstellt wurde, enthält. Durch den Standard-Callback wird die Karte auch animiert, um nach Sydney zu schwenken.

In dieser Aufgabe bewegen Sie die Karte nach Hause, zoomen auf eine von Ihnen festgelegte Ebene und platzieren dort eine Markierung.

Schritt 1: Heranzoomen und eine Markierung hinzufügen

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

}
  1. Wenn Sie den Längen- und Breitengrad Ihres Zuhauses abrufen möchten, folgen Sie dieser Anleitung.
  2. Erstellen Sie einen Wert für den Breitengrad und einen Wert für den Längengrad und geben Sie die Gleitkommazahlen ein.
val latitude = 37.422160
val longitude = -122.084270
  1. Erstellen Sie ein neues LatLng-Objekt namens homeLatLng. Übergeben Sie im Objekt homeLatLng die soeben erstellten Werte.
val homeLatLng = LatLng(latitude, longitude)
  1. Erstelle eine val für das Heranzoomen auf der Karte. Zoomfaktor 15f verwenden.
val zoomLevel = 15f

Über die Zoomstufe wird gesteuert, wie auf der Karte herangezoomt wird. Die folgende Liste gibt Aufschluss darüber, welche Detailebene jede Zoomstufe anzeigt:

  • 1: Welt
  • 5: Landmasse/Kontinent
  • 10: Stadt
  • 15: Straßen
  • 20: Gebäude
  1. Bewegen Sie die Kamera nach homeLatLng, indem Sie die Funktion moveCamera() für das Objekt map aufrufen und ein Objekt CameraUpdate mit CameraUpdateFactory.newLatLngZoom() übergeben. Übergib das Objekt homeLatLng und zoomLevel.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
  1. Erstelle unter homeLatLng eine Markierung.
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ühre deine App aus. Die Karte sollte nach Hause schwenken, auf das gewünschte Level zoomen und eine Markierung auf deinem Zuhause setzen.

Schritt 2: Nutzern erlauben, mit einem langen Klick eine Markierung hinzuzufügen

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

  1. Erstelle einen Methoden-Stub in MapsActivity 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. Rufe in setOnMapLongClickListener() die Methode addMarker() auf. Übergib ein neues MarkerOptions-Objekt mit der Position, die auf den übergebenen LatLng gesetzt 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ühre deine App aus.
  2. Halten Sie die Karte gedrückt, um eine Markierung an einem Ort zu platzieren.
  3. Tippen Sie auf die Markierung, sodass sie auf dem Bildschirm zentriert wird.

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

In diesem Schritt fügen Sie ein InfoWindow hinzu, mit dem die Koordinaten der Markierung beim Antippen angezeigt werden.

  1. Erstellen Sie in setMapLongClick()setOnMapLongClickListener() einen val für snippet. Ein Snippet ist zusätzlicher Text nach dem Titel. Im Snippet werden der 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. Lege in addMarker() den title der Markierung mithilfe einer String-Ressource von R.string.dropped_pin auf „Gesetzte Markierung“ fest.
  2. Setze die Markierung snippet auf snippet.

Die abgeschlossene 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ühre deine App aus.
  2. Halten Sie die Karte gedrückt, um eine Standortmarkierung zu setzen.
  3. Tippe auf die Markierung, um das Infofenster aufzurufen.

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 Dienstgebäude. Wenn der Kartentyp auf normal gesetzt 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. Dieser Klick-Listener platziert eine Markierung direkt auf der Karte, wenn der Nutzer auf einen POI klickt. Im Klick-Listener wird auch ein Infofenster angezeigt, das den Namen des POI enthält.

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

   }
}
  1. Erstelle in setOnPoiClickListener() ein val poiMarker für die Markierung .
  2. Lege sie auf eine Markierung fest, indem du map.addMarker() mit MarkerOptions title auf den Namen des POI stellst.
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->
       val poiMarker = map.addMarker(
           MarkerOptions()
               .position(poi.latLng)
               .title(poi.name)
       )
   }
}
  1. Rufe in der Funktion setOnPoiClickListener() showInfoWindow() unter poiMarker auf, um das Infofenster sofort anzuzeigen.
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. Am Ende von onMapReady() setPoiClick() anrufen und map übergeben.
override fun onMapReady(googleMap: GoogleMap) {
   ...

   setPoiClick(map)
}
  1. Führen Sie Ihre App aus und suchen Sie nach einem POI, zum Beispiel einem Park oder Café.
  2. Tippe auf den POI, um eine Markierung zu setzen und den Namen des POI in einem Infofenster anzuzeigen.

Sie können Google Maps auf verschiedene Weise anpassen, sodass Ihre Karte einen einzigartigen Look erhält.

Du kannst ein MapFragment-Objekt mit den verfügbaren XML-Attributen wie jedes andere Fragment anpassen. In diesem Schritt passen Sie das Erscheinungsbild des Inhalts von MapFragment mithilfe von Methoden für das GoogleMap-Objekt an.

Generieren Sie einen benutzerdefinierten Stil für Ihre Karte, indem Sie eine JSON-Datei generieren, die angibt, wie Merkmale auf der Karte angezeigt werden. Sie müssen diese JSON-Datei nicht manuell erstellen. Google stellt den Maps Platform Styling Wizard zur Verfügung, der den JSON-Code für Sie generiert, nachdem Sie Ihre Karte visuell gestaltet haben. Bei dieser Aufgabe formatieren Sie die Karte mit einem Retrostil. Das heißt, die Karte verwendet alte Farben und Sie fügen farbige Straßen hinzu.

Schritt 1: Stil für die Karte erstellen

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

  1. Klicke auf Weitere Optionen.

  1. Wähle in der Liste Funktionstyp die Option Straße & Füllen aus.
  2. Ändern Sie die Farbe der Straßen in eine beliebige Farbe, z. B. rosa.

  1. Klicken Sie auf Fertig.

  1. Kopieren Sie den JSON-Code aus dem daraufhin angezeigten Dialogfeld und stecken Sie ihn bei Bedarf in eine Nur-Text-Notiz.

Schritt 2: Stil zu Ihrer Karte hinzufügen

  1. Erstellen Sie in Android Studio im Verzeichnis res ein Ressourcenverzeichnis und nennen Sie es raw. Sie verwenden die Verzeichnisressourcen von raw wie JSON-Code.
  2. Erstelle in res/raw eine Datei mit dem Namen map_style.json.
  3. Fügen Sie den eingefügten JSON-Code in die neue Ressourcendatei ein.
  4. Erstellen Sie in MapsActivity eine TAG-Klassenvariable über der Methode onCreate(). Er wird zu Logging-Zwecken verwendet.
private val TAG = MapsActivity::class.java.simpleName
  1. Erstellen Sie außerdem in MapsActivity eine setMapStyle()-Funktion, die ein GoogleMap-Element verwendet.
  2. Fügen Sie in setMapStyle() einen try{}-Block hinzu.
  3. Erstellen Sie im Block try{} ein val success für den gewünschten Stil. Sie fügen den folgenden Block hinzu.
  4. Legen Sie im try{}-Block den JSON-Stil auf die Karte fest und rufen Sie setMapStyle() für das GoogleMap-Objekt auf. Übergib 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 beim 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 für success als „false“ hinzu. Wenn der Stil nicht erfolgreich ist, drucken Sie ein Protokoll, dass das Parsen fehlgeschlagen ist.
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
       if (!success) {
           Log.e(TAG, "Style parsing failed.")
       }
   }
}
  1. Füge einen catch{}-Block hinzu, um die Situation mit einer fehlenden Stildatei zu verarbeiten. Wenn die Datei im catch-Block nicht geladen werden kann, soll ein Resources.NotFoundException ausgelöst werden.
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
   } catch (e: Resources.NotFoundException) {
       Log.e(TAG, "Can't find style. Error: ", e)
   }
}

Die abgeschlossene Methode sollte in etwa so 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 abschließend die Methode setMapStyle() in der Methode onMapReady() auf, die das GoogleMap-Objekt übergibt.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   setMapStyle(map)
}
  1. Führe deine App aus.
  2. Wenn Sie für die Karte den Modus normal auswählen, sollte der neue Stil mit Retro-Designs und Straßen der ausgewählten Farbe sichtbar sein.

Schritt 3: Markierung gestalten

Sie können Ihre Karte weiter personalisieren, indem Sie den Stil der Kartenmarkierungen anpassen. In diesem Schritt verwandelst du die standardmäßigen roten Markierungen in etwas Grausameres.

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

Jetzt sieht onMapLongClickListener() 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 schattiert. POI-Markierungen sind weiterhin rot, weil du der Methode onPoiClick() keinen Stil hinzugefügt hast.

Eine Möglichkeit, die Google-Karte anzupassen, ist das Zeichnen auf der Karte. Diese Methode ist nützlich, wenn Sie einen bestimmten Standorttyp 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 Unterschied zu Markierungen sind Boden-Overlays auf die Erdoberfläche und nicht auf den Bildschirm ausgerichtet. Durch das Drehen, Neigen oder Zoomen der Karte wird die Ausrichtung des Bilds geändert. Mit Boden-Overlays kann ein einzelnes Bild an einem Punkt der Karte fixiert werden.

Schritt: Boden-Overlay hinzufügen

Bei dieser Aufgabe fügen Sie ein Boden-Overlay in Form eines Android-Geräts zu Ihrem Standort hinzu.

  1. Laden Sie dieses Android-Image herunter und speichern Sie es in Ihrem Ordner res/drawable. Achten Sie darauf, dass der Dateiname android.png ist.

  1. Erstellen Sie in onMapReady() nach dem Aufruf, um die Kamera in Ihre Position zu bewegen, ein GroundOverlayOptions-Objekt.
  2. Weisen Sie das Objekt einer Variablen namens androidOverlay zu.
val androidOverlay = GroundOverlayOptions()
  1. Verwende die Methode BitmapDescriptorFactory.fromResource(), um ein BitmapDescriptor-Objekt aus der heruntergeladenen Bildressource zu erstellen.
  2. Übergib das resultierende BitmapDescriptor-Objekt an die image()-Methode des GroundOverlayOptions-Objekts.
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
  1. Erstellen Sie ein float overlaySize für die Breite des gewünschten Overlays in Metern. In diesem Beispiel hat die Breite 100f eine gute Leistung.

Lege die Property position für das Objekt GroundOverlayOptions fest, indem du die Methode position() aufrufst und das Objekt homeLatLng und overlaySize übergibst.

val overlaySize = 100f
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
   .position(homeLatLng, overlaySize)
  1. Rufe addGroundOverlay() für das GoogleMap-Objekt auf und übergib das GroundOverlayOptions-Objekt.
map.addGroundOverlay(androidOverlay)
  1. Führen Sie die App aus.
  2. Ändern Sie den Wert von zoomLevel in 18f, um das Android-Bild als Overlay zu sehen.

Nutzer verwenden Google Maps häufig, um ihren aktuellen Standort zu sehen. Sie können die Ebene „Standortdaten“ verwenden, um den Gerätestandort auf der Karte anzuzeigen.

Durch die Datenschicht wird der Karte Mein Standort hinzugefügt. Wenn der Nutzer auf die Schaltfläche tippt, wird die Karte auf den Standort des Geräts zentriert. Der Standort wird als blauer Punkt angezeigt, wenn das Gerät sich nicht bewegt, und als blauer Pfeil, wenn das Gerät in Bewegung ist.

In dieser Aufgabe aktivieren Sie die Datenschichtebene.

Schritt: Berechtigung zur Standortermittlung anfordern

Für die Aktivierung des Standort-Trackings in Google Maps ist eine einzelne Codezeile erforderlich. Der Nutzer muss jedoch mithilfe des Berechtigungsmodells „Laufzeit“ Berechtigungen zur Standortermittlung erteilt haben.

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

  1. Überprüfe in der Datei AndroidManifest.xml, ob die FINE_LOCATION-Berechtigung bereits vorhanden ist. Diese Berechtigung wurde von Android Studio eingefügt, als du die Google Maps-Vorlage ausgewählt hast.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  1. Erstelle in MapsActivity eine REQUEST_LOCATION_PERMISSION-Klassenvariable.
private val REQUEST_LOCATION_PERMISSION = 1
  1. Erstelle in MapsActivity eine Methode namens isPermissionGranted(), um zu prüfen, ob die Berechtigungen erteilt 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. Wenn Sie das Standort-Tracking in Ihrer App aktivieren möchten, erstellen Sie in MapsActivity eine Methode namens enableMyLocation(), die keine Argumente erhält und keine Ergebnisse zurückgibt. Prüfen Sie darin die Berechtigung ACCESS_FINE_LOCATION. Wenn die Berechtigung gewährt wird, aktivieren Sie die Standortebene. Beantragen Sie andernfalls die Berechtigung.
private fun enableMyLocation() {
   if (isPermissionGranted()) {
       map.isMyLocationEnabled = true 
   }
   else {
       ActivityCompat.requestPermissions(
           this,
           arrayOf<String>(Manifest.permission.ACCESS_FINE_LOCATION),
           REQUEST_LOCATION_PERMISSION
       )
   }
}
  1. Rufen Sie enableMyLocation() aus dem onMapReady()-Callback auf, um die Standortebene zu aktivieren.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   enableMyLocation()
}
  1. Überschreibe die Methode onRequestPermissionsResult(). Wenn die Berechtigung requestCode der Berechtigung REQUEST_LOCATION_PERMISSION entspricht und wenn das Array grantResults in der ersten Anzeigenfläche nicht leer ist, während PackageManager.PERMISSION_GRANTED in der ersten Anzeigenfläche angegeben ist, die Methode enableMyLocation() aufrufen.
override fun onRequestPermissionsResult(
   requestCode: Int,
   permissions: Array<String>,
   grantResults: IntArray) {
   if (requestCode == REQUEST_LOCATION_PERMISSION) {
       if (grantResults.contains(PackageManager.PERMISSION_GRANTED)) {
           enableMyLocation()
       }
   }
}
  1. Führe deine App aus. Ein Dialogfeld, in dem der Zugriff auf den Standort des Geräts angefordert wird, sollte angezeigt werden. Erlauben Sie die Berechtigung.

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

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.

ZIP herunterladen

  • Für die Nutzung der Google Maps API benötigst du einen API-Schlüssel aus der Google API Console.
  • In Android Studio wird mit der Google Maps-Aktivitätsvorlage ein Activity mit einem einzelnen SupportMapFragment im Layout der App generiert. Außerdem wird die ACCESS_FINE_PERMISSION zum App-Manifest hinzugefügt, die OnMapReadyCallback in deiner Aktivität implementiert und die erforderliche onMapReady()-Methode überschrieben.

Um den Kartentyp eines GoogleMap zur Laufzeit zu ändern, verwende die Methode GoogleMap.setMapType(). Google Maps-Karten können einen der folgenden Kartentypen haben:

  • Normal: Typische Straßenkarte. Straßen, einige von Menschen geschaffene Merkmale und wichtige Landschaftsmerkmale wie Flüsse werden angezeigt. Die Straßen und sonstigen Merkmale sind beschriftet.
  • Hybrid: Satellitenfotodaten mit hinzugefügten Straßenkarten. Die Straßen und sonstigen Merkmale sind beschriftet.
  • Satellit: Fotodaten Straßen und sonstige Merkmale sind nicht beschriftet.
  • Gelände: Topografische Daten. Die Karte enthält Farben, Höhenlinien und Labels sowie perspektivische Schattierungen. Außerdem werden einige Straßen und Labels dargestellt.
  • Keine: Keine Basiskartenkacheln.

Über Google Maps:

  • Eine Markierung ist ein Indikator für einen bestimmten Standort.
  • Wenn darauf getippt wird, wird standardmäßig ein Infofenster mit Informationen zum Standort angezeigt.
  • Standardmäßig werden Points of Interest (POIs) zusammen mit ihren Icons auf der Karte dargestellt. POIs sind beispielsweise Parks, Schulen und Dienstgebäude.
  • Darüber hinaus werden Unternehmens-POIs (Geschäfte, Restaurants, Hotels usw.) standardmäßig auf der Karte angezeigt, wenn der Kartentyp normal ist.
  • Mit OnPoiClickListener können Sie Klicks auf POIs erfassen.
  • Mit dem Stilassistenten können Sie die Darstellung fast aller Elemente einer Google Maps-Karte ändern. Der Styling-Assistent generiert eine JSON-Datei, die du mit der setMapStyle()-Methode an die Google Maps-Karte übergibst.
  • Sie können sie anpassen, indem Sie die Standardfarbe ändern oder das Standardmarkierungssymbol durch ein benutzerdefiniertes Bild ersetzen.

Weitere wichtige Informationen:

  • Verwenden Sie ein Boden-Overlay, um das Bild an einem bestimmten Ort zu korrigieren.
  • Verwende ein GroundOverlayOptions-Objekt, um das Bild, die Größe des Bildes in Metern und die Position des Bildes anzugeben. Übergib dieses Objekt an die GoogleMap.addGroundOverlay()-Methode, um das Overlay für die Karte festzulegen.
  • Solange deine App die Berechtigung ACCESS_FINE_LOCATION hat, kannst du die Standortermittlung aktivieren, indem du map.isMyLocationEnabled = true legst.
  • Es wird in diesem Codelab nicht behandelt, aber Sie können mit Google Street View, einem navigierbaren Panoramafoto für einen bestimmten Standort, zusätzliche Informationen bereitstellen.

Android-Entwicklerdokumentation:

Referenzdokumentation:

Links zu weiteren Codelabs in diesem Kurs finden Sie auf der Landingpage für Codelabs auf Android-Geräten für Fortgeschrittene.