Kartenobjekte

Karten werden in der API durch die Klassen GoogleMap und MapFragment dargestellt.

Codebeispiele

Das ApiDemos-Repository auf GitHub enthält Beispiele, in denen das Verwenden des GoogleMap-Objekts und des SupportMapFragment-Elements veranschaulicht wird:

Karte in eine Android-App einbinden

Um eine Karte hinzuzufügen, sind folgende grundlegende Schritte erforderlich:

  1. Du musst dieses Verfahren nur einmal ausführen: Befolge die Anleitung im Leitfaden zur Projektkonfiguration, um die API zu erhalten, einen Schlüssel abzurufen und dem Android-Manifest die erforderlichen Attribute hinzuzufügen.
  2. Füge dem Activity-Element ein Fragment-Objekt hinzu, mit dem die Karte verarbeitet wird. Am einfachsten ist es, der Layoutdatei für Activity ein <fragment>-Element hinzuzufügen.
  3. Implementiere die Schnittstelle OnMapReadyCallback und verwende die Callback-Methode onMapReady(GoogleMap), um einen Ziehpunkt für das Objekt GoogleMap zu erhalten. Das Objekt GoogleMap ist die interne Darstellung der eigentlichen Karte. Um die Ansichtsoptionen für eine Karte festzulegen, ändere das dazugehörige Objekt GoogleMap.
  4. Rufe getMapAsync() auf dem Fragment auf, um den Callback zu registrieren.

Nachfolgend erhältst du ausführlichere Informationen zu den einzelnen Schritten.

Fragment hinzufügen

Füge der Layoutdatei der Aktivität ein <fragment>-Element hinzu, um ein Fragment-Objekt zu definieren. Lege in diesem Element das android:name-Attribut auf "com.google.android.gms.maps.MapFragment" fest. Dadurch wird automatisch ein MapFragment-Element an die Aktivität angefügt.

Die folgende Layoutdatei enthält ein <fragment>-Element:

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    android:name="com.google.android.gms.maps.MapFragment"
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Du kannst auch ein MapFragment einem Activity-Element im Code hinzufügen. Dazu erstellst du eine neue MapFragment-Instanz und rufst dann FragmentTransaction.add() auf, um das Fragment dem aktuellen Activity-Element hinzuzufügen.

 mMapFragment = MapFragment.newInstance();
 FragmentTransaction fragmentTransaction =
         getFragmentManager().beginTransaction();
 fragmentTransaction.add(R.id.my_container, mMapFragment);
 fragmentTransaction.commit();

Kartencode hinzufügen

Um mit der Karte in deiner App zu arbeiten, musst du die Schnittstelle OnMapReadyCallback implementieren und eine Instanz des Callbacks in einem MapFragment- oder MapView-Objekt definieren. In dieser Anleitung wird MapFragment verwendet, weil das die gängigste Methode zum Hinzufügen einer Karte ist. Im ersten Schritt implementierst du die Callback-Schnittstelle:

public class MainActivity extends FragmentActivity
    implements OnMapReadyCallback {
...
}

Lege in der onCreate()-Methode von Activity die Layoutdatei als Inhaltsansicht fest. Wenn die Layoutdatei beispielsweise den Namen main.xml hat, verwende diesen Code:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    ...
}

Erstelle einen Ziehpunkt zum Fragment, indem du FragmentManager.findFragmentById() aufrufst und die Ressourcen-ID des <fragment>-Elements übergibst. Die Ressourcen-ID R.id.map wird dem Android-Projekt automatisch hinzugefügt, wenn du die Layoutdatei erstellst.

Verwende dann getMapAsync(), um den Callback für das Fragment festzulegen.

MapFragment mapFragment = (MapFragment) getFragmentManager()
    .findFragmentById(R.id.map);
mapFragment.getMapAsync(this);

