Inizia a utilizzare i widget

Prerequisiti e configurazione

Prima di iniziare, assicurati che il tuo ambiente soddisfi i seguenti requisiti.

Requisiti di runtime

I widget per Wear richiedono la versione 1.6.1 o successive dell'APK com.google.android.wearable.protolayout.renderer sul dispositivo di destinazione.

Ottieni una versione compatibile del renderer in uno dei seguenti modi:

  • Emulatore Wear OS 7: utilizza l'immagine dell'emulatore Wear OS 7. Le versioni inferiori a 7 non sono adatte. Per istruzioni per la configurazione, vedi Configurare l'emulatore Wear OS 7.
  • Dispositivo fisico: utilizza un dispositivo Wear OS fisico che riceve aggiornamenti automatici dal Google Play Store o un dispositivo per sviluppatori su cui è stato eseguito l'accesso al Google Play Store.

Per controllare la versione installata sul dispositivo, utilizza il seguente comando:

adb shell dumpsys package com.google.android.wearable.protolayout.renderer | \
  grep -m 1 versionName | \
  awk -F= '{print $2}'

Configurazione di Gradle

Le librerie dei widget per Wear sono disponibili su Google Maven.

1. Configura la versione dell'SDK

Assicurati che compileSdk e targetSdk siano impostati su 37 o versioni successive.

android {
    compileSdk = 37
    // ...
    defaultConfig {
        targetSdk = 37
        // ...
    }
}

2. Aggiungi dipendenze

Includi le seguenti dipendenze nel file build.gradle.kts dell'app:

Groovy

dependencies {
    // Core Wear Widget and Remote Compose libraries
    implementation "androidx.compose.remote:remote-creation-compose:1.0.0-alpha19"
    implementation "androidx.compose.remote:remote-core:1.0.0-alpha19"
    implementation "androidx.glance.wear:wear:1.0.0-alpha18"
    implementation "androidx.glance.wear:wear-core:1.0.0-alpha18"
    implementation "androidx.wear.compose.remote:remote-material3:1.0.0-alpha11"

    // Tooling for previews (optional, but recommended)
    implementation "androidx.compose.remote:remote-tooling-preview:1.0.0-alpha19"
    implementation "androidx.wear.compose:compose-ui-tooling:1.6.2"
    implementation "androidx.wear.tiles:tiles-tooling-preview:1.6.2"
    debugImplementation "androidx.wear.tiles:tiles-renderer:1.6.2"
}

Kotlin

dependencies {
    // Core Wear Widget and Remote Compose libraries
    implementation("androidx.compose.remote:remote-creation-compose:1.0.0-alpha19")
    implementation("androidx.compose.remote:remote-core:1.0.0-alpha19")
    implementation("androidx.glance.wear:wear:1.0.0-alpha18")
    implementation("androidx.glance.wear:wear-core:1.0.0-alpha18")
    implementation("androidx.wear.compose.remote:remote-material3:1.0.0-alpha11")

    // Tooling for previews (optional, but recommended)
    implementation("androidx.compose.remote:remote-tooling-preview:1.0.0-alpha19")
    implementation("androidx.wear.compose:compose-ui-tooling:1.6.2")
    implementation("androidx.wear.tiles:tiles-tooling-preview:1.6.2")
    debugImplementation("androidx.wear.tiles:tiles-renderer:1.6.2")
}

Crea un widget Hello World

Un widget Wear è costituito da un servizio che estende GlanceWearWidgetService e da una classe widget che estende GlanceWearWidget. Definisci la UI utilizzando le funzioni @RemoteComposable.

Definisci il servizio

Il servizio è il punto di ingresso a cui si associa il sistema.

Per definire il widget, crea un servizio che estenda GlanceWearWidgetService e annotalo con @AssociateWithGlanceWearWidget, per associare il servizio alla classe GlanceWearWidget appropriata.

@AssociateWithGlanceWearWidget(HelloWidget::class)
class HelloWidgetService : GlanceWearWidgetService() {
    override val widget: GlanceWearWidget = HelloWidget()
}

Definisci il widget

La classe del widget fornisce i dati e il layout del widget.

class HelloWidget : GlanceWearWidget() {
    override suspend fun provideWidgetData(
        context: Context,
        params: WearWidgetParams,
    ): WearWidgetData {
        return WearWidgetDocument(
            background = WearWidgetBrush.color(Color.Blue.rc),
        ) {
            HelloWidgetContent()
        }
    }
}

Definisci i contenuti

I contenuti sono creati utilizzando i componenti Remote Compose.

@RemoteComposable
@Composable
fun HelloWidgetContent() {
    RemoteBox(
        modifier = RemoteModifier.fillMaxSize(),
        contentAlignment = RemoteAlignment.Center,
    ) {
        RemoteText(
            text = "Hello World".rs,
            color = Color.White.rc,
        )
    }
}

Visualizzare l'anteprima del widget in Android Studio

Puoi visualizzare l'anteprima dei layout dei widget direttamente nel riquadro Design di Android Studio utilizzando androidx.glance.wear:wear-tooling-preview.

Suite di anteprima predefinite

La libreria wear-tooling-preview fornisce suite PreviewParameterProvider predefinite per testare i layout in diverse forme di contenitori e configurazioni di dispositivi:

  • Suite Supercerchio (SquircleAllWidgetPreviewParams): contenitori rettangolari arrotondati.
  • Round Suite (RoundAllWidgetPreviewParams): contenitori a forma di pillola.
  • Suite rettangolare (RectangularAllWidgetPreviewParams): contenitori rettangolari non ritagliati con spaziatura sicura. Le immagini generate con questa configurazione di anteprima sono adatte all'uso come immagini di anteprima incorporate nell'APK utilizzate dal selettore di widget (vedi Generare asset di immagini di anteprima).

