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

1. Hinweis

Wenn Sie Apps mit Google Maps entwickeln, können Sie Ihrer App Funktionen wie Satellitenbilder, leistungsstarke UI-Steuerelemente für Karten, Standortverfolgung und Standortmarkierungen hinzufügen. Sie können Google Maps um Informationen aus Ihrem eigenen Datensatz ergänzen, z. B. um die Standorte bekannter Angel- oder Klettergebiete. Sie können auch Spiele erstellen, in denen der Spieler die physische Welt erkundet, z. B. eine Schatzsuche oder sogar Augmented Reality-Spiele.

In dieser Lektion erstellen Sie eine Google Maps-App namens „Wander“, in der benutzerdefinierte Karten angezeigt werden und der Standort des Nutzers zu sehen ist.

Vorbereitung

Kenntnisse in folgenden Bereichen:

  • So erstellen Sie eine einfache Android-App und führen sie mit Android Studio aus.
  • So erstellen und verwalten Sie Ressourcen wie Strings.
  • Code umgestalten und Variablen mit Android Studio umbenennen
  • Google Maps als Nutzer verwenden
  • Laufzeitberechtigungen festlegen

Lerninhalte

  • API-Schlüssel über die Google API Console abrufen und für Ihre App registrieren
  • Google Maps in Ihre App einbinden
  • Verschiedene Kartentypen anzeigen
  • Google Maps-Karte gestalten
  • Markierungen zur Karte hinzufügen
  • Nutzer in die Lage versetzen, eine Markierung auf einem POI zu platzieren
  • Standortverfolgung aktivieren
  • Die App Wander erstellen, in die eine Google-Karte eingebettet ist
  • Benutzerdefinierte Funktionen für Ihre App erstellen, z. B. Markierungen und Formatierung
  • Standortverfolgung in Ihrer App aktivieren

2. App-Übersicht

In diesem Codelab erstellen Sie die App Wander, in der eine Google-Karte mit benutzerdefinierten Stilen angezeigt wird. Mit der Wander-App können Sie Markierungen auf Standorte setzen, Overlays hinzufügen und Ihren 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 auf der Seite APIs & Services. Der API-Schlüssel ist an ein digitales Zertifikat gebunden, das die App mit ihrem 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 Debugzertifikat ist von Natur aus unsicher, wie im Abschnitt 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 Release-Zertifikat. Weitere Informationen zum Abrufen eines Release-Zertifikats finden Sie unter API-Schlüssel verwenden.

Android Studio enthält eine Google Maps-Aktivitätsvorlage, mit der hilfreicher Vorlagencode generiert wird. 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-Aktivitäten aus.

d6b874bb19ea68cd.png

  1. Nennen Sie das Projekt Wander.
  2. Legen Sie das Mindest-API-Level auf API 19 fest. Die Sprache muss Kotlin sein.
  3. Klicken Sie auf Fertig.
  4. Sehen Sie sich nach dem Erstellen der App Ihr Projekt und die folgenden kartenbezogenen Dateien an, die Android Studio für Sie erstellt:

google_maps_api.xml: In dieser Konfigurationsdatei wird Ihr API-Schlüssel gespeichert. Mit der Vorlage werden zwei google_maps_api.xml-Dateien generiert: eine für Debugging 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 verwenden 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 abgeleitete Klasse der Klasse Fragment. Ein SupportMapFragment ist die einfachste Möglichkeit, eine Karte in eine App einzufügen. Es handelt sich um einen Wrapper für eine Kartenansicht, der die erforderlichen Lebenszyklus-Anforderungen automatisch verarbeitet.

