Maps API unter Wear OS

Eine Karte auf einem Wearable-Gerät

Mit dem Maps SDK for Android können Sie eine kartenbasierte Wearable-App erstellen, die direkt auf Wear OS by Google-Geräten läuft. So können Nutzer Ihrer App den eigenen Standort auf der Karte schon mit einem einfachen Blick auf ihr Handgelenk sehen. Nutzer können beispielsweise die eigene Position auf einer Route verfolgen und dann durch Vergrößern der Ansicht Details anzeigen oder durch Tippen auf eine Markierung ein Infofenster Ihrer App aufrufen.

Auf dieser Seite werden die API-Funktionen, die auf Wear-Geräten verfügbar sind, und die ersten Schritte zum Erstellen Ihrer App beschrieben.

Erste Schritte mit Wear OS

Das Erstellen einer Wearable-App mit dem Maps SDK for Android funktioniert im Wesentlichen genauso wie das Erstellen einer Google Maps-App für andere Android-Geräte. Allerdings muss der kleinere Formfaktor des Wearable-Geräts berücksichtigt werden, damit die App dort optimal läuft und bestmöglich genutzt werden kann.

Wir empfehlen Android Studio als Entwicklungsumgebung für Wear OS, weil es die Projektkonfiguration, die Einbindung von Bibliotheken und die Paketerstellung vereinfacht.

Allgemeine Hilfestellungen zum Entwickeln einer Wearable-App finden Sie in den Designrichtlinien für Wear OS. Informationen zum Erstellen Ihrer ersten Wearable-App finden Sie in der Anleitung zum Erstellen von Wearable-Apps.

Erste Karten-App für Wear OS erstellen

In dieser Kurzanleitung wird vorausgesetzt, dass Sie mit dem Maps SDK for Android vertraut sind, die Wear OS-Anleitungen zum Erstellen eines Wearable-Moduls in Ihrer App befolgt haben und nun dem Wearable-Modul eine Karte hinzufügen möchten.

Abhängigkeiten für Ihr Wearable-Modul hinzufügen

Folgende Abhängigkeiten müssen in der build.gradle.kts-Datei des Wear OS-Moduls Ihrer App enthalten sein:

dependencies {
    // ...
    compileOnly("com.google.android.wearable:wearable:2.9.0")
    implementation("com.google.android.support:wearable:2.9.0")
    implementation("com.google.android.gms:play-services-maps:19.0.0")

    // This dependency is necessary for ambient mode
    implementation("androidx.wear:wear:1.3.0")
}

Weitere Informationen zu den Abhängigkeiten finden Sie in der Anleitung zum Hinzufügen eines Wear OS-Moduls zu einem Projekt.

Wischgeste zum Schließen implementieren und anfängliche Hintergrundfarbe festlegen

Es empfiehlt sich, ein SwipeDismissFrameLayout-Element zu verwenden, um die Karte auf dem Wearable-Gerät darzustellen. Mit der Klasse SwipeDismissFrameLayout können Sie die Wischgeste zum Schließen implementieren, damit Nutzer die App verlassen können, indem sie vom linken Bildschirmrand nach rechts wischen.

Eine benutzerdefinierte anfängliche Hintergrundfarbe lässt sich über das XML-Attribut map:backgroundColor festlegen. Damit bestimmen Sie die Farbe, die zu sehen ist, bis die tatsächlichen Kartenkacheln geladen werden.

Fügen Sie Ihrer Layoutdefinition die Elemente SwipeDismissFrameLayout und backgroundColor als Container von SupportMapFragment hinzu:

  <androidx.wear.widget.SwipeDismissFrameLayout
      android:id="@+id/map_container"
      android:layout_width="match_parent"
      android:layout_height="match_parent">
    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        map:backgroundColor="#fff0b2dd" />
  </androidx.wear.widget.SwipeDismissFrameLayout>

