Interfejs API Map Google na Wear OS

Mapa na urządzeniu do noszenia

Za pomocą pakietu Maps SDK na Androida możesz utworzyć opartą na mapie aplikację do noszenia, która będzie działać bezpośrednio na urządzeniach z Wear OS by Google. Użytkownicy aplikacji mogą zobaczyć swoją lokalizację na mapie, patrząc na nadgarstki. Mogą na przykład wyznaczyć swoją pozycję na trasie i powiększyć widok, by zobaczyć szczegóły, lub kliknąć znacznik, by wyświetlić okno informacyjne dostarczone przez aplikację.

Na tej stronie opisujemy funkcje interfejsu API dostępne na urządzeniach do Wear. Pomogą Ci one rozpocząć tworzenie aplikacji.

Pierwsze kroki na Wear OS

Tworzenie aplikacji do noszenia za pomocą pakietu Maps SDK na Androida jest zasadniczo takie samo jak tworzenie aplikacji Mapy Google na dowolne inne urządzenie z Androidem. Różnica polega na tym, że rozmiar urządzenia do noszenia jest mniejszy, co optymalizuje łatwość obsługi i wydajność aplikacji.

Narzędzie Android Studio jest zalecanym narzędziem do programowania na Wear OS, ponieważ zapewnia konfigurację projektu, dodanie biblioteki i udogodnienia podczas pakietów.

Ogólną pomoc w projektowaniu aplikacji do noszenia znajdziesz w wytycznych dotyczących projektowania aplikacji na Wear OS. Aby uzyskać pomoc przy tworzeniu pierwszej aplikacji do noszenia, zapoznaj się z przewodnikiem Tworzenie takich aplikacji.

Tworzenie pierwszej aplikacji z mapami na Wear OS

W tym krótkim przewodniku przyjęto założenie, że znasz pakiet Maps SDK na Androida oraz że postępujesz zgodnie z instrukcjami dotyczącymi Wear OS, aby utworzyć moduł do noszenia w swojej aplikacji, i chcesz dodać do niego mapę.

Dodaję zależności modułu Wear

Upewnij się, że plik build.gradle modułu Wear OS aplikacji zawiera te zależności:

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:18.2.0'

    // This dependency is necessary for ambient mode
    implementation 'androidx.wear:wear:1.3.0'
}

Więcej informacji o zależnościach znajdziesz w artykule Dodawanie modułu Wear OS do istniejącego projektu.

Wdrażanie gestu przesuwania w celu zamknięcia i ustawienie początkowego koloru tła

Do wyświetlania mapy na urządzeniu do noszenia zalecamy użycie SwipeDismissFrameLayout. Za pomocą klasy SwipeDismissFrameLayout możesz zaimplementować gest przesuń, aby ukryć, który umożliwia użytkownikom wyjście z aplikacji przez przesunięcie palcem od lewej krawędzi ekranu.

Aby ustawić niestandardowy początkowy kolor tła, użyj atrybutu XML map:backgroundColor do określenia koloru wyświetlanego do momentu wczytania rzeczywistego fragmentu mapy.

Dodaj elementy SwipeDismissFrameLayout i backgroundColor do definicji układu jako kontener elementu SupportMapFragment:

  <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>

Gdy uzyskasz w aktywności obiekt SwipeDismissFrameLayout, dodaj wywołanie zwrotne i skonfiguruj działanie wywołania zwrotnego w celu wykonania niezbędnej operacji odrzucenia, jak pokazano poniżej:

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);
    }

    // ...
}

      

Dodawanie mapy

Aby uzyskać uchwyt do obiektu GoogleMap, użyj jak zwykle metody wywołania zwrotnego onMapReady(GoogleMap). Wywołanie zwrotne jest wywoływane, gdy mapa jest gotowa do użycia. W metodzie wywołania zwrotnego można dodać do mapy znaczniki lub linie łamane, dodać detektory i przesunąć kamerę. Poniższy przykład zawiera znacznik wyboru w pobliżu Opery w Sydney:

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));
}

      

Włączam dźwięki otoczenia