Verwende die Callback-Methode onMapReady(GoogleMap), um einen Ziehpunkt zum Objekt GoogleMap zu erhalten. Der Callback wird ausgelöst, sobald die Karte einsatzbereit ist. Er stellt eine Nicht-NULL-Instanz von GoogleMap bereit. Du kannst das Objekt GoogleMap verwenden, um Ansichtsoptionen für die Karte festzulegen oder eine Markierung hinzuzufügen.

@Override
public void onMapReady(GoogleMap map) {
    map.addMarker(new MarkerOptions()
        .position(new LatLng(0, 0))
        .title("Marker"));
}

Kartenobjekt

Mit dem Maps SDK for Android kannst du eine Google-Karte in deiner Android-Anwendung darstellen. Diese Karten sehen genauso aus wie in der mobilen App von Google Maps und die API stellt viele derselben Funktionen bereit. Das sind die beiden wichtigsten Unterschiede zwischen der mobilen App von Google Maps und den Karten, die durch Maps SDK for Android dargestellt werden:

  • Von der API angezeigte Kartenkacheln enthalten keine personalisierten Inhalte, z. B. personalisierte intelligente Symbole.
  • Nicht alle Symbole auf der Karte sind anklickbar. Beispielsweise kann nicht auf Symbole für Haltestellen öffentlicher Verkehrsmittel geklickt werden. Der Nutzer kann jedoch auf Markierungen klicken, die du der Karte hinzufügst. Die API hat eine Listener-Callback-Schnittstelle für verschiedene Markierungsinteraktionen.

Zusätzlich zur Kartendarstellungsfunktion unterstützt die API auch zahlreiche Interaktionen, die mit dem Android-UI-Modell kompatibel sind. Damit Nutzer mit einer Karte interagieren können, kannst du zum Beispiel Listener definieren, die auf Touch-Gesten reagieren.

Die wichtigste Klasse bei einem Kartenobjekt ist die Klasse GoogleMap. GoogleMap modelliert das Kartenobjekt innerhalb deiner App. Auf deiner UI wird eine Karte entweder durch ein MapFragment- oder MapView-Objekt dargestellt.

Mit GoogleMap werden folgende Vorgänge automatisch verarbeitet:

  • Verbindung zum Google Maps-Dienst herstellen
  • Kartenkacheln herunterladen
  • Kacheln auf dem Gerätebildschirm anzeigen
  • Verschiedene Steuerelemente z. B. zum Schwenken und Zoomen anzeigen
  • Auf Gesten zum Schwenken und Zoomen reagieren, indem die Karte verschoben oder vergrößert bzw. verkleinert wird

Zusätzlich zu diesen automatischen Vorgängen kannst du die Funktionsweise von Karten auch mit Objekten und Methoden der API steuern. Beispielsweise umfasst GoogleMap Callback-Methoden, die auf Tastaturanschläge und Touch-Gesten auf der Karte reagieren. Außerdem kannst du auf deiner Karte Markierungssymbole einrichten und diese durch Overlays ergänzen. Dazu verwendest du Objekte, die du für GoogleMap bereitstellst.

MapFragment

Mit MapFragment, einer Teilklasse der Android-Klasse Fragment, kannst du eine Karte in einem Android-Fragment platzieren. MapFragment-Objekte fungieren als Container für die Karte und bieten Zugriff auf das GoogleMap-Objekt.

Im Unterschied zu View stellt Fragment eine Funktionsweise oder einen Teil der Benutzeroberfläche (UI) in einer Aktivität dar. Du kannst mehrere Fragmente in einer einzigen Aktivität kombinieren, um eine UI mit mehreren Fensterbereichen zu erstellen und ein Fragment in mehreren Aktivitäten wiederzuverwenden. Weitere Informationen findest du in der Android-Dokumentation zu Fragmenten.

MapView

