Interfejs API Map Google na Wear OS

Mapa na urządzeniu do noszenia

Za pomocą pakietu SDK Map Google na Androida możesz utworzyć aplikację na urządzenia noszące, która działa bezpośrednio na Wear OS na urządzeniach Google. Użytkownicy Twojej aplikacji mogą zobaczyć swoją lokalizację na mapie, zerkając na nadgarstok. Mogą na przykład wyświetlić swoją pozycję na trasie, a następnie powiększyć widok, aby zobaczyć szczegóły, lub kliknąć znacznik, aby wyświetlić okno z informacjami w aplikacji.

Na tej stronie opisujemy funkcje interfejsu API dostępne na urządzeniu z Androidem Wear i pomagamy Ci zacząć tworzyć aplikację.

Pierwsze kroki w Wear OS

Tworzenie aplikacji na urządzenia noszące z użyciem pakietu SDK Map Google na Androida jest zasadniczo takie samo jak tworzenie aplikacji Mapy Google na dowolne inne urządzenie z Androidem. Różnica polega na tym, że musisz zaprojektować aplikację pod kątem mniejszego formatu urządzenia do noszenia, aby zoptymalizować jej użyteczność i wydajność.

Android Studio to zalecane narzędzie do tworzenia aplikacji na Wear OS, ponieważ umożliwia konfigurowanie projektu, dodawanie bibliotek i pakowanie.

Ogólne wskazówki dotyczące projektowania aplikacji na urządzenia noszące znajdziesz w wytycznych dotyczących projektowania na Wear OS. Aby utworzyć pierwszą aplikację na urządzenie noszące, skorzystaj z pomocy w tym przewodniku Tworzenie aplikacji na urządzenia noszące.

Tworzenie pierwszej aplikacji map na Wear OS

W tym krótkim przewodniku zakładamy, że znasz pakiet SDK Map na Androida, że korzystając z instrukcji dotyczących Wear OS, utworzysz w swojej aplikacji moduł na urządzenia noszące, i że chcesz teraz dodać do tego modułu mapę.

Dodawanie zależności dla modułu Wear

Upewnij się, że w pliku build.gradle.kts w module aplikacji na Wear OS znajdują się 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:19.0.0")

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

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

Implementacja gestu przesunięcia w dół w celu zamknięcia i ustawienie początkowego koloru tła

Zalecamy wyświetlanie mapy na urządzeniu do noszenia za pomocą SwipeDismissFrameLayout. Za pomocą klasy SwipeDismissFrameLayout możesz wdrożyć gest przesuń, aby zamknąć, który umożliwi użytkownikom zamykanie aplikacji przez przesunięcie palcem od lewej krawędzi ekranu.

Aby ustawić niestandardowy początkowy kolor tła, użyj atrybutu XML map:backgroundColor, aby określić kolor, który ma być wyświetlany do momentu załadowania się rzeczywistych płytek mapy.

Dodaj do definicji układu elementy SwipeDismissFrameLayoutbackgroundColor jako element kontenera 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 obiekt SwipeDismissFrameLayout w swojej aktywności, dodaj funkcję wywołania zwrotnego i ustaw jej zachowanie, aby wykonać niezbędne działanie anulowania, 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

Użyj metody wywołania zwrotnego onMapReady(GoogleMap) jak zwykle, aby uzyskać uchwyt do obiektu GoogleMap. Gdy mapa jest gotowa do użycia, wywołuje się wywołanie zwrotne. W metodzie wywołania możesz dodawać do mapy znaczniki lub linie złożone, dodawać słuchaczy lub przesuwać kamerę. Przykład poniżej pokazuje dodanie znacznika 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łączanie trybu nieaktywnego

Pakiet SDK Map na Androida obsługuje tryb ambient w aplikacjach na urządzenia noszące. Aplikacje obsługujące tryb ambient są czasami nazywane aplikacjami zawsze włączonymi. Tryb ambient jest aktywowany, gdy użytkownik nie korzysta już aktywnie z aplikacji, i pozwala aplikacji pozostać widocznej na urządzeniu do noszenia.

Pakiet SDK Map Google na Androida zapewnia uproszczone renderowanie mapy w małej ilości kolorów na potrzeby trybu ambient. Styl mapy dostosowuje się automatycznie, gdy urządzenie przełączy się z trybu interaktywnego na tryb ambient. Wszystkie znaczniki, obiekty i elementy interfejsu użytkownika znikają w trybie otoczenia. Dzięki temu zmniejszysz zużycie energii przez aplikację i zapewnisz spójny wygląd i działanie w porównaniu z innymi aplikacjami na ekranie Ambient, takimi jak tarcze zegarka.

