API di Google Maps su Wear OS

Una mappa su un dispositivo indossabile

Con Maps SDK for Android puoi creare un'app per dispositivi indossabili basata su mappe che viene eseguita direttamente sui dispositivi Wear OS di Google. Gli utenti della tua app possono vedere la propria posizione sulla mappa semplicemente guardando il polso. Ad esempio, possono tracciare la propria posizione su un percorso, quindi aumentare lo zoom per visualizzare i dettagli o toccare un indicatore per visualizzare una finestra informativa fornita dalla tua app.

Questa pagina descrive la funzionalità dell'API disponibile su un dispositivo Wear e ti aiuta a iniziare a creare la tua app.

Iniziare a utilizzare Wear OS

La creazione di un'app per dispositivi indossabili con Maps SDK for Android è essenzialmente la stessa della creazione di un'app Google Maps per qualsiasi altro dispositivo Android. La differenza sta nel design per il fattore di forma più piccolo del dispositivo indossabile, per ottimizzare l'usabilità e le prestazioni dell'app.

Android Studio è lo strumento consigliato per lo sviluppo per Wear OS, poiché offre la configurazione del progetto, l'inclusione delle librerie e la comodità del packaging.

Per assistenza generale sulla progettazione di un'app per indossabili, consulta le linee guida per la progettazione di Wear OS. Per assistenza sulla creazione della tua prima app per dispositivi indossabili, consulta la guida alla creazione di app per dispositivi indossabili.

Creare la tua prima app di mappe su Wear OS

Questa guida rapida presuppone che tu abbia dimestichezza con Maps SDK for Android, che tu abbia seguito le guide per Wear OS per creare un modulo per dispositivi indossabili nella tua app e che ora tu voglia aggiungere una mappa al modulo per dispositivi indossabili.

Aggiunta di dipendenze per il modulo Wear

Assicurati che le seguenti dipendenze siano incluse nel file build.gradle.kts del modulo Wear OS della tua app:

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

Per ulteriori informazioni sulle dipendenze, consulta la guida su come aggiungere un modulo Wear OS al progetto esistente.

Implementazione di un gesto di scorrimento per chiudere e impostazione del colore di sfondo iniziale

Ti consigliamo di utilizzare un SwipeDismissFrameLayout per visualizzare la mappa sul dispositivo indossabile. Utilizzando la classe SwipeDismissFrameLayout, puoi implementare il gesto di scorrimento per chiudere, offrendo agli utenti un modo per uscire dall'app scorrendo dal bordo più a sinistra dello schermo.

Per impostare un colore di sfondo iniziale personalizzato, utilizza l'attributo XML map:backgroundColor per definire il colore da visualizzare fino al caricamento dei riquadri della mappa effettivi.

Aggiungi gli elementi SwipeDismissFrameLayout e backgroundColor alla definizione del layout come contenitore di 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>

Quando ottieni l'oggetto SwipeDismissFrameLayout nella tua attività, aggiungi un callback e imposta il relativo comportamento in modo da eseguire l'azione di chiusura necessaria, come mostrato di seguito:

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

    // ...
}

      

Aggiunta di una mappa

Utilizza il metodo di callback onMapReady(GoogleMap) come di consueto per ottenere un handle per l'oggetto GoogleMap. Il callback viene attivato quando la mappa è pronta per essere utilizzata. Nel metodo di callback, puoi aggiungere indicatori o polilinee alla mappa, aggiungere ascoltatori o spostare la fotocamera. L'esempio riportato di seguito aggiunge un indicatore vicino alla Sydney Opera House:

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

      

Attivazione della modalità Ambient

Maps SDK for Android supporta la modalità Ambient per le app per dispositivi indossabili. Le app che supportano la modalità Ambient vengono talvolta chiamate app sempre attive. La modalità Ambient viene attivata quando l'utente non utilizza più attivamente l'app e consente all'app di rimanere visibile sul dispositivo indossabile.

Maps SDK for Android fornisce un rendering semplificato e a colori ridotti della mappa per l'utilizzo in modalità Ambient e lo stile della mappa si regola automaticamente quando il dispositivo passa dalla modalità interattiva a quella Ambient. Tutti gli indicatori, gli oggetti e i controlli della UI scompaiono in modalità Ambient. In questo modo, riduci il consumo energetico della tua app e garantisci un'esperienza coerente con altre app Ambient, come i quadranti.