Mit MapView, einer Teilklasse der Android-Klasse View, kannst du eine Karte in einem Android-View platzieren. Ein View-Element repräsentiert einen rechteckigen Bereich des Bildschirms und bildet einen Basisbaustein für Android-Apps und -Widgets. Ähnlich wie MapFragment fungiert MapView als Container für die Karte und stellt grundlegende Kartenfunktionen über das GoogleMap-Objekt bereit.

Wird die API im vollständig interaktiven Modus verwendet, müssen Nutzer der Klasse MapView die folgenden Methoden des Aktivitätslebenszyklus an die entsprechenden Methoden in der Klasse MapView weiterleiten: onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy(), onSaveInstanceState() und onLowMemory(). Das ApiDemos-Repository auf GitHub enthält ein Beispiel, das zeigt, wie die Methoden des Aktivitätslebenszyklus weitergeleitet werden. Wenn die API im Lite-Modus eingesetzt wird, ist das Weiterleiten von Lebenszyklusereignissen optional. Weitere Informationen findest du in der Dokumentation zum Lite-Modus.

Kartentypen

Im Maps SDK for Android sind viele verschiedene Kartentypen verfügbar. Der Typ einer Karte ist entscheidend für ihre Gesamtdarstellung. Beispielsweise enthält ein Atlas meist politische Karten, mit denen in erster Linie Grenzen dargestellt werden, während auf Straßenkarten vor allem die Straßen einer Stadt oder Region zu sehen sind.

Das Maps SDK for Android umfasst vier Kartentypen sowie die Option zum Verzicht auf jegliche Karten:

Normal
Typische Straßenkarte. Straßen, einige von Menschen geschaffene Merkmale und wichtige Landschaftsmerkmale wie Flüsse werden angezeigt. Die dazugehörigen Labels sind ebenfalls sichtbar.
Hybrid
Enthält Satellitenfotodaten mit zusätzlichen Straßenkarten. Die dazugehörigen Labels sind ebenfalls sichtbar.
Satellit
Enthält Satellitenfotodaten. Straßen und sonstige Merkmale sind nicht beschriftet.
Gelände
Enthält topografische Daten. Die Karte umfasst Farben, Höhenlinien und Labels sowie perspektivische Schattierungen. Außerdem werden einige Straßen und Labels dargestellt.
Enthält keine Kacheln. Diese Karte wird als leeres Raster ohne geladene Kacheln gerendert.

Kartentyp ändern

Um den Typ einer Karte festzulegen, rufst du die setMapType()-Methode des GoogleMap-Objekts auf und übergibst eine der Typkonstanten, die in GoogleMap definiert sind. Eine Satellitenkarte lässt sich beispielsweise so aufrufen:

GoogleMap map;
...
// Sets the map type to be "hybrid"
map.setMapType(GoogleMap.MAP_TYPE_HYBRID);

Die folgende Abbildung zeigt einen Vergleich der Kartentypen "Normal", "Hybrid" und "Gelände" für denselben Standort:

MapType-Vergleich

Indoor-Karten

Bei einem hohen Zoomfaktor sind auf der Karte Gebäudepläne für Innenbereiche wie z. B. Flughäfen, Einkaufszentren, große Einzelhandelsgeschäfte und Haltestellen öffentlicher Verkehrsmittel zu sehen. Diese Gebäudepläne, auch als Indoor-Karten bezeichnet, werden für die Kartentypen "normal" und "Satellit" (GoogleMap.MAP_TYPE_NORMAL und GoogleMap.MAP_TYPE_SATELLITE) angezeigt. Sie werden automatisch aktiviert, wenn der Nutzer heranzoomt, und ausgeblendet, wenn er wieder herauszoomt.

Hinweis zur Einstellung: In einem zukünftigen Release sind Indoor-Karten nur für den Kartentyp normal verfügbar. Nicht mehr unterstützt werden Indoor-Karten vom Typ satellite, terrain und hybrid. Auch wenn sie nicht unterstützt werden, gibt isIndoorEnabled() weiterhin den Wert zurück, der über setIndoorEnabled() festgelegt wurde. Standardmäßig ist setIndoorEnabled auf true festgelegt. In den Versionshinweisen erfährst du, wann die Indoor-Unterstützung für diese Kartentypen nicht mehr verfügbar ist.