Aby mieć pewność, że Twoja aplikacja korzysta z trybu nieaktywnej mapy:

  1. Zaktualizuj pakiet SDK Androida, aby uwzględnić platformę Android 6.0 (API 23) lub nowszą, która udostępnia interfejsy API umożliwiające przechodzenie aktywności w tryb ambient. Informacje o aktualizowaniu pakietu 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 w pliku manifestu aplikacji parametr targetSdkVersion na 23 lub wyższy.
  3. Dodaj zależności dotyczące urządzeń noszonych do pliku build.gradle.kts aplikacji. Zobacz przykład na tej stronie.
  4. Dodaj wpis do wspólnej biblioteki na urządzeniu noszącym w pliku manifestu aplikacji na urządzenie noszące, zgodnie z opisem w szkoleniu na temat Androida dotyczącym utrzymywania widoczności aplikacji.
  5. Dodaj uprawnienia WAKE_LOCK do plików manifestów aplikacji na urządzenia ręczne i na urządzenia noszące, zgodnie z instrukcjami podanymi w szkoleniu na temat Androida dotyczącym 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 powinna przejść w tryb otoczenia, a nie wracać na tarczę zegarka.
  7. W swojej aktywności zaimplementuj interfejs AmbientModeSupport.AmbientCallbackProvider, aby mogła ona odbierać zmiany stanu trybu ambient.
  8. Skonfiguruj mapę tak, aby obsługiwała tryb obrazu w tle. Możesz to zrobić, ustawiając atrybut map:ambientEnabled="true" w pliku układu XML aktywności lub programowo, ustawiając GoogleMapOptions.ambientEnabled(true). To ustawienie informuje interfejs API, że musi wstępnie wczytać niezbędne kafelki mapy na potrzeby trybu ambient.
  9. Gdy aktywność przełączy się na tryb pełnoekranowy, system wywoła metodę onEnterAmbient() w określonym przez Ciebie obiekcie AmbientCallback. Zastąpić onEnterAmbient() i wywołać funkcję SupportMapFragment.onEnterAmbient(ambientDetails) lub MapView.onEnterAmbient(ambientDetails). Interfejs API przełącza się na nieinteraktywną mapę z niskim poziomem kolorów.
  10. Podobnie w onExitAmbient() nazwa SupportMapFragment.onExitAmbient() lub MapView.onExitAmbient(). Interfejs API przełącza się na normalne renderowanie mapy.

Ten przykładowy kod włącza tryb ambient 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 aktualizować ekran, gdy aplikacja jest w trybie ambient. Więcej informacji o aktualizowaniu treści i ogólnych zasadach działania trybu ambient znajdziesz w sesji szkoleniowej na temat Androida poświęconej utrzymywaniu widoczności aplikacji.

Korzystanie z Street View na Wear OS

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

Aby umożliwić użytkownikom wyjście z aplikacji podczas oglądania panoramy Street View, użyj interfejsu StreetViewPanorama.OnStreetViewPanoramaLongClickListener, aby wykrywać długie kliknięcia. Gdy użytkownik kliknie i przytrzyma gdzieś na zdjęciu w Street View, otrzymasz zdarzenie onStreetViewPanoramaLongClick(StreetViewPanoramaOrientation). Zadzwoń DismissOverlayView.show(), aby wyświetlić przycisk wyjścia.

Przykładowy kod

Na GitHub jest dostępna przykładowa aplikacja, którą możesz wykorzystać jako punkt wyjścia do tworzenia własnej aplikacji. Przykład pokazuje, jak skonfigurować podstawowe Mapy Google na Wear OS.

Obsługiwane funkcje interfejsu Maps API na Wear OS

W tej sekcji opisano różnice w obsługiwanych funkcjach map na urządzeniach do noszenia w porównaniu z urządzeniami przenośnymi (telefony i tablety). Wszystkie funkcje interfejsu API, które nie są wymienione poniżej, powinny działać zgodnie z dokumentacją dotyczącą pełnego interfejsu API.

Funkcjonalność
Tryb w pełni interaktywny i tryb uproszczony

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

W trybie uproszczonym, gdy użytkownik kliknie mapę, zamiar uruchomienia aplikacji mobilnej Mapy Google jest wyłączony i nie można go włączyć na urządzeniu do noszenia.

Pełną listę różnic między trybem uproszczonym a w pełni interaktywnym znajdziesz w dokumentacji dotyczącej trybu uproszczonego.

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 w interfejsie Elementy sterujące interfejsu użytkownika są domyślnie wyłączone na urządzeniach do noszenia. Dotyczy to opcji powiększania, kompasu i mojej lokalizacji. Możesz je włączyć, korzystając z klasy UiSettings jak zwykle.
Gesty Gesty jednodotykowe działają zgodnie z oczekiwaniami. Przykłady: dotknij i przeciągnij, aby przesuwać mapę, kliknij dwukrotnie, aby powiększyć, i kliknij 2 palcami, aby pomniejszyć. Obsługa gestów wielodotykowych różni się w zależności od urządzenia użytkownika. Przykłady gestów wielodotykowych: naciśnięcie 2 palcami, aby przechylić mapę, ściśnięcie palcami, aby powiększyć, oraz obrócenie 2 palcami.
Mapy i budynki wewnętrzne Mapy wewnętrzne są domyślnie wyłączone na urządzeniu do noszenia. Możesz je włączyć, dzwoniąc pod numer GoogleMap.setIndoorEnabled(true). Jeśli mapy wewnętrzne są włączone, mapa będzie wyświetlać domyślny poziom piętra. Element interfejsu użytkownika poziomównie jest obsługiwany na urządzeniach noszonych.
Nakładki z kafelkami Nakładki na kafelki nie są obsługiwane na urządzeniach do noszenia.

Sprawdzone metody tworzenia aplikacji z użyciem interfejsu Maps API na Wear OS

Jak zapewnić użytkownikom jak najlepsze wrażenia w aplikacji:

  • Mapa powinna zajmować dużą część ekranu. Jest to konieczne, aby zoptymalizować użyteczność mapy na małym urządzeniu do noszenia.
  • Podczas projektowania aplikacji weź pod uwagę fakt, że urządzenie do noszenia ma ograniczoną pojemność baterii. Utrzymywanie ekranu w stanie aktywnym i mapy w widoczności będzie wpływać na wydajność baterii.