Wenn Sie das SwipeDismissFrameLayout-Objekt in Ihre Aktivität einbinden, fügen Sie einen Callback hinzu und legen Sie sein Verhalten so fest, dass die erforderliche Aktion zum Schließen wie unten gezeigt ausgeführt wird:

Kotlin

class MainActivity : AppCompatActivity(), OnMapReadyCallback,
                     AmbientModeSupport.AmbientCallbackProvider {


    public override fun onCreate(savedState: Bundle?) {
        super.onCreate(savedState)

        // Set the layout. It only contains a SupportMapFragment and a DismissOverlay.
        setContentView(R.layout.activity_main)

        // Enable ambient support, so the map remains visible in simplified, low-color display
        // when the user is no longer actively using the app but the app is still visible on the
        // watch face.
        val controller = AmbientModeSupport.attach(this)
        Log.d(MainActivity::class.java.simpleName, "Is ambient enabled: " + controller.isAmbient)

        // Retrieve the containers for the root of the layout and the map. Margins will need to be
        // set on them to account for the system window insets.
        val mapFrameLayout = findViewById<SwipeDismissFrameLayout>(R.id.map_container)
        mapFrameLayout.addCallback(object : SwipeDismissFrameLayout.Callback() {
            override fun onDismissed(layout: SwipeDismissFrameLayout) {
                onBackPressed()
            }
        })

        // Obtain the MapFragment and set the async listener to be notified when the map is ready.
        mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)
    }

    // ...
}

      

Java

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback,
    AmbientModeSupport.AmbientCallbackProvider {


    public void onCreate(Bundle savedState) {
        super.onCreate(savedState);

        // Set the layout. It only contains a SupportMapFragment and a DismissOverlay.
        setContentView(R.layout.activity_main);

        // Enable ambient support, so the map remains visible in simplified, low-color display
        // when the user is no longer actively using the app but the app is still visible on the
        // watch face.
        AmbientModeSupport.AmbientController controller = AmbientModeSupport.attach(this);
        Log.d(MainActivity.class.getSimpleName(), "Is ambient enabled: " + controller.isAmbient());

        // Retrieve the containers for the root of the layout and the map. Margins will need to be
        // set on them to account for the system window insets.
        final SwipeDismissFrameLayout mapFrameLayout = (SwipeDismissFrameLayout) findViewById(
            R.id.map_container);
        mapFrameLayout.addCallback(new SwipeDismissFrameLayout.Callback() {
            @Override
            public void onDismissed(SwipeDismissFrameLayout layout) {
                onBackPressed();
            }
        });

        // Obtain the MapFragment and set the async listener to be notified when the map is ready.
        mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    // ...
}

      

Karte hinzufügen

Verwenden Sie wie gewohnt die Callback-Methode onMapReady(GoogleMap), um ein Handle zum GoogleMap-Objekt zu erhalten. Der Callback wird ausgelöst, sobald die Karte einsatzbereit ist. In der Callback-Methode können Sie der Karte Markierungen oder Polylinien hinzufügen, Listener ergänzen oder die Kamera verschieben. Im folgenden Beispiel wird eine Markierung in der Nähe des Opernhauses Sydney hinzugefügt:

Kotlin

private val sydney = LatLng(-33.85704, 151.21522)

override fun onMapReady(googleMap: GoogleMap) {
    // Add a marker with a title that is shown in its info window.
    googleMap.addMarker(
        MarkerOptions().position(sydney)
            .title("Sydney Opera House")
    )

    // Move the camera to show the marker.
    googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 10f))
}

      

Java

private static final LatLng SYDNEY = new LatLng(-33.85704, 151.21522);

@Override
public void onMapReady(@NonNull GoogleMap googleMap) {
    // Add a marker with a title that is shown in its info window.
    googleMap.addMarker(new MarkerOptions().position(SYDNEY)
        .title("Sydney Opera House"));

    // Move the camera to show the marker.
    googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(SYDNEY, 10));
}

      

Inaktivmodus aktivieren