Sie können SupportMapFragment in eine Layoutdatei einfügen, indem Sie in einem beliebigen ViewGroup ein <fragment>-Tag mit einem zusätzlichen name-Attribut verwenden.

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

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

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 Parameter der URL 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 & Dienste zu erstellen. Aufgrund der Parameter in der angegebenen URL wird das Maps SDK for Android auf der Seite automatisch aktiviert.
  5. Klicken Sie auf API-Schlüssel erstellen.
  6. Rufen Sie auf der nächsten Seite den Bereich „API-Schlüssel“ auf und klicken Sie auf den gerade 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. Er beginnt mit „AIza"“.
  9. Fügen Sie in der Datei google_maps_api.xml den Schlüssel in den String google_maps_key ein, an der Stelle, an der YOUR_KEY_HERE steht.
  10. Führen Sie die App aus. In Ihrer Aktivität sollte eine eingebettete Karte mit einer Markierung für Sydney (Australien) angezeigt werden. Die Markierung für Sydney ist Teil der Vorlage und wird später geändert.

34dc9dd877c90996.png

Schritt 3: mMap umbenennen

MapsActivity hat ein privates lateinit var mit dem Namen mMap vom Typ GoogleMap. Um den Kotlin-Namenskonventionen zu entsprechen, ändern Sie den Namen von mMap in map.

  1. Klicken Sie in MapsActivity mit der rechten Maustaste auf mMap und dann auf Refactor > Rename...

e713ccb3384450c6.png

  1. Ändern Sie den Variablennamen in map.

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

4. Aufgabe: Kartentypen hinzufügen

Google Maps umfasst mehrere Kartentypen: „Normal“, „Hybrid“, „Satellit“, „Gelände“ und „Keine“ (für keine Karte).

Normale Karte

Satellitenkarte

Hybridkarte

Geländekarte

Jeder Kartentyp bietet unterschiedliche Informationen. Wenn Sie beispielsweise Karten zur Navigation in einem Auto verwenden, ist es hilfreich, Straßennamen zu sehen. In diesem Fall sollten Sie die normale Option verwenden. Beim Wandern kann die Geländekarte hilfreich sein, um zu entscheiden, wie viel Sie noch aufsteigen müssen, um den Gipfel zu erreichen.

In dieser Aufgabe führen Sie folgende Schritte aus:

  1. Fügen Sie eine App-Leiste mit einem Optionsmenü hinzu, über das der Nutzer den Kartentyp ändern kann.
  2. Verschieben Sie den Startpunkt der Karte an Ihren eigenen Wohnort.
  3. Unterstützung für Markierungen hinzugefügt, mit denen einzelne Orte auf einer Karte gekennzeichnet werden können und die ein Label enthalten können.

Menü für Kartentypen hinzufügen

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

  1. Klicken Sie zum Erstellen einer neuen XML-Datei für das Menü mit der rechten Maustaste auf das Verzeichnis res und wählen Sie Neu > Android-Ressourcendatei aus.
  2. Geben Sie im Dialogfeld map_options als Dateinamen ein.
  3. Wählen Sie Menü als Ressourcentyp 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 Menüoptionen für die Karte zu erstellen. Der Kartentyp „none“ wird ausgelassen, da er dazu führt, dass keine Karte angezeigt wird. Dieser Schritt führt zu einem 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. Überschreiben Sie in MapsActivity die Methode onCreateOptionsMenu() und blähen Sie 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(). Ändern Sie den Kartentyp mithilfe von Konstanten für Kartentypen, um die Auswahl des Nutzers zu berücksichtigen.
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. Achten Sie darauf, wie sich das Aussehen der Karte in den verschiedenen Modi ändert.

6fa42970d87f5dc7.png

5. Aufgabe: Markierungen hinzufügen

Standardmäßig enthält der onMapReady()-Callback Code, mit dem eine Markierung in Sydney, Australien, platziert wird, wo Google Maps entwickelt wurde. Der Standard-Callback animiert die Karte auch so, dass sie auf Sydney geschwenkt wird.

In dieser Aufgabe lassen Sie die Kamera der Karte zu Ihrem Zuhause bewegen, auf eine von Ihnen angegebene Ebene zoomen und dort eine Markierung platzieren.

Schritt 1: Zuhause heranzoomen und Markierung hinzufügen

  1. Suchen Sie in der Datei MapsActivity.kt nach der Methode onMapReady(). Entfernen Sie den Code, mit dem die Markierung in Sydney platziert und die Kamera bewegt wird. So sollte die Methode jetzt 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 die entsprechenden 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 Werte, die Sie gerade erstellt haben.
