Interfejs API Map Google na Wear OS

Mapa na urządzeniu do noszenia

Dzięki pakietowi Maps SDK na Androida możesz tworzyć aplikacje na urządzenia do noszenia oparte na mapach, które działają bezpośrednio na urządzeniach z Wear OS by Google. Użytkownicy Twojej aplikacji mogą sprawdzić swoją lokalizację na mapie, spoglądając na nadgarstek. Mogą na przykład wyznaczyć swoją pozycję na trasie, a potem powiększyć widok, aby zobaczyć szczegóły, lub kliknąć znacznik, aby wyświetlić okno informacyjne dostarczone przez Twoją aplikację.

Na tej stronie opisaliśmy funkcje interfejsu API dostępne na urządzeniu do noszenia i pomożemy Ci zacząć tworzyć aplikację.

Wprowadzenie do Wear OS

Tworzenie aplikacji na urządzenia do noszenia za pomocą pakietu Maps SDK na Androida jest zasadniczo takie samo jak tworzenie aplikacji Map 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ż ułatwia konfigurowanie projektów, dodawanie bibliotek i pakowanie aplikacji.

Ogólne wskazówki dotyczące projektowania aplikacji na urządzenia do noszenia znajdziesz w wytycznych dotyczących projektowania aplikacji na Wear OS. Aby uzyskać pomoc w tworzeniu pierwszej aplikacji na urządzenie do noszenia, zapoznaj się z przewodnikiem tworzenia aplikacji na urządzenia do noszenia.

Tworzenie pierwszej aplikacji do map na Wear OS

Ten krótki przewodnik zakłada, że znasz pakiet Maps SDK na Androida, że zgodnie z przewodnikami dotyczącymi Wear OS utworzono w aplikacji moduł na urządzenie do noszenia i że chcesz teraz dodać do niego mapę.

Dodawanie zależności do modułu Wear

Sprawdź, czy w pliku build.gradle.kts modułu Wear OS aplikacji 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.

Implementowanie gestu przesuwania w celu zamknięcia i ustawianie początkowego koloru tła

Zalecamy używanie SwipeDismissFrameLayout do wyświetlania mapy na urządzeniu do noszenia. Za pomocą klasy SwipeDismissFrameLayout możesz zaimplementować gest przesunięcia w celu zamknięcia, który umożliwia użytkownikom zamknięcie 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 zdefiniować kolor, który ma być wyświetlany do czasu wczytania rzeczywistych kafelków mapy.

Dodaj elementy SwipeDismissFrameLayoutbackgroundColor 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 w aktywności uzyskasz obiekt SwipeDismissFrameLayout, dodaj wywołanie zwrotne i ustaw jego działanie tak, aby wykonywało niezbędną czynność zamykania, jak pokazano poniżej:

Kotlin

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


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

        // 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. Wywołanie zwrotne jest wywoływane, gdy mapa jest gotowa do użycia. W metodzie wywołania zwrotnego możesz dodawać do mapy markery lub polilinie, dodawać odbiorniki lub przesuwać kamerę. W przykładzie poniżej dodajemy marker 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 Maps SDK na Androida obsługuje tryb otoczenia w aplikacjach na urządzenia do noszenia. Aplikacje obsługujące tryb otoczenia są czasami nazywane aplikacjami zawsze włączonymi. Tryb nieaktywny jest aktywowany, gdy użytkownik przestaje aktywnie korzystać z aplikacji, i umożliwia jej wyświetlanie na urządzeniu do noszenia.

Pakiet Maps SDK na Androida zapewnia uproszczone renderowanie mapy w trybie otoczenia z użyciem mniejszej liczby kolorów. Styl mapy dostosowuje się automatycznie, gdy urządzenie przełącza się z trybu interaktywnego na tryb otoczenia. W trybie otoczenia znikają wszystkie znaczniki, obiekty i elementy interfejsu. Zmniejsza to zużycie energii przez aplikację i zapewnia spójny wygląd i działanie z innymi aplikacjami działającymi w trybie otoczenia, takimi jak tarcze zegarka.