Beispiel für eine Indoor-Karte

Mit Indoor-Karten in der API arbeiten

Hier sind die API-Funktionen für Indoor-Karten zusammengefasst:

  • Du kannst Indoor-Karten durch den Aufruf von GoogleMap.setIndoorEnabled(false) deaktivieren. Standardmäßig sind Indoor-Karten aktiviert. Indoor-Karten werden jeweils auf einer Karte angezeigt. Das ist standardmäßig die erste Karte, die deiner App hinzugefügt wird. Wenn du Indoor-Karten auf einer anderen Karte anzeigen möchtest, deaktiviere sie auf der ersten Karte und rufe setIndoorEnabled(true) auf der zweiten Karte auf.
  • Um die Standardauswahl für die Ebene (Etagenauswahl) zu deaktivieren, rufst du GoogleMap.getUiSettings().setIndoorLevelPickerEnabled(false) auf. Weitere Informationen findest du unter Mit der Karte interagieren.
  • Mithilfe der Schnittstelle OnIndoorStateChangeListener in GoogleMap kannst du einen Listener festlegen, der aufgerufen wird, wenn ein neues Gebäude fokussiert oder eine neue Etage in einem Gebäude aktiviert wird. Weitere Informationen findest du unter Mit der Karte interagieren.
  • Mit GoogleMap.getFocusedBuilding() wird das Gebäude abgerufen, das derzeit im Fokus ist. Anschließend kannst du die derzeit aktive Ebene durch Aufrufen von IndoorBuilding.getActiveLevelIndex() ermitteln. In der Referenzdokumentation findest du alle Informationen, die in den Objekten IndoorBuilding und IndoorLevel verfügbar sind.

Der Stil der Basiskarte wirkt sich nicht auf Indoor-Karten aus.

Gebäudepläne hinzufügen

Indoor-Karten (Gebäudepläne) sind an ausgewählten Standorten verfügbar. Wenn für ein Gebäude, das du in deiner App hervorheben möchtest, keine Gebäudeplandaten verfügbar sind, hast du folgende Möglichkeiten:

Verkehrsebene

Du kannst den Nutzern die Möglichkeit geben, eine Karte mit darüber gelagerten Informationen zur Verkehrsdichte zu sehen. Das ist eine visuelle Zusammenfassung der lokalen Verkehrssituation. Du kannst die Verkehrsebene aktivieren und deaktivieren, indem du die setTrafficEnabled()-Methode aufrufst. Mit der Methode isTrafficEnabled() lässt sich feststellen, ob die Verkehrsebene derzeit aktiviert ist. Das folgende Beispiel zeigt, wie die Verkehrsebene auf einer Karte aussehen könnte.

Eine Google-Karte mit der Verkehrsebene

Anfangszustand konfigurieren

Mithilfe der Google Maps API kannst du den Anfangszustand der Karte an die Anforderungen deiner App anpassen. Du kannst Folgendes festlegen:

  • Die Kameraposition, einschließlich Position, Zoomfaktor, Ausrichtung und Neigung. Weitere Informationen zur Positionierung der Kamera und den Kameraeigenschaften findest du unter Kamera und Ansicht.
  • Der Kartentyp
  • Ob die Zoomschaltflächen und/oder der Kompass auf dem Bildschirm angezeigt werden
  • Mit welchen Touch-Gesten Nutzer die Kamera ändern können
  • Ob der Lite-Modus aktiviert ist oder nicht Eine Karte im Lite-Modus ist ein Bitmapbild einer Karte, die eine Teilmenge der Funktionen unterstützt, die von der vollständigen API bereitgestellt werden.

Du kannst den Anfangszustand der Karte entweder programmatisch konfigurieren oder über XML, wenn du die Karte der Layoutdatei deiner Aktivität hinzugefügt hast.