Das Maps SDK for Android unterstützt den Inaktivmodus für Wearable-Apps. Apps, die den Inaktivmodus unterstützen, werden auch als Always-On-Apps bezeichnet. Der Inaktivmodus wird aktiviert, wenn der Nutzer die App nicht mehr aktiv verwendet, und sorgt dafür, dass die App weiter auf dem Wearable-Gerät angezeigt wird.

Das Maps SDK for Android ermöglicht ein vereinfachtes Rendern der Karte mit geringer Farbtiefe für die Verwendung im Inaktivmodus, und das Kartenformat wird automatisch angepasst, wenn das Gerät vom interaktiven Modus in den Inaktivmodus wechselt. Alle Markierungen, Objekte und UI-Steuerelemente werden im Inaktivmodus ausgeblendet. Das reduziert den Stromverbrauch Ihrer App und sorgt gleichzeitig für ein einheitliches Erscheinungsbild im Vergleich mit anderen Apps mit Inaktivitätsdisplay, z. B. Zifferblättern.

So können Sie bewirken, dass Ihre App den Inaktivmodus der Karte verwendet:

  1. Aktualisieren Sie Ihr Android SDK so, dass dabei die Plattform Android 6.0 (API-Level 23) oder höher eingebunden wird, die die nötigen APIs zum Aufrufen des Inaktivmodus umfasst. Informationen zum Aktualisieren des SDK finden Sie in der Android-Dokumentation zum Hinzufügen von SDK-Paketen.
  2. Ihr Projekt muss für Android 6.0 oder höher ausgelegt sein. Setzen Sie targetSdkVersion dazu im App-Manifest auf 23 oder höher.
  3. Fügen Sie der Datei build.gradle.kts Ihrer App die Wearable-Abhängigkeiten hinzu. Ein Beispiel dafür finden Sie auf dieser Seite.
  4. Fügen Sie den Eintrag der freigegebenen Wearable-Bibliothek dem App-Manifest hinzu, wie im Android-Schulungskurs zum Thema Sicherstellen der Sichtbarkeit der App beschrieben.
  5. Fügen Sie dem Handheld- und Wearable-App-Manifest die Berechtigung WAKE_LOCK hinzu, wie im Android-Schulungskurs zum Thema Sicherstellen der Sichtbarkeit der App beschrieben.
  6. Rufen Sie in der Methode onCreate() Ihrer Aktivität die Methode AmbientModeSupport.attach() auf. Dadurch erhält das Betriebssystem die Information, dass die App immer aktiviert ist. Wenn das Gerät also in den Energiesparmodus übergeht, sollte die App in den Inaktivmodus wechseln und nicht das Zifferblatt auf dem Gerät angezeigt werden.
  7. Implementieren Sie die Schnittstelle AmbientModeSupport.AmbientCallbackProvider in Ihrer Aktivität, damit sie im Inaktivmodus Statusänderungen empfangen kann.
  8. Konfigurieren Sie Ihre Karte so, dass sie den Inaktivmodus unterstützt. Dazu können Sie das Attribut map:ambientEnabled="true" in der XML-Layoutdatei der Aktivität definieren oder es programmatisch einrichten, indem Sie GoogleMapOptions.ambientEnabled(true) angeben. So weiß die API, dass die erforderlichen Kartenkacheln für die Verwendung im Inaktivmodus vorab geladen werden müssen.
  9. Wenn die Aktivität in den Inaktivmodus wechselt, ruft das System die Methode onEnterAmbient() in Ihrem AmbientCallback auf. Überschreiben Sie onEnterAmbient() und rufen Sie SupportMapFragment.onEnterAmbient(ambientDetails) oder MapView.onEnterAmbient(ambientDetails) auf. Die API wechselt dann zum nicht interaktiven Rendern mit geringer Farbtiefe.
  10. Rufen Sie in onExitAmbient() entsprechend SupportMapFragment.onExitAmbient() oder MapView.onExitAmbient() auf. Die API wechselt zum normalen Rendering der Karte.

Mit dem folgenden Codebeispiel wird der Inaktivmodus in der Aktivität aktiviert:

Kotlin

class AmbientActivity : AppCompatActivity(), AmbientModeSupport.AmbientCallbackProvider {

    private lateinit var mapFragment: SupportMapFragment

    public override fun onCreate(savedState: Bundle?) {
        super.onCreate(savedState)

        // Set the layout. It only contains a SupportMapFragment and a DismissOverlay.
        setContentView(R.layout.activity_main)

        // Enable ambient support, so the map remains visible in simplified, low-color display
        // when the user is no longer actively using the app but the app is still visible on the
        // watch face.
        val controller = AmbientModeSupport.attach(this)
        Log.d(AmbientActivity::class.java.simpleName, "Is ambient enabled: " + controller.isAmbient)

        // Obtain the MapFragment and set the async listener to be notified when the map is ready.
        mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as SupportMapFragment
    }

    override fun getAmbientCallback(): AmbientModeSupport.AmbientCallback {
        return object : AmbientModeSupport.AmbientCallback() {
            /**
             * Starts ambient mode on the map.
             * The API swaps to a non-interactive and low-color rendering of the map when the user is no
             * longer actively using the app.
             */
            override fun onEnterAmbient(ambientDetails: Bundle) {
                super.onEnterAmbient(ambientDetails)
                mapFragment.onEnterAmbient(ambientDetails)
            }

            /**
             * Exits ambient mode on the map.
             * The API swaps to the normal rendering of the map when the user starts actively using the app.
             */
            override fun onExitAmbient() {
                super.onExitAmbient()
                mapFragment.onExitAmbient()
            }
        }
    }
}

      

Java

public class AmbientActivity extends AppCompatActivity implements
    AmbientModeSupport.AmbientCallbackProvider {

    private SupportMapFragment mapFragment;

    public void onCreate(Bundle savedState) {
        super.onCreate(savedState);

        // Set the layout. It only contains a SupportMapFragment and a DismissOverlay.
        setContentView(R.layout.activity_main);

        // Enable ambient support, so the map remains visible in simplified, low-color display
        // when the user is no longer actively using the app but the app is still visible on the
        // watch face.
        AmbientModeSupport.AmbientController controller = AmbientModeSupport.attach(this);
        Log.d(AmbientActivity.class.getSimpleName(), "Is ambient enabled: " + controller.isAmbient());

        // Obtain the MapFragment and set the async listener to be notified when the map is ready.
        mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    }

    @Override
    public AmbientCallback getAmbientCallback() {
        return new AmbientCallback() {
            /**
             * Starts ambient mode on the map.
             * The API swaps to a non-interactive and low-color rendering of the map when the user is no
             * longer actively using the app.
             */
            @Override
            public void onEnterAmbient(Bundle ambientDetails) {
                super.onEnterAmbient(ambientDetails);
                mapFragment.onEnterAmbient(ambientDetails);
            }

            /**
             * Exits ambient mode on the map.
             * The API swaps to the normal rendering of the map when the user starts actively using the app.
             */
            @Override
            public void onExitAmbient() {
                super.onExitAmbient();
                mapFragment.onExitAmbient();
            }
        };
    }
}

      

Sie können festlegen, dass der Bildschirm aktualisiert wird, während die App im Inaktivmodus ausgeführt wird. Weitere Informationen zum Aktualisieren von Inhalten und zum Inaktivmodus im Allgemeinen finden Sie im Android-Schulungskurs zum Sicherstellen der Sichtbarkeit der App.

Street View unter Wear OS verwenden

Street View wird auf Wearable-Geräten vollständig unterstützt.

Um den Nutzern die Möglichkeit zu geben, die App während der Anzeige eines Street View-Panoramas zu beenden, verwenden Sie die Schnittstelle StreetViewPanorama.OnStreetViewPanoramaLongClickListener, die auf eine lange Klick-/Tippbewegung reagiert. Wenn ein Nutzer lange auf eine beliebige Stelle des Street View-Bilds klickt/tippt, wird ein onStreetViewPanoramaLongClick(StreetViewPanoramaOrientation)-Ereignis empfangen. Rufen Sie DismissOverlayView.show() auf, um eine Schaltfläche zum Beenden anzuzeigen.