val homeLatLng = LatLng(latitude, longitude)
  1. Erstellen Sie einen val für den gewünschten Zoomfaktor der Karte. Verwenden Sie die Zoomstufe 15f.
val zoomLevel = 15f

Mit der Zoomstufe wird festgelegt, wie stark Sie in die Karte hineingezoomt sind. Die folgende Liste gibt Ihnen einen Eindruck davon, welche Detailebene bei den einzelnen Zoomstufen angezeigt wird:

  • 1: Welt
  • 5: Landmasse/Kontinent
  • 10: Stadt
  • 15: Straßen
  • 20: Gebäude
  1. Bewegen Sie die Kamera zu homeLatLng, indem Sie die Funktion moveCamera() für das map-Objekt aufrufen und ein CameraUpdate-Objekt mit CameraUpdateFactory.newLatLngZoom() übergeben. Übergeben Sie das Objekt homeLatLng und die zoomLevel.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
  1. Füge 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 schwenken, auf die gewünschte Stufe zoomen und eine Markierung auf Ihrem Zuhause platzieren.

fc939024778ee76.png

Schritt 2: Nutzern erlauben, Markierungen durch langes Klicken hinzuzufügen

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

  1. Erstellen Sie in MapsActivity einen Methoden-Stub namens setMapLongClick(), der ein GoogleMap als Argument akzeptiert.
  2. Hängen Sie dem Kartenobjekt einen setOnMapLongClickListener-Listener an.
private fun setMapLongClick(map:GoogleMap) {
   map.setOnMapLongClickListener { }
}
  1. Rufen Sie in setOnMapLongClickListener() die Methode addMarker() auf. Übergeben Sie ein neues MarkerOptions-Objekt, bei dem die Position auf den übergebenen LatLng-Wert 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 die App aus.
  2. Halten Sie die Karte gedrückt, um eine Markierung an einem Ort zu platzieren.
  3. Tippen Sie auf die Markierung, um sie auf dem Bildschirm zu zentrieren.

4ff8d1c1db3bca9e.png

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

In diesem Schritt fügen Sie ein InfoWindow hinzu, in dem die Koordinaten der Markierung angezeigt werden, wenn darauf getippt wird.

  1. Erstellen Sie in setMapLongClick()setOnMapLongClickListener() ein val für snippet. Ein Snippet ist zusätzlicher Text, der nach dem Titel angezeigt wird. In Ihrem Snippet werden der Längen- und der Breitengrad 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. Legen Sie in addMarker() den title der Markierung mit einer R.string.dropped_pin-String-Ressource auf „Dropped Pin“ fest.
  2. Setzen Sie den Wert snippet des Markers 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 die App aus.
  2. Halten Sie die Karte gedrückt, um eine Standortmarkierung zu setzen.
  3. Tippen Sie auf die Markierung, um das Infofenster aufzurufen.

63f210e6e47dfa29.png

Schritt 4: POI-Listener hinzufügen

Standardmäßig werden Points of Interest (POIs) zusammen mit den entsprechenden Symbolen auf der Karte dargestellt. 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. Dieser Klick-Listener platziert sofort eine Markierung auf der Karte, wenn der Nutzer auf einen POI klickt. Der Klick-Listener zeigt auch ein Infofenster mit dem Namen des POI an.

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

   }
}
  1. Erstellen Sie in setOnPoiClickListener() ein val poiMarker für die Markierung .
  2. Legen Sie sie mit map.addMarker() auf eine Markierung fest. Mit MarkerOptions wird title auf den Namen des POI festgelegt.
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() die Methode showInfoWindow() für 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. 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 nach einem POI, z. B. einem Park oder einem Café.
  2. Tippen Sie auf den POI, um eine Markierung darauf zu platzieren und den Namen des POI in einem Infofenster anzuzeigen.

f4b0972c75d5fa5f.png

6. Aufgabe: Karte gestalten

Sie können Google Maps auf vielfältige Weise anpassen und Ihrer Karte so ein einzigartiges Erscheinungsbild verleihen.