XML-Attribute verwenden

In diesem Abschnitt wird beschrieben, wie der Anfangszustand der Karte festgelegt wird, wenn du eine Karte mithilfe einer XML-Layoutdatei deiner App hinzugefügt hast.

In der Google Maps API ist eine Gruppe benutzerdefinierter XML-Attribute für MapFragment oder MapView definiert, mit denen du den Anfangszustand der Karte direkt über die Layoutdatei konfigurieren kannst. Folgende Attribute sind derzeit definiert:

  • mapType. Mit diesem Attribut kannst du den Typ der anzuzeigenden Karte definieren. Zulässige Werte: none, normal, hybrid, satellite und terrain
  • cameraTargetLat, cameraTargetLng, cameraZoom, cameraBearing, cameraTilt. Mit diesen Attributen kannst du die Anfangsposition der Kamera definieren. Weitere Details zur Position der Kamera und ihren Eigenschaften
  • uiZoomControls, uiCompass. Damit kannst du angeben, ob die Zoomsteuerelemente und der Kompass auf der Karte angezeigt werden sollen. Unter UiSettings findest du weitere Details.
  • uiZoomGestures, uiScrollGestures, uiRotateGestures, uiTiltGestures. Damit kannst du angeben, welche Touch-Gesten für die Interaktion mit der Karte aktiviert bzw. deaktiviert sind. Unter UiSettings findest du weitere Details.
  • zOrderOnTop. Damit kannst du festlegen, ob die Oberfläche der Kartenansicht über dem Kartenfenster platziert wird. Weitere Details findest du unter SurfaceView.setZOrderOnTop(boolean). Dadurch werden alle anderen Ansichten verdeckt, die auf der Karte vorhanden sein könnten, z. B. die Zoomsteuerelemente und die Schaltfläche "Mein Standort".
  • useViewLifecycle. Nur gültig mit MapFragment. Dieses Attribut gibt an, ob der Lebenszyklus der Karte an die Ansicht des Fragments oder an das Fragment selbst gebunden sein soll. Weitere Informationen
  • liteMode. Mit dem Wert true wird die Karte auf den Lite-Modus festgelegt. Eine Karte im Lite-Modus ist ein Bitmapbild einer Karte, die eine Teilmenge der Funktionen unterstützt, die von der vollständigen API bereitgestellt werden. Der Standardwert dieses Attributs ist false.

Um diese benutzerdefinierten Attribute innerhalb deiner XML-Layoutdatei verwenden zu können, musst du zuerst die folgende Namespace-Deklaration hinzufügen. Du kannst einen beliebigen Namensraum auswählen. Es muss nicht map sein:

xmlns:map="http://schemas.android.com/apk/res-auto"

Anschließend kannst du die Attribute mit dem Präfix map: deinen Layout-Komponenten hinzufügen, so wie du es auch bei standardmäßigen Android-Attributen machst.

Das folgende XML-Code-Snippet zeigt, wie ein MapFragment-Element mit einigen benutzerdefinierten Optionen konfiguriert wird (dieselben Attribute können auch auf ein MapView-Element angewendet werden).

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:map="http://schemas.android.com/apk/res-auto"
  android:name="com.google.android.gms.maps.SupportMapFragment"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  map:cameraBearing="112.5"
  map:cameraTargetLat="-33.796923"
  map:cameraTargetLng="150.922433"
  map:cameraTilt="30"
  map:cameraZoom="13"
  map:mapType="normal"
  map:uiCompass="false"
  map:uiRotateGestures="true"
  map:uiScrollGestures="false"
  map:uiTiltGestures="true"
  map:uiZoomControls="false"
  map:uiZoomGestures="true"/>

Programmatisch

In diesem Abschnitt wird beschrieben, wie der Anfangszustand der Karte festgelegt wird, wenn du eine Karte programmatisch deiner App hinzugefügt hast.