Beispielcode

Auf GitHub ist eine Beispiel-App verfügbar, die Sie als Ausgangspunkt zum Erstellen einer App verwenden können. Daraus geht hervor, wie Sie eine einfache Google Maps-Karte unter Wear OS konfigurieren.

Unterstützte Funktionen in der Maps API unter Wear OS

In diesem Abschnitt wird beschrieben, wie sich die unterstützten Funktionen für Karten auf Wearable-Geräten einerseits und auf Handheld-Geräten (Smartphones und Tablets) andererseits unterscheiden. Alle API-Funktionen, die nachfolgend nicht aufgeführt sind, sollten wie dokumentiert für die gesamte API funktionieren.

Funktionen
Vollständig interaktiver Modus und Lite-Modus

Sie können das Maps SDK for Android im vollständig interaktiven Modus oder im Lite-Modus verwenden. Der Lite-Modus empfiehlt sich, wenn Sie die Performance des Wearable-Geräts optimieren möchten und für Ihre App Interaktionen wie Gesten oder das Schwenken/Zoomen von Karten nicht unterstützt werden müssen.

Im Lite-Modus ist der Intent zum Starten der mobilen Google Maps App, wenn der Nutzer auf die Karte tippt, deaktiviert. Er kann auf einem Wearable-Gerät auch nicht aktiviert werden.

Eine vollständige Liste der Unterschiede zwischen dem Lite-Modus und dem interaktiven Modus finden Sie in der Dokumentation zum Lite-Modus.

Kartensymbolleiste Die Kartensymbolleiste ist deaktiviert und kann auf einem Wearable-Gerät nicht aktiviert werden.
UI-Steuerelemente Die UI-Steuerelemente sind auf Wearable-Geräten standardmäßig deaktiviert. Das gilt für die Steuerelemente für das Zoomen, den Kompass und den eigenen Standort. Um diese zu aktivieren, verwenden Sie wie gewohnt die UiSettings-Klasse.
Gesten Einfache Touch-Gesten können wie gewohnt verwendet werden. Beispiele: Berühren und Ziehen zum Schwenken der Karte, Doppeltippen zum Heranzoomen und Zweifingertippen zum Herauszoomen. Welche Multi-Touch-Gesten unterstützt werden, ist vom jeweiligen Gerät des Nutzers abhängig. Zu den Multi-Touch-Gesten gehören Zweifingerschieben zum Neigen der Karte, Auseinander- und Zusammenziehen zum Heran- und Herauszoomen und Drehen mit zwei Fingern.
Indoor-Karten und Gebäude Indoor-Karten sind auf Wearable-Geräten standardmäßig deaktiviert. Sie können sie aktivieren, indem Sie GoogleMap.setIndoorEnabled(true) aufrufen. Sind Indoor-Karten aktiviert, wird in der Karte die Standardebene (Etage) angezeigt. Das UI-Element zur Auswahl der Ebene (Etage) wird auf Wearable-Geräten nicht unterstützt.
Kachel-Overlays Kachel-Overlays werden auf Wearable-Geräten nicht unterstützt.

Best Practices für das Entwickeln mit der Maps API unter Wear OS

So erreichen Sie die bestmögliche Nutzerfreundlichkeit Ihrer App:

  • Die Karte sollte einen großen Teil des Bildschirms einnehmen. Damit wird die Nutzerfreundlichkeit der Karte auf den kleinen Formfaktor eines Wearable-Geräts hin optimiert.
  • Berücksichtigen Sie bei der Gestaltung Ihrer App, dass ein Wearable-Gerät nur eine niedrige Akkuleistung hat. Ein durchgängig aktiver Bildschirm und eine permanente Anzeige der Karte beeinträchtigen die Akkuleistung.