Per visualizzare l'anteprima del widget in Android Studio, utilizza @WearWidgetPreview:

@Preview
@Composable
fun HelloWidgetPreview(
    @PreviewParameter(SquircleAllWidgetPreviewParams::class) params: WearWidgetParams,
) {
    WearWidgetPreview(
        widget = HelloWidget(),
        params = params,
    )
}

Crea il file XML di configurazione del widget

Crea un nuovo file res/xml/hello_widget_info.xml per definire le proprietà e le dimensioni supportate del widget. Per un riferimento completo degli attributi XML supportati nel tag <wearwidget-provider>, consulta la documentazione di WearWidgetProviderInfo.

<wearwidget-provider
    description="@string/hello_widget_description"
    icon="@mipmap/ic_launcher"
    label="@string/hello_widget_label"
    preferredType="SMALL">

    <container
        type="SMALL"
        previewImage="@drawable/widget_preview_small" />
    <container
        type="LARGE"
        previewImage="@drawable/widget_preview_large" />
</wearwidget-provider>

Generare asset immagine di anteprima

L'attributo previewImage dell'elemento <container> fa riferimento a un asset disegnabile mostrato nel selettore di widget di sistema. Per generare asset di anteprima con limiti e densità corretti, utilizza le anteprime di Android Studio con RectangularAllWidgetPreviewParams (che genera varianti di anteprima per contenitori piccoli e grandi) e specifica una densità di visualizzazione dello smartwatch di 320 DPI:

@Preview(
    name = "Widget Preview Asset",
    device = "spec:width=1000dp,height=1000dp,dpi=320",
)
@Composable
fun HelloWidgetCatalogPreview(
    @PreviewParameter(RectangularAllWidgetPreviewParams::class) params: WearWidgetParams,
) {
    WearWidgetPreview(
        widget = HelloWidget(),
        params = params,
    )
}

Per estrarre le immagini di anteprima sottoposte a rendering, completa i seguenti passaggi:

  1. In Android Studio, apri la superficie Design per il composable di anteprima.
  2. Nella finestra di anteprima, fai clic con il tasto destro del mouse sull'anteprima sottoposta a rendering o utilizza la barra degli strumenti di anteprima per selezionare Copia immagine o salvare l'immagine. In alternativa, utilizza strumenti CLI o script automatizzati per estrarre le anteprime di Compose.
  3. Salva i file immagine piccoli e grandi nella directory res/drawable-nodpi/ della tua app, ad esempio res/drawable-nodpi/widget_preview_small.png e res/drawable-nodpi/widget_preview_large.png.

Registrazione in AndroidManifest.xml

Registra il servizio in AndroidManifest.xml con i filtri di intent e i metadati richiesti.

<service
    android:name=".snippets.widget.HelloWidgetService"
    android:exported="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/hello_widget_label"
    android:permission="com.google.android.wearable.permission.BIND_TILE_PROVIDER">

    <intent-filter>
        <action android:name="androidx.glance.wear.action.BIND_WIDGET_PROVIDER" />
        <!-- If you already have a Tile, omit the following line. -->
        <action android:name="androidx.wear.tiles.action.BIND_TILE_PROVIDER" />
    </intent-filter>

    <meta-data
        android:name="androidx.glance.wear.widget.provider"
        android:resource="@xml/hello_widget_info" />

    <meta-data
        android:name="androidx.wear.tiles.PREVIEW"
        android:resource="@drawable/tile_preview" />
</service>

Creazione e deployment

Dopo aver definito il servizio e il widget, puoi creare il progetto e implementarlo su un dispositivo o un emulatore.

Creazione e installazione

Crea il progetto e installa l'APK di debug sul dispositivo connesso o sull'emulatore:

./gradlew :app:installDebug

Aggiungere e visualizzare l'anteprima del widget

Dopo l'installazione dell'app, utilizza adb per aggiungere il widget in modo programmatico al carosello e visualizzarlo sullo schermo.

Nota:i widget Wear utilizzano l'infrastruttura dei riquadri sottostante a scopo di debug. Di conseguenza, i comandi adb richiedono le operazioni add-tile e show-tile.

1. Aggiungi il widget al carosello:

adb shell am broadcast \
  -a com.google.android.wearable.app.DEBUG_SURFACE \
  --es operation add-tile \
  --ecn component <your_package_name>/.HelloWidgetService

2. Mostrare il widget:

adb shell am broadcast \
  -a com.google.android.wearable.app.DEBUG_SYSUI \
  --es operation show-tile \
  --ei index 0

Aggiornare i contenuti del widget in modo programmatico

Quando i dati sottostanti dell'app cambiano (ad esempio, quando ricevi una sincronizzazione dei dati, una notifica push o un'azione dell'utente), notifica al sistema di aggiornare i contenuti del widget.

Per richiedere un aggiornamento per tutte le istanze attive del widget, chiama triggerUpdateAll nella classe del widget:

// Request a content update for all active HelloWidget instances
HelloWidget().triggerUpdateAll(context)

Per aggiornare un'istanza widget specifica senza aggiornare tutte le istanze attive, chiama triggerUpdate con l'ID istanza di destinazione.