Aby mieć pewność, że aplikacja korzysta z trybu nieaktywnego mapy, wykonaj te czynności:

  1. Zaktualizuj pakiet SDK na Androida, aby zawierał platformę Android 6.0 (API 23) lub nowszą, która udostępnia interfejsy API umożliwiające przechodzenie aktywności w tryb otoczenia. Informacje o tym, jak zaktualizować pakiet SDK, znajdziesz w dokumentacji Androida na temat dodawania pakietów SDK.
  2. Upewnij się, że projekt jest kierowany na Androida 6.0 lub nowszego, ustawiając wartość parametru targetSdkVersion na 23 lub wyższą w pliku manifestu aplikacji.
  3. Dodaj zależności dotyczące urządzeń do pliku build.gradle.kts aplikacji. Zobacz przykłady na tej stronie.
  4. Dodaj wpis do biblioteki udostępnianej na urządzeniach do noszenia do pliku manifestu aplikacji na urządzenie do noszenia, jak opisano w szkoleniu na Androida dotyczącym zapewniania widoczności aplikacji.
  5. Dodaj uprawnienie WAKE_LOCK do plików manifestu aplikacji na urządzenia przenośne i zegarki, zgodnie z opisem w szkoleniu na 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 gdy urządzenie się wyłączy, powinno przejść w tryb otoczenia, a nie wrócić do tarczy zegarka.
  7. Zaimplementuj interfejs AmbientModeSupport.AmbientCallbackProvider w aktywności, aby mogła ona odbierać zmiany stanu trybu otoczenia.
  8. Skonfiguruj mapę tak, aby obsługiwała tryb nieaktywny. 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 do użycia w trybie otoczenia.
  9. Gdy aktywność przejdzie w tryb nieaktywny, system wywoła metodę onEnterAmbient()AmbientCallback, którą podasz. Zastąp onEnterAmbient() i zadzwoń SupportMapFragment.onEnterAmbient(ambientDetails) lub MapView.onEnterAmbient(ambientDetails). Interfejs API przełącza się na nieinteraktywną mapę o niskiej liczbie kolorów.
  10. Podobnie w przypadku połączenia onExitAmbient() wybierz SupportMapFragment.onExitAmbient() lub MapView.onExitAmbient(). API przełącza się na normalne renderowanie mapy.

Poniższy przykładowy kod włącza tryb otoczenia w aktywności:

Kotlin

class AmbientActivity : AppCompatActivity(), AmbientModeSupport.AmbientCallbackProvider {

    private lateinit var mapFragment: SupportMapFragment

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

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

      

Ekran można aktualizować, gdy aplikacja jest w trybie dalszego wykrywania. Więcej informacji o aktualizowaniu treści i trybie otoczenia znajdziesz w szkoleniu na temat Androida Utrzymywanie 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 wyjście z aplikacji podczas wyświetlania panoramy Street View, użyj interfejsu StreetViewPanorama.OnStreetViewPanoramaLongClickListener, aby nasłuchiwać gestu długiego kliknięcia. Gdy użytkownik kliknie i przytrzyma wskaźnik w dowolnym miejscu na obrazie Street View, otrzymasz zdarzenie onStreetViewPanoramaLongClick(StreetViewPanoramaOrientation). Call DismissOverlayView.show(), aby wyświetlić przycisk wyjścia.

Przykładowy kod

Na GitHub dostępna jest przykładowa aplikacja, której możesz użyć jako punktu wyjścia. Pokazuje ona, jak skonfigurować podstawową mapę Google na urządzeniu z Wear OS.

Obsługiwane funkcje interfejsu API Map Google na Wear OS

W tej sekcji znajdziesz informacje o różnicach w obsługiwanych funkcjach map na urządzeniach do noszenia w porównaniu z urządzeniami przenośnymi (telefonami i tabletami). Wszystkie funkcje interfejsu API, które nie zostały wymienione poniżej, powinny działać zgodnie z dokumentacją pełnej wersji interfejsu API.

Funkcje
Tryb w pełni interaktywny i wersja uproszczona

Pakiet Maps SDK na Androida możesz używać w trybie w pełni interaktywnym lub w trybie uproszczonym. Tryb uproszczony warto rozważyć, 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 zamiar uruchomienia aplikacji mobilnej Mapy Google po kliknięciu mapy przez użytkownika 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 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 interfejsu Elementy sterujące interfejsu są domyślnie wyłączone na urządzeniach do noszenia. Obejmuje to elementy sterujące powiększeniem, kompasem i moją lokalizacją. Możesz je włączyć za pomocą klasy UiSettings jak zwykle.
Gesty Gesty jednym palcem działają zgodnie z oczekiwaniami. Przykłady to dotknięcie i przeciągnięcie, aby przesunąć mapę, dwukrotne kliknięcie, aby powiększyć, oraz kliknięcie dwoma palcami, aby pomniejszyć. Obsługa gestów wielodotykowych zależy od urządzenia użytkownika. Przykłady gestów wielodotykowych to przesuwanie dwoma palcami w celu pochylenia mapy, ściąganie palców w celu powiększenia widoku i obracanie dwoma palcami.
Mapy obiektów i budynków Mapy obiektów 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 wnętrz są włączone, na mapie będzie widoczny domyślny poziom. Element interfejsu selektora poziomu nie jest obsługiwany na urządzeniach do noszenia.
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 API Map Google na Wear OS

Jak zapewnić użytkownikom jak największą wygodę w aplikacji:

  • Mapa powinna zajmować dużą część ekranu. Jest to konieczne, aby zoptymalizować użyteczność mapy na małym urządzeniu, jakim jest urządzenie do noszenia.
  • Projektując interfejs użytkownika aplikacji, weź pod uwagę, że urządzenie do noszenia ma słabą baterię. Włączony ekran i widoczna mapa mają wpływ na wydajność baterii.