Pakiet Maps SDK na Androida obsługuje tryb nieaktywny w aplikacjach do noszenia. Aplikacje obsługujące dźwięki otoczenia są czasami nazywane aplikacjami zawsze włączonymi. Tryb nieaktywny włącza się, gdy użytkownik nie korzysta już z aplikacji, i umożliwia pozostawienie aplikacji widocznej na urządzeniu do noszenia.

Maps SDK na Androida upraszcza renderowanie mapy w niskiej jakości, co pozwala jej używać w trybie nieaktywnym. Styl mapy dostosowuje się automatycznie, gdy urządzenie przechodzi z trybu interaktywnego w tryb nieaktywny. Wszystkie znaczniki, obiekty i elementy sterujące UI znikają w trybie nieaktywnym. Zmniejsza to zużycie energii przez aplikację i zapewnia spójny wygląd i styl z innymi aplikacjami z powiadomieniami, takimi jak tarcze zegarka.

Aby aplikacja używała trybu nieaktywnego mapy, wykonaj te czynności:

  1. Zaktualizuj pakiet Android SDK, dodając platformę Android 6.0 (API 23) lub nowszą, która udostępnia interfejsy API umożliwiające przejście działań w tryb nieaktywny. Informacje o tym, jak zaktualizować pakiet SDK, znajdziesz w dokumentacji Androida dotyczącej dodawania pakietów SDK.
  2. Upewnij się, że Twój projekt jest kierowany na Androida 6.0 lub nowszego, ustawiając targetSdkVersion w manifeście aplikacji na 23 lub nowszą.
  3. Dodaj zależności urządzenia do noszenia do pliku build.gradle aplikacji. Zobacz przykład na tej stronie.
  4. Dodaj wpis biblioteki współdzielonej urządzenia do noszenia do pliku manifestu aplikacji zgodnie z opisem w klasie trenowania Androida dotyczącej utrzymywania widoczności aplikacji.
  5. Dodaj uprawnienie WAKE_LOCK do plików manifestu aplikacji na urządzenia przenośne i urządzenia do noszenia zgodnie z opisem w klasie trenowania Androida na temat utrzymywania widoczności aplikacji.
  6. W metodzie onCreate() aktywności wywołaj metodę AmbientModeSupport.attach(). Informuje to system operacyjny, że aplikacja jest zawsze włączona, więc po wyłączeniu urządzenia powinien przejść w tryb nieaktywny, a nie wracać do tarczy zegarka.
  7. Zaimplementuj w Aktywności interfejs AmbientModeSupport.AmbientCallbackProvider, aby odbierał zmiany stanu otoczenia.
  8. Skonfiguruj mapę tak, aby obsługiwała dźwięki otoczenia. Możesz to zrobić, ustawiając atrybut map:ambientEnabled="true" w pliku układu XML aktywności lub automatycznie przez ustawienie GoogleMapOptions.ambientEnabled(true). To ustawienie informuje interfejs API, że musi wstępnie wczytywać niezbędne kafelki mapy do użycia w trybie nieaktywnym.
  9. Gdy aktywność przełączy się w tryb nieaktywny, system wywoła metodę onEnterAmbient() w podanym przez Ciebie AmbientCallback. Zastąp onEnterAmbient() i wywołaj SupportMapFragment.onEnterAmbient(ambientDetails) lub MapView.onEnterAmbient(ambientDetails). Interfejs API przełącza się na nieinteraktywne renderowanie mapy w niskim kolorze.
  10. Podobnie w onExitAmbient() wywołaniu SupportMapFragment.onExitAmbient() lub MapView.onExitAmbient(). Interfejs API przełączy się na normalne renderowanie mapy.

Ten przykładowy kod włącza tryb nieaktywny w aktywności:

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();
            }
        };
    }
}

      

Możesz zaktualizować ekran, gdy aplikacja jest w trybie nieaktywnym. Więcej informacji o aktualizowaniu treści oraz o trybie nieaktywnym znajdziesz na lekcji szkoleniowej dotyczącej Androida poświęconej utrzymywaniu widoczności aplikacji.

