Dieses Codelab ist Teil des Kurses „Advanced Android in Kotlin“. Sie können den größten Nutzen aus diesem Kurs ziehen, wenn Sie die Codelabs der Reihe nach durcharbeiten. Das ist jedoch nicht zwingend erforderlich. Alle Codelabs des Kurses sind auf der Landingpage für Codelabs zu „Android für Fortgeschrittene mit Kotlin“ aufgeführt.
Wenn Sie Apps mit Google Maps entwickeln, können Sie Ihrer App Funktionen wie Satellitenbilder, robuste 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.
- Ressourcen wie Strings erstellen und verwalten
- 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
- Standortermittlung aktivieren
- Die App
Wander
erstellen, in die eine Google-Karte eingebettet ist - Benutzerdefinierte Funktionen für Ihre App erstellen, z. B. Markierungen und Formatierung
- Standort-Tracking in Ihrer App aktivieren
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 an Orten platzieren, Overlays hinzufügen und Ihren Standort in Echtzeit sehen.
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 & Dienste. 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
- Erstellen Sie ein neues Android Studio-Projekt.
- Wählen Sie die Vorlage Google Maps-Aktivitäten aus.
- Geben Sie dem Projekt den Namen
Wander
. - Legen Sie das Mindest-API-Level auf API 19 fest. Die Sprache muss Kotlin sein.
- Klicken Sie auf Fertig.
- 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
. Mit einem SupportMapFragment
lässt sich eine Karte am einfachsten in eine App einfügen. Es handelt sich um einen Wrapper für eine Kartenansicht, mit dem die erforderlichen Lebenszyklus-Anforderungen automatisch verarbeitet werden.
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 OnMapReadyCallback
-Schnittstelle und die onMapReady()
-Methode dieser Schnittstelle implementieren. Die Methode onMapReady()
wird aufgerufen, wenn die Karte geladen wird.
Schritt 2: API-Schlüssel abrufen
- Öffnen Sie die Debug-Version der Datei google_maps_api.xml.
- Suchen Sie in der Datei nach einem Kommentar mit einer langen URL. Die Parameter der URL enthalten spezifische Informationen zu Ihrer App.
- Kopieren Sie die URL und fügen Sie sie in einen Browser ein.
- Folgen Sie der Anleitung, um auf der Seite APIs & Dienste ein Projekt zu erstellen. Aufgrund der Parameter in der angegebenen URL wird das Maps SDK for Android auf der Seite automatisch aktiviert.
- Klicken Sie auf API-Schlüssel erstellen.
- Rufen Sie auf der nächsten Seite den Bereich „API-Schlüssel“ auf und klicken Sie auf den gerade erstellten Schlüssel.
- 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.
- Kopieren Sie den generierten API-Schlüssel. Er beginnt mit „
AIza"
“. - Fügen Sie in der Datei
google_maps_api.xml
den Schlüssel in den Stringgoogle_maps_key
ein, an der Stelle, an derYOUR_KEY_HERE
steht. - 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.
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
.
- Klicken Sie in
MapsActivity
mit der rechten Maustaste aufmMap
und dann auf Refactor> Rename...
- Ändern Sie den Variablennamen in
map
.
Beachten Sie, dass sich alle Verweise auf mMap
in der Funktion onMapReady()
auch in map
ändern.
Google Maps umfasst mehrere Kartentypen: „Normal“, „Hybrid“, „Satellit“, „Gelände“ und „Keine“ (für keine Karte).
Normal Map | 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:
- Fügen Sie eine App-Leiste mit einem Optionsmenü hinzu, über das der Nutzer den Kartentyp ändern kann.
- Verschieben Sie den Startpunkt der Karte an Ihren eigenen Wohnort.
- Unterstützung für Markierungen hinzugefügt, mit denen einzelne Orte auf einer Karte gekennzeichnet werden können. Markierungen können auch ein Label enthalten.
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.
- 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.
- Geben Sie im Dialogfeld
map_options
als Dateinamen ein. - Wählen Sie Menü als Ressourcentyp aus.
- Klicken Sie auf OK.
- 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 er dazu führt, dass überhaupt 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>
- Fügen Sie in
strings.xml
Ressourcen für dietitle
-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>
- Überschreiben Sie in
MapsActivity
die MethodeonCreateOptionsMenu()
und blähen Sie das Menü aus der Ressourcendateimap_options
auf.
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.map_options, menu)
return true
}
- Überschreiben Sie in
MapsActivity.kt
die MethodeonOptionsItemSelected()
. Ä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)
}
- Starten Sie die App.
- Klicken Sie auf
, um den Kartentyp zu ändern. Achten Sie darauf, wie sich das Aussehen der Karte in den verschiedenen Modi ändert.
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 soll die Kamera der Karte zu Ihrem Zuhause bewegt, auf eine von Ihnen angegebene Ebene gezoomt und dort eine Markierung platziert werden.
Schritt 1: An Ihr Zuhause heranzoomen und eine Markierung hinzufügen
- Suchen Sie in der Datei
MapsActivity.kt
nach der MethodeonMapReady()
. 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
}
- Folgen Sie dieser Anleitung, um die Breiten- und Längenkoordinaten Ihres Zuhauses zu ermitteln.
- 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
- Erstellen Sie ein neues
LatLng
-Objekt mit dem NamenhomeLatLng
. Übergeben Sie imhomeLatLng
-Objekt die Werte, die Sie gerade erstellt haben.
val homeLatLng = LatLng(latitude, longitude)
- 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
: Welt5
: Landmasse/Kontinent10
: Stadt15
: Straßen20
: Gebäude
- Bewegen Sie die Kamera zu
homeLatLng
, indem Sie die FunktionmoveCamera()
für dasmap
-Objekt aufrufen und einCameraUpdate
-Objekt mitCameraUpdateFactory.newLatLngZoom()
übergeben. Übergeben Sie das ObjekthomeLatLng
und diezoomLevel
.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
- Füge der Karte bei
homeLatLng
eine Markierung hinzu.
map.addMarker(MarkerOptions().position(homeLatLng))
Ihre 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))
}
- 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.
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.
- Erstellen Sie in
MapsActivity
einen Methoden-Stub namenssetMapLongClick()
, der einGoogleMap
als Argument akzeptiert. - Fügen Sie dem Kartenobjekt einen
setOnMapLongClickListener
-Listener hinzu.
private fun setMapLongClick(map:GoogleMap) {
map.setOnMapLongClickListener { }
}
- Rufen Sie in
setOnMapLongClickListener()
die MethodeaddMarker()
auf. Übergeben Sie ein neuesMarkerOptions
-Objekt, bei dem die Position auf den übergebenenLatLng
-Wert festgelegt ist.
private fun setMapLongClick(map: GoogleMap) {
map.setOnMapLongClickListener { latLng ->
map.addMarker(
MarkerOptions()
.position(latLng)
)
}
}
- Rufen Sie am Ende der Methode
onMapReady()
setMapLongClick()
mitmap
auf.
override fun onMapReady(googleMap: GoogleMap) {
...
setMapLongClick(map)
}
- Führen Sie die App aus.
- Halten Sie die Karte gedrückt, um eine Markierung an einem Ort zu platzieren.
- Tippen Sie auf die Markierung, um sie auf dem Bildschirm zu zentrieren.
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 auf die Markierung getippt wird.
- Erstellen Sie in
setMapLongClick()setOnMapLongClickListener()
einval
fürsnippet
. 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)
)
}
}
- Legen Sie in
addMarker()
dentitle
der Markierung mit einerR.string.
dropped_pin
-String-Ressource auf „Dropped Pin“ fest. - Setzen Sie den
snippet
des Markers aufsnippet
.
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)
)
}
}
- Führen Sie die App aus.
- Halten Sie die Karte gedrückt, um eine Standortmarkierung zu setzen.
- Tippen Sie 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 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.
- Erstellen Sie in
MapsActivity
einen Methoden-Stub namenssetPoiClick()
, der einGoogleMap
als Argument akzeptiert. - Legen Sie in der Methode
setPoiClick()
einenOnPoiClickListener
für das übergebeneGoogleMap
fest.
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
}
}
- Erstellen Sie in
setOnPoiClickListener()
einval poiMarker
für die Markierung . - Legen Sie sie mit
map.addMarker()
auf eine Markierung fest und legen Sie mitMarkerOptions
dentitle
auf den Namen des POI fest.
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
val poiMarker = map.addMarker(
MarkerOptions()
.position(poi.latLng)
.title(poi.name)
)
}
}
- Rufen Sie in der Funktion
setOnPoiClickListener()
showInfoWindow()
fürpoiMarker
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()
}
}
- Rufen Sie am Ende von
onMapReady()
setPoiClick()
auf und übergeben Siemap
.
override fun onMapReady(googleMap: GoogleMap) {
...
setPoiClick(map)
}
- Führen Sie Ihre App aus und suchen Sie nach einem POI, z. B. einem Park oder einem Café.
- Tippen Sie auf den POI, um eine Markierung darauf zu platzieren und den Namen des POI in einem Infofenster anzeigen zu lassen.
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 des 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 JSON-Code generieren können, nachdem Sie Ihre Karte visuell gestaltet haben. In dieser Aufgabe gestalten Sie die Karte mit einem Retro-Design. Das bedeutet, dass die Karte Vintage-Farben verwendet und Sie farbige Straßen hinzufügen.
Schritt 1: Stil für die Karte erstellen
- Rufen Sie in Ihrem Browser https://mapstyle.withgoogle.com/ auf.
- Wählen Sie Stil erstellen aus.
- Wählen Sie Retro aus.
- Klicke auf Weitere Optionen.
- Wählen Sie in der Liste Funktionstyp die Option Straße> Füllen aus.
- Ändern Sie die Farbe der Straßen in eine beliebige Farbe, z. B. Rosa.
- Klicken Sie auf Fertig.
- 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.
Schritt 2: Stil zur Karte hinzufügen
- Erstellen Sie in Android Studio im Verzeichnis
res
ein Ressourcenverzeichnis mit dem Namenraw
. Sie verwenden dieraw
-Verzeichnisressourcen wie JSON-Code. - Erstellen Sie im Ordner
res/raw
eine Datei mit dem Namenmap_style.json
. - Fügen Sie den zwischengespeicherten JSON-Code in die neue Ressourcendatei ein.
- Erstellen Sie in
MapsActivity
eineTAG
-Klassenvariable über deronCreate()
-Methode. Dies wird für Protokollierungszwecke verwendet.
private val TAG = MapsActivity::class.java.simpleName
- Erstellen Sie auch in
MapsActivity
einesetMapStyle()
-Funktion, die einGoogleMap
akzeptiert. - Fügen Sie in
setMapStyle()
einentry{}
-Block hinzu. - Erstellen Sie im Block
try{}
eineval success
für den Erfolg des Stylings. (Sie fügen den folgenden Catch-Block hinzu.) - Legen Sie im
try{}
-Block den JSON-Stil für die Karte fest, indem SiesetMapStyle()
für dasGoogleMap
-Objekt aufrufen. Übergeben Sie einMapStyleOptions
-Objekt, mit dem die JSON-Datei geladen wird. - Weisen Sie das Ergebnis
success
zu. Die MethodesetMapStyle()
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
)
)
}
}
- Fügen Sie eine IF-Anweisung für den Fall hinzu, dass
success
„false“ ist. Wenn die Formatierung nicht erfolgreich ist, geben Sie ein Protokoll aus, dass die Verarbeitung fehlgeschlagen ist.
private fun setMapStyle(map: GoogleMap) {
try {
...
if (!success) {
Log.e(TAG, "Style parsing failed.")
}
}
}
- Fügen Sie einen
catch{}
-Block hinzu, um den Fall einer fehlenden Formatvorlagendatei zu verarbeiten. Wenn die Datei im Blockcatch
nicht geladen werden kann, geben Sie eineResources.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)
}
}
- Rufen Sie schließlich die Methode
setMapStyle()
in der MethodeonMapReady()
auf und übergeben Sie IhrGoogleMap
-Objekt.
override fun onMapReady(googleMap: GoogleMap) {
...
setMapStyle(map)
}
- Führen Sie die App aus.
- Stellen Sie die Karte auf den Modus
normal
ein. Der neue Stil sollte mit dem Retro-Design und den Straßen in der von Ihnen ausgewählten Farbe sichtbar sein.
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.
- Fügen Sie in der Methode
onMapLongClick()
derMarkerOptions()
des Konstruktors die folgende Codezeile hinzu, 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))
)
}
- Führen Sie die App aus. Die Markierungen, die nach dem langen Klicken angezeigt werden, sind jetzt blau schattiert. POI-Markierungen sind weiterhin rot, da Sie der
onPoiClick()
-Methode kein Styling hinzugefügt haben.
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 Wohnadresse ein Boden-Overlay in Form eines Android hinzu.
- Laden Sie dieses Android-Image herunter und speichern Sie es im Ordner
res/drawable
. Achten Sie darauf, dass der Dateinameandroid.png
lautet.
- Erstellen Sie in
onMapReady()
nach dem Aufruf zum Bewegen der Kamera an die Position Ihres Zuhauses einGroundOverlayOptions
-Objekt. - Weisen Sie das Objekt einer Variablen mit dem Namen
androidOverlay
zu.
val androidOverlay = GroundOverlayOptions()
- Verwenden Sie die Methode
BitmapDescriptorFactory.fromResource()
, um einBitmapDescriptor
-Objekt aus der heruntergeladenen Bildressource zu erstellen. - Übergeben Sie das resultierende
BitmapDescriptor
-Objekt an die Methodeimage()
desGroundOverlayOptions
-Objekts.
val androidOverlay = GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android))
- Erstellen Sie eine
float overlaySize
für die Breite des gewünschten Overlays in Metern. In diesem Beispiel ist eine Breite von100f
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)
- Rufen Sie
addGroundOverlay()
für dasGoogleMap
-Objekt auf und übergeben Sie IhrGroundOverlayOptions
-Objekt.
map.addGroundOverlay(androidOverlay)
- Starten Sie die App.
- Ä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. 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 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 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.
- Prüfen Sie in der Datei
AndroidManifest.xml
, ob die BerechtigungFINE_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" />
- Erstellen Sie in
MapsActivity
eineREQUEST_LOCATION_PERMISSION
-Klassenvariable.
private val REQUEST_LOCATION_PERMISSION = 1
- Wenn Sie prüfen möchten, ob Berechtigungen erteilt wurden, erstellen Sie in
MapsActivity
die MethodeisPermissionGranted()
. 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
}
- Wenn Sie die Standortverfolgung in Ihrer App aktivieren möchten, erstellen Sie in
MapsActivity
eine Methode namensenableMyLocation()
, die keine Argumente akzeptiert und nichts zurückgibt. Prüfen Sie, ob Sie die BerechtigungACCESS_FINE_LOCATION
haben. Wenn die Berechtigung erteilt wurde, aktivieren Sie die Standorte-Ebene. 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
)
}
}
- Rufen Sie
enableMyLocation()
über denonMapReady()
-Callback auf, um die Standortebene zu aktivieren.
override fun onMapReady(googleMap: GoogleMap) {
...
enableMyLocation()
}
- Überschreiben Sie die Methode
onRequestPermissionsResult()
. WennrequestCode
gleichREQUEST_LOCATION_PERMISSION
ist, wird die Berechtigung erteilt. Wenn dasgrantResults
-Array nicht leer ist undPackageManager.PERMISSION_GRANTED
im ersten Slot enthält, wirdenableMyLocation()
aufgerufen.
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray) {
if (requestCode == REQUEST_LOCATION_PERMISSION) {
if (grantResults.contains(PackageManager.PERMISSION_GRANTED)) {
enableMyLocation()
}
}
}
- 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.
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 weg bewegen 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, entzippen und in Android Studio öffnen.
- Wenn Sie die Maps API verwenden möchten, benötigen Sie einen API-Schlüssel aus der Google API Console.
- Wenn Sie in Android Studio die Google Maps Activity-Vorlage verwenden, wird ein
Activity
mit einem einzelnenSupportMapFragment
im Layout der App generiert. Die Vorlage fügt dem App-Manifest auchACCESS_FINE_PERMISSION
hinzu, implementiertOnMapReadyCallback
in Ihrer Aktivität und überschreibt die erforderliche MethodeonMapReady()
.
Wenn Sie den Kartentyp eines GoogleMap
zur Laufzeit ändern möchten, verwenden Sie die Methode GoogleMap.setMapType()
. Eine Google-Karte kann 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: Enthält Satellitenfotodaten mit zusätzlichen 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 geografischen Standort.
- Wenn auf die Markierung getippt wird, wird standardmäßig ein Infofenster mit Informationen zum Ort eingeblendet.
- Standardmäßig werden Points of Interest (POIs) zusammen mit ihren Icons auf der Karte dargestellt. POIs sind beispielsweise Parks, Schulen und Behördengebä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 Styling-Assistenten können Sie das Erscheinungsbild fast aller Elemente einer Google-Karte ändern. Mit dem Styling Wizard wird eine JSON-Datei generiert, die Sie mit der Methode
setMapStyle()
an die Google-Karte übergeben. - Sie können die Markierungen anpassen, indem Sie die Standardfarbe ändern oder das Standardmarkierungssymbol durch ein benutzerdefiniertes Bild ersetzen.
Weitere wichtige Informationen:
- Mit einem Boden-Overlay können Sie ein Bild an einem geografischen Ort fixieren.
- Verwenden Sie ein
GroundOverlayOptions
-Objekt, um das Bild, die Größe des Bildes in Metern und die Position des Bildes anzugeben. Übergeben Sie dieses Objekt an dieGoogleMap.addGroundOverlay()
-Methode, um das Overlay auf der Karte festzulegen. - Wenn Ihre App die Berechtigung
ACCESS_FINE_LOCATION
hat, können Sie die Standortverfolgung aktivieren, indem Siemap.isMyLocationEnabled = true
festlegen. - Das wird in diesem Codelab nicht behandelt, aber Sie können mit Google Street View zusätzliche Informationen zu einem Ort bereitstellen. Dabei handelt es sich um ein navigierbares Panoramabild eines bestimmten Ortes.
Android-Entwicklerdokumentation:
- Jetzt starten
- Karte mit einer Markierung hinzufügen
- Kartenobjekte
- Karte mit benutzerdefinierten Stilen hinzufügen
- Street View
- Boden-Overlays
Referenzdokumentation:
Links zu anderen Codelabs in diesem Kurs finden Sie auf der Landingpage für die Codelabs zum Thema „Fortgeschrittenes Android in Kotlin“.