Per assicurarti che la tua app utilizzi la modalità Ambient della mappa:

  1. Aggiorna l'SDK Android in modo da includere la piattaforma Android 6.0 (livello API 23) o versioni successive, che fornisce le API che consentono alle attività di passare alla modalità Ambient. Per informazioni su come aggiornare l'SDK, consulta la documentazione Android sull'aggiunta di pacchetti SDK.
  2. Assicurati che il progetto abbia come target Android 6.0 o versioni successive impostando il valore targetSdkVersion su 23 o versioni successive nel file manifest dell'app.
  3. Aggiungi le dipendenze per i dispositivi indossabili al file build.gradle.kts della tua app. Guarda l'esempio in questa pagina.
  4. Aggiungi la voce della libreria condivisa per il dispositivo indossabile al manifest dell'app per il dispositivo indossabile, come descritto nel corso di formazione Android su come mantenere visibile l'app.
  5. Aggiungi l'autorizzazione WAKE_LOCK ai manifest delle app per dispositivi portatili e indossabili, come descritto nel corso di formazione Android su come mantenere visibile la tua app.
  6. Nel metodo onCreate() della tua attività, chiama il metodo AmbientModeSupport.attach(). In questo modo, il sistema operativo viene informato che l'applicazione è sempre attiva, quindi quando il dispositivo si spegne dovrebbe entrare in modalità Ambient anziché tornare al quadrante.
  7. Implementa l'interfaccia AmbientModeSupport.AmbientCallbackProvider nella tua attività in modo che possa ricevere le modifiche dello stato della modalità Ambient.
  8. Imposta la mappa in modo che supporti la modalità Ambient. Puoi farlo impostando l'attributo map:ambientEnabled="true" nel file di layout XML dell'attività o in modo programmatico impostando GoogleMapOptions.ambientEnabled(true). Questa impostazione indica all'API che deve precaricare le tessere della mappa necessarie per l'utilizzo in modalità Ambient.
  9. Quando l'attività passa alla modalità Ambient, il sistema chiama il metodo onEnterAmbient() nell'AmbientCallback fornito. Sostituisci onEnterAmbient() e chiama SupportMapFragment.onEnterAmbient(ambientDetails) o MapView.onEnterAmbient(ambientDetails). L'API passa a un rendering non interattivo e a colori ridotti della mappa.
  10. Analogamente, in onExitAmbient() chiama SupportMapFragment.onExitAmbient() o MapView.onExitAmbient(). L'API passa al rendering normale della mappa.

Il seguente esempio di codice attiva la modalità Ambient nell'attività:

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

      

Puoi aggiornare lo schermo mentre l'app è in modalità Ambient. Per maggiori dettagli sull'aggiornamento dei contenuti e sulla modalità Ambient in generale, consulta il corso di formazione Android su come mantenere visibile la tua app.

Utilizzare Street View su Wear OS

Street View è completamente supportato sui dispositivi indossabili.

Per consentire agli utenti di uscire dall'app quando visualizzano una panoramica di Street View, utilizza l'interfaccia StreetViewPanorama.OnStreetViewPanoramaLongClickListener per rilevare un gesto di clic prolungato. Quando un utente fa clic prolungato su un punto dell'immagine di Street View, riceverai un evento onStreetViewPanoramaLongClick(StreetViewPanoramaOrientation). Chiama DismissOverlayView.show() per visualizzare un pulsante di uscita.

Codice di esempio

Su GitHub è disponibile un'app di esempio che puoi utilizzare come punto di partenza per la tua app. L'esempio mostra come configurare una mappa di Google di base su Wear OS.

Funzionalità supportate nell'API Maps su Wear OS

Questa sezione illustra le differenze nelle funzionalità supportate per le mappe sui dispositivi indossabili rispetto ai dispositivi portatili (smartphone e tablet). Tutte le funzionalità dell'API non menzionate di seguito dovrebbero funzionare come descritto per l'API completa.

Funzionalità
Modalità completamente interattiva e modalità Lite

Puoi utilizzare Maps SDK for Android in modalità completamente interattiva o in modalità Lite. Valuta la possibilità di utilizzare la modalità Lite se vuoi ottimizzare il rendimento sul dispositivo indossabile e la tua app non deve supportare interazioni come i gesti o la panoramica e lo zoom della mappa.

In modalità Lite, l'intent per avviare l'app mobile Google Maps quando l'utente tocca la mappa è disattivato e non può essere attivato su un dispositivo indossabile.

Per un elenco completo delle differenze tra la modalità Lite e la modalità completamente interattiva, consulta la documentazione relativa alla modalità Lite.

Barra degli strumenti della mappa La barra degli strumenti della mappa è disattivata e non può essere attivata su un dispositivo indossabile.
Controlli UI I controlli della UI sono disattivati per impostazione predefinita sui dispositivi indossabili. Sono inclusi i controlli di zoom, bussola e posizione. Puoi attivarli utilizzando la classe UiSettings come di consueto.
Gesti I gesti con un solo tocco funzionano come previsto. Alcuni esempi sono toccare e trascinare per eseguire la panoramica della mappa, toccare due volte per aumentare lo zoom e toccare con due dita per diminuire lo zoom. Il supporto dei gesti multi-touch varia in base al dispositivo dell'utente. Alcuni esempi di gesti multi-touch sono spingere con due dita per inclinare la mappa, pizzicare per aumentare lo zoom e ruotare con due dita.
Mappe e edifici al coperto Le mappe di interni sono disattivate per impostazione predefinita su un dispositivo indossabile. Puoi attivarle chiamando GoogleMap.setIndoorEnabled(true). Se le mappe al chiuso sono attivate, la mappa mostrerà il livello del piano predefinito. L'elemento dell'interfaccia utente selettore di livello non è supportato sui dispositivi indossabili.
Overlay riquadri Gli overlay delle schede non sono supportati sui dispositivi indossabili.

Best practice per lo sviluppo con l'API Maps su Wear OS

Come offrire la migliore esperienza utente nella tua app:

  • La mappa deve occupare una parte considerevole dello schermo. Questo è necessario per ottimizzare l'usabilità della mappa sul fattore di forma ridotto di un dispositivo indossabile.
  • Quando progetti l'esperienza utente della tua app, tieni conto del fatto che la batteria di un dispositivo indossabile è in esaurimento. Se mantieni attivo lo schermo e visibile la mappa, il rendimento della batteria ne risentirà.