Korzystanie ze Street View na Wear OS

Street View jest w pełni obsługiwane na urządzeniach do noszenia.

Aby umożliwić użytkownikom wychodzenie z aplikacji podczas oglądania panoramy Street View, użyj interfejsu StreetViewPanorama.OnStreetViewPanoramaLongClickListener, aby nasłuchiwać gestu przytrzymania. Gdy użytkownik kliknie długo na zdjęciu Street View, otrzymasz zdarzenie onStreetViewPanoramaLongClick(StreetViewPanoramaOrientation). Wywołaj DismissOverlayView.show(), aby wyświetlić przycisk wyjścia.

Przykładowy kod

Przykładowa aplikacja jest dostępna w GitHub i możesz ją wykorzystać jako punkt wyjścia dla swojej aplikacji. Pokazuje on, jak skonfigurować podstawową mapę Google na Wear OS.

Obsługiwane funkcje interfejsu API Map Google na Wear OS

W tej sekcji opisujemy różnice pod względem obsługi map na urządzeniach do noszenia w porównaniu z urządzeniami mobilnymi (telefonami i tabletami). Wszystkie funkcje interfejsu API, które nie zostały wymienione poniżej, powinny działać zgodnie z opisem dla pełnego interfejsu API.

Funkcjonalność
Tryb w pełni interaktywny i wersja uproszczona

Z pakietu SDK Maps na Androida możesz korzystać w trybie w pełni interaktywnym lub w trybie uproszczonym. Wybierz tryb uproszczony, jeśli chcesz zoptymalizować wydajność na urządzeniu do noszenia, a aplikacja nie musi obsługiwać interakcji takich jak gesty czy przesuwanie i powiększanie mapy.

W trybie uproszczonym intencja uruchamiania aplikacji mobilnej Mapy Google po kliknięciu mapy przez użytkownika jest wyłączona i nie można jej włączyć na urządzeniu do noszenia.

Pełną listę różnic między trybem uproszczonym a w pełni interaktywnym znajdziesz w dokumentacji wersji uproszczonej.

Pasek narzędzi mapy Pasek narzędzi mapy jest wyłączony i nie można go włączyć na urządzeniu do noszenia.
Elementy sterujące interfejsu Elementy sterujące interfejsu są domyślnie wyłączone na urządzeniach do noszenia. Dotyczy to również powiększenia, kompasu i lokalizacji. Możesz je włączyć w zwykły sposób za pomocą klasy UiSettings.
Gesty Gesty z pojedynczym dotknięciem działają zgodnie z oczekiwaniami. Przykładem może być kliknięcie i przeciągnięcie mapy, by ją przesunąć, dwukrotne kliknięcie, by ją powiększyć, lub dwukrotne kliknięcie, by pomniejszyć. Obsługa gestów wielodotykowych różni się w zależności od urządzenia użytkownika. Przykłady gestów wielodotykowych to naciśnięcie 2 palcami, aby przechylić mapę, ściągnięcie palcami, aby powiększyć, i obrót 2 palcami.
Mapy obiektów i budynki Mapy wnętrz są domyślnie wyłączone na urządzeniach do noszenia. Aby je włączyć, wywołaj GoogleMap.setIndoorEnabled(true). Jeśli włączone są mapy obiektów, na mapie wyświetli się domyślny poziom piętra. Element interfejsu selektora poziomu nie jest obsługiwany na urządzeniach do noszenia.
Nakładki z kafelkami Nakładki z kafelkami nie są obsługiwane na urządzeniach do noszenia.

Sprawdzone metody tworzenia aplikacji za pomocą interfejsu API Map Google na Wear OS

Jak zadbać o wygodę użytkowników aplikacji:

  • Mapa powinna zajmować dużą część ekranu. Jest to konieczne, aby zoptymalizować łatwość obsługi mapy na małych urządzeniach do noszenia.
  • Podczas projektowania aplikacji weź pod uwagę fakt, że urządzenie do noszenia ma niski poziom baterii. Aktywny ekran i widoczna mapa wpływa na zużycie baterii.