Sie können ein MapFragment-Objekt mit den verfügbaren XML-Attributen anpassen, wie Sie es auch bei anderen Fragmenten tun würden. In diesem Schritt passen Sie jedoch das Erscheinungsbild des Inhalts von MapFragment mit Methoden für das GoogleMap-Objekt an.

Wenn Sie einen benutzerdefinierten Stil für Ihre Karte erstellen möchten, generieren Sie eine JSON-Datei, in der angegeben wird, wie die Elemente auf der Karte dargestellt werden. Sie müssen diese JSON-Datei nicht manuell erstellen. Google bietet den Maps Platform Styling Wizard an, mit dem Sie die JSON-Datei generieren können, nachdem Sie Ihre Karte visuell gestaltet haben. In dieser Aufgabe gestalten Sie die Karte mit einem Retro-Design. Das bedeutet, dass Sie Vintage-Farben verwenden und farbige Straßen hinzufügen.

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.

208b3d3aeab0d9b6.png

  1. Klicke auf Weitere Optionen.

4a35faaf9535ee82.png

  1. Wählen Sie Road > Fill (Straße > Füllen) aus.
  2. Ändern Sie die Farbe der Straßen in eine beliebige Farbe, z. B. Rosa.

92c3293749293a4c.png

  1. Klicken Sie auf Fertig.

f1bfe8585eb69480.png

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

3c32168b299d6420.png

Schritt 2: Stil zur Karte hinzufügen

  1. Erstellen Sie in Android Studio im Verzeichnis res ein Ressourcenverzeichnis mit dem Namen raw. Sie verwenden die raw-Verzeichnisressourcen wie JSON-Code.
  2. Erstellen Sie im Ordner res/raw eine Datei mit dem Namen map_style.json.
  3. Fügen Sie den zwischengespeicherten JSON-Code in die neue Ressourcendatei ein.
  4. Erstellen Sie in MapsActivity eine TAG-Klassenvariable über der onCreate()-Methode. Dies wird für Protokollierungszwecke verwendet.
private val TAG = MapsActivity::class.java.simpleName
  1. Erstellen Sie auch in MapsActivity eine setMapStyle()-Funktion, die eine GoogleMap akzeptiert.
  2. Fügen Sie in setMapStyle() einen try{}-Block hinzu.
  3. Erstellen Sie im Block try{} eine val success für den Erfolg des Stylings. (Sie fügen den folgenden Catch-Block hinzu.)
  4. Legen Sie im try{}-Block den JSON-Stil für die Karte fest, indem Sie setMapStyle() für das GoogleMap-Objekt aufrufen. Übergeben Sie ein MapStyleOptions-Objekt, um die JSON-Datei zu laden.
  5. Weisen Sie das Ergebnis success zu. Die Methode setMapStyle() gibt einen booleschen Wert zurück, der den Erfolgsstatus des Parsens der Formatierungsdatei und des Festlegens 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 den Fall hinzu, dass success „false“ ist. Wenn das Styling nicht erfolgreich ist, wird ein Protokoll ausgegeben, dass das Parsen fehlgeschlagen 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 behandeln. Wenn die Datei im catch-Block nicht geladen werden kann, geben Sie eine Resources.NotFoundException aus.
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
   } catch (e: Resources.NotFoundException) {
       Log.e(TAG, "Can't find style. Error: ", e)
   }
}

Die fertige Methode sollte 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 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 die App aus.
  2. Stellen Sie die Karte auf den normal-Modus ein. Der neue Stil sollte mit dem Retro-Design und den Straßen in der von Ihnen ausgewählten Farbe sichtbar 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 Cooleres.

  1. Fügen Sie in der Methode onMapLongClick() die folgende Codezeile in den MarkerOptions() des Konstruktors ein, um die Standardmarkierung zu verwenden, aber die Farbe in Blau zu ändern.
.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 dem langen Klicken angezeigt werden, sind jetzt blau schattiert. Die POI-Markierungen sind weiterhin rot, da Sie der onPoiClick()-Methode kein Styling hinzugefügt haben.

b9916bca3c367e3.png