Wenn du programmatisch ein MapFragment oder MapView hinzugefügt hast, kannst du den Anfangszustand konfigurieren, indem du ein GoogleMapOptions-Objekt mit den angegebenen Optionen übergibst. Die verfügbaren Optionen sind genau dieselben wie beim Hinzufügen per XML. So kannst du ein GoogleMapOptions-Objekt erstellen:

GoogleMapOptions options = new GoogleMapOptions();

Anschließend konfigurierst du das Objekt so:

options.mapType(GoogleMap.MAP_TYPE_SATELLITE)
    .compassEnabled(false)
    .rotateGesturesEnabled(false)
    .tiltGesturesEnabled(false);

Um diese Optionen beim Erstellen einer Karte anzuwenden, führst du einen der folgenden Schritte aus:

Karte mit Innenrand versehen

In diesem Video siehst du ein Beispiel für das Hinzufügen eines Karteninnenrands.

Eine Google-Karte füllt standardmäßig den gesamten Bereich aus, der von ihrem Containerelement, in der Regel MapView oder MapFragment, definiert wird. Verschiedene Aspekte der Darstellung und Funktionsweise der Karte werden durch die Abmessungen des Kartencontainers definiert:

  • Das Ziel der Kamera entspricht der Mitte des abgesetzten Bereichs.
  • Kartensteuerelemente werden relativ zu den Rändern der Karte positioniert.
  • Rechtliche Informationen wie Urheberrechtsangaben oder das Google-Logo werden am unteren Rand der Karte angezeigt.

Du kannst mithilfe von GoogleMap an der Kartenaußenseite einen Innenrand hinzufügen.setPadding()-Methode. Die Karte füllt weiterhin den gesamten Container aus, aber die Positionierung von Text und Steuerelementen, Touch-Gesten für die Kartensteuerung und Kamerabewegung verhalten sich so, als wenn die Karte in einem kleineren Bereich platziert worden wäre. Das führt zu folgenden Änderungen:

  • Kamerabewegungen über API-Aufrufe oder die Betätigung von Schaltflächen (z. B. der Kompassschaltfläche, der Schaltfläche "Mein Standort" oder der Zoomschaltflächen) erfolgen relativ zum abgesetzten Bereich.
  • getCameraPosition() gibt die Mitte des abgesetzten Bereichs zurück.
  • Projection.getVisibleRegion() gibt den abgesetzten Bereich zurück.
  • UI-Steuerelemente werden um die angegebene Anzahl von Pixeln vom Rand des Containers entfernt platziert.

Ein Innenrand kann beim Entwerfen von UI-Elementen hilfreich sein, die sich mit einem Teil der Karte überschneiden. Auf dem Bild unten wurden zum Beispiel Innenränder entlang des oberen und rechten Rands der Karte festgelegt. Sichtbare Kartensteuerelemente und rechtliche Informationen werden entlang der Ränder des abgesetzten Bereichs (grün) angezeigt. Die Karte füllt aber weiterhin den gesamten Container (blau) aus. In diesem Beispiel kannst du rechts auf der Karte ein Menü einblenden, ohne die Kartensteuerelemente zu verdecken.

Karte mit Innenrand versehen

Karte lokalisieren

Wenn du deiner App MapView oder MapFragment hinzufügst, werden Textelemente auf der Karte in der Sprache angezeigt, die den Einstellungen und dem Standort des Nutzergeräts entsprechen. Du kannst die in deiner App verfügbaren Sprachen auf eine Teilmenge aller unterstützten Sprachen beschränken, indem du deiner Gradle-Datei ein resConfigs-Element hinzufügst. Das ist nützlich, um nicht verwendete Sprachen zu entfernen und die Binärgröße der App zu reduzieren. Beispiel:

defaultConfig {
    resConfigs "en", "fr", "es", "zh", "de", "ja", "ru", "ko", "pt", "in"
}

Weitere Informationen zur Lokalisierung deiner Android-App