Как начать работу с виджетами

Требования и настройка

Прежде чем начать, убедитесь, что ваша среда соответствует следующим требованиям.

Требования к среде выполнения

Для работы виджетов Wear на целевом устройстве требуется APK 1.6.1 или более поздней версии. com.google.android.wearable.protolayout.renderer

Получите совместимую версию средства визуализации одним из следующих способов:

  • Эмулятор Wear OS 7. Используйте образ эмулятора Wear OS 7. Версии ниже 7 не подходят. Инструкции по настройке приведены в статье Как настроить эмулятор Wear OS 7.
  • Физическое устройство. Используйте физическое устройство Wear OS, которое автоматически получает обновления из Google Play, или устройство разработчика, на котором выполнен вход в Google Play.

Чтобы проверить, какая версия установлена на вашем устройстве, используйте следующую команду:

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

Конфигурация Gradle

Библиотеки Wear Widget доступны в Google Maven.

1. Настройка версии SDK

Убедитесь, что для compileSdk и targetSdk задано значение 37 или выше.

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

2. Как добавить зависимости

Добавьте в файл build.gradle.kts своего приложения следующие зависимости:

Groovy

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

    // Tooling for previews (optional, but recommended)
    implementation "androidx.compose.remote:remote-tooling-preview:1.0.0-alpha20"
    implementation "androidx.wear.compose:compose-ui-tooling:1.7.0"
    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-alpha20")
    implementation("androidx.compose.remote:remote-core:1.0.0-alpha20")
    implementation("androidx.glance.wear:wear:1.0.0-alpha19")
    implementation("androidx.glance.wear:wear-core:1.0.0-alpha19")
    implementation("androidx.wear.compose.remote:remote-material3:1.0.0-alpha12")

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

Как создать виджет Hello World

Виджет Wear состоит из сервиса, расширяющего класс GlanceWearWidgetService, и класса виджета, расширяющего класс GlanceWearWidget. Интерфейс определяется с помощью функций @RemoteComposable.

Как определить сервис

Сервис – это точка входа, с которой связывается система.

Чтобы определить виджет, создайте сервис, который расширяет GlanceWearWidgetService, и добавьте к нему аннотацию @AssociateWithGlanceWearWidget, чтобы связать сервис с подходящим классом GlanceWearWidget.

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

Как задать виджет

Класс виджета предоставляет данные и макет для виджета.

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

Как определить контент

Контент создан с помощью компонентов Remote Compose.

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

Как посмотреть виджет в Android Studio

Вы можете посмотреть макеты виджетов прямо на панели Дизайн в Android Studio, используя androidx.glance.wear:wear-tooling-preview.

Стандартные наборы для предпросмотра

Библиотека wear-tooling-preview содержит готовые наборы PreviewParameterProvider для тестирования макетов на контейнерах разных форм и устройствах с разными конфигурациями:

  • Squircle Suite (SquircleAllWidgetPreviewParams): контейнеры в виде прямоугольников со скругленными углами.
  • Круглые контейнеры (RoundAllWidgetPreviewParams) в форме таблеток.
  • Прямоугольные контейнеры (RectangularAllWidgetPreviewParams). Прямоугольные контейнеры без обрезки с безопасными отступами. Изображения, созданные с помощью этой конфигурации предпросмотра, подходят для использования в качестве встроенных в APK изображений предпросмотра, которые используются в инструменте выбора виджетов (см. Создание объектов изображений предпросмотра).

Чтобы посмотреть виджет в Android Studio, выполните следующие действия:@WearWidgetPreview

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

Как создать XML-файл конфигурации виджета

Создайте новый файл res/xml/hello_widget_info.xml, чтобы определить свойства виджета и поддерживаемые размеры. Полный список поддерживаемых атрибутов XML в теге <wearwidget-provider> приведен в документации по тегу 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>

Как создать объекты изображений для предпросмотра

Атрибут previewImage элемента <container> ссылается на графический объект, который показывается в инструменте выбора системных виджетов. Чтобы создать объекты для предварительного просмотра с правильными границами и плотностью, используйте функцию предварительного просмотра в Android Studio с параметром RectangularAllWidgetPreviewParams (он позволяет создавать варианты для контейнеров разных размеров) и укажите плотность экрана часов 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,
    )
}

Чтобы извлечь изображения предпросмотра, выполните следующие действия:

  1. В Android Studio откройте дизайн для предварительного просмотра composable-функции.
  2. В окне предпросмотра нажмите правой кнопкой мыши на сгенерированное изображение или используйте панель инструментов предпросмотра, чтобы выбрать Копировать изображение или сохранить изображение. Также можно использовать инструменты командной строки или автоматизированные скрипты для извлечения предварительных версий Compose.
  3. Сохраните файлы изображений в каталоге res/drawable-nodpi/ приложения, например res/drawable-nodpi/widget_preview_small.png и res/drawable-nodpi/widget_preview_large.png.

Регистрация в AndroidManifest.xml

Зарегистрируйте сервис в файле AndroidManifest.xml, указав необходимые фильтры намерений и метаданные.

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

Создание и развертывание

После того как вы определите сервис и виджет, вы можете создать проект и развернуть его на устройстве или эмуляторе.

Сборка и установка

Соберите проект и установите отладочный APK на подключенное устройство или эмулятор:

./gradlew :app:installDebug

Как добавить виджет и посмотреть его предварительную версию

После установки приложения используйте adb, чтобы программно добавить виджет в карусель и отобразить его на экране.

Примечание. Для отладки виджеты Wear используют инфраструктуру плиток. В результате для команд adb требуются операции add-tile и show-tile.

1. Добавьте виджет в карусель:

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

2. Показать виджет:

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

Как обновлять контент виджета программным способом

Когда в приложении меняются данные (например, при синхронизации, получении push-уведомления или действии пользователя), уведомляйте систему о необходимости обновить контент виджета.

Чтобы запросить обновление для всех активных экземпляров виджета, вызовите метод triggerUpdateAll в классе виджета:

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

Чтобы обновить определенный экземпляр виджета, не обновляя все активные экземпляры, вызовите triggerUpdate с идентификатором целевого экземпляра.