7. Aufgabe: Overlay hinzufügen

Eine Möglichkeit, die 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 Unterschied zu Markierungen sind Boden-Overlays an der Erdoberfläche und nicht am Bildschirm ausgerichtet. Wenn Sie die Karte drehen, neigen oder zoomen, ändert sich die Ausrichtung des Bildes. Boden-Overlays sind nützlich, um ein einzelnes Bild an einem Punkt der Karte zu fixieren.

Schritt: Boden-Overlay hinzufügen

In dieser Aufgabe fügen Sie Ihrer Heimatadresse ein Boden-Overlay in Form eines Android hinzu.

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

61fabd56a0841b44.png

  1. Erstellen Sie in onMapReady() nach dem Aufruf zum Bewegen der Kamera zur Position Ihres Zuhauses ein GroundOverlayOptions-Objekt.
  2. Weisen Sie das Objekt einer Variablen mit dem Namen 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 Methode image() des GroundOverlayOptions-Objekts.
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
  1. Erstellen Sie eine 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 Eigenschaft position für das Objekt GroundOverlayOptions fest, indem Sie die Methode position() aufrufen und das Objekt homeLatLng und die overlaySize ü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 Ihr GroundOverlayOptions-Objekt.
map.addGroundOverlay(androidOverlay)
  1. Starten Sie die App.
  2. Ändern Sie den Wert von zoomLevel in 18f, um das Android-Bild als Overlay zu sehen.

b1b25b0acd6a9807.png

8. Aufgabe: Standortverfolgung aktivieren

Nutzer verwenden Google Maps häufig, um ihren aktuellen Standort zu sehen. Wenn Sie den Gerätestandort auf Ihrer Karte anzeigen möchten, können Sie die Ebene mit Standortdaten verwenden.

Durch die Ebene mit Standortdaten wird das Symbol Mein Standort auf der Karte angezeigt.

f317f84dcb3ac3a1.png

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 Navigationspfeil, wenn das Gerät in Bewegung ist.

In dieser Aufgabe aktivieren Sie die Ebene mit Standortdaten.

Schritt: Berechtigungen zur Standortermittlung anfordern

Um die Standortverfolgung in Google Maps zu aktivieren, ist nur eine Codezeile erforderlich. Sie müssen jedoch dafür sorgen, dass der Nutzer Standortberechtigungen erteilt hat (mit dem Laufzeitberechtigungsmodell).

In diesem Schritt fordern Sie Berechtigungen 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. Wenn Sie prüfen möchten, ob Berechtigungen erteilt wurden, erstellen Sie in MapsActivity die Methode isPermissionGranted(). Prüfen Sie in 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 die Standortverfolgung in Ihrer App aktivieren möchten, erstellen Sie in MapsActivity eine Methode namens enableMyLocation(), die keine Argumente akzeptiert und nichts zurückgibt. Prüfen Sie, ob Sie die Berechtigung ACCESS_FINE_LOCATION haben. 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. Rufen Sie 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. Wenn ja, bedeutet das, dass die Berechtigung erteilt wurde. Wenn die Berechtigung erteilt wurde, prüfen Sie auch, ob das grantResults-Array PackageManager.PERMISSION_GRANTED im ersten Slot enthält. Wenn das der Fall ist, rufen Sie enableMyLocation() an.
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. Erteilen Sie die Berechtigung.

da7e23e00ec762c1.png

Auf der Karte wird jetzt der aktuelle Standort des Geräts als blauer Punkt angezeigt. Beachten Sie, dass es einen Standort-Button gibt. Wenn Sie die Karte von Ihrem Standort weg bewegen 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, entzippen und in Android Studio öffnen.

10. Zusammenfassung

Glückwunsch! Sie haben eine Google-Karte in eine Android-Kotlin-App eingefügt und sie gestaltet.

11. Weitere Informationen

Android-Entwicklerdokumentation:

Referenzdokumentation:

12. Nächstes Codelab

Links zu anderen Codelabs in diesem Kurs finden Sie auf der Landingpage für die Codelabs zum Thema „Erweitertes Android in Kotlin“.