Как настроить приложение для Wear OS для Watch Face Push

Функция Watch Face Push позволяет приложению управлять циферблатами на устройстве Wear OS. В частности, вы можете добавлять, обновлять и удалять циферблаты, а также выбирать активный циферблат. Настройте приложение для Wear OS для использования Watch Face Push API.

Настроить

Добавьте зависимость androidx.wear.watchfacepush:watchfacepush в файл build.gradle.kts.

Добавьте в файл AndroidManifest.xml следующий код:

<!-- Required to use the Watch Face Push API.  -->
<uses-permission android:name="com.google.wear.permission.PUSH_WATCH_FACES" />

Как получить ссылку на экземпляр менеджера

Получите экземпляр WatchFacePushManager:

val watchFacePushManager = WatchFacePushManagerFactory.createWatchFacePushManager(context)

WatchFacePushManager предоставляет доступ ко всем методам взаимодействия с Watch Face Push.

Как работать с паузами

При работе с функцией "Отправка циферблатов" важно понимать, что такое слоты. Слоты позволяют обращаться к установленным циферблатам, которые относятся к вашему приложению. Система устанавливает максимальное количество рекламных мест, которые могут быть на торговой площадке. В Wear OS 6 это ограничение составляет 1.

При обновлении или удалении циферблата значок slotId используется для идентификации циферблата, с которым нужно выполнить операцию.

Как посмотреть список циферблатов

Чтобы получить список установленных циферблатов, используйте команду listWatchFaces():

val response = watchFacePushManager.listWatchFaces()
val installedList = response.installedWatchFaceDetails
installedList.forEach {
    Log.i(TAG, "Installed watchface: ${it.packageName}")
}

val remainingSlots = response.remainingSlotCount
Log.i(TAG, "Remaining slots: $remainingSlots")

Это позволяет определить, доступен ли слот или для добавления другого циферблата потребуется заменить существующий. В списке также приводится информация об установленном циферблате. Например, чтобы проверить, установлен ли определенный пакет циферблата, выполните следующие действия:

suspend fun isInstalled(packageName: String) = watchFacePushManager.listWatchFaces()
    .installedWatchFaceDetails.any { it.packageName == packageName }

Как добавить циферблат

Если в ответе listWatchFaces указано, что есть свободные места, следует использовать метод addWatchFace():

try {
    // Supply the validation token along with the watch face package data itself.
    val slot = watchFacePushManager.addWatchFace(parcelFileDescriptor, token)
    Log.i(TAG, "${slot.packageName} (${slot.versionCode}) added in slot ${slot.slotId}")
} catch (e: WatchFacePushManager.AddWatchFaceException) {
    Log.e(TAG, "Something went wrong installing the watch face", e)
}

Как обновить циферблат

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

// Replacing the com.example.watchfacepush.green watch face with
// com.example.watchfacepush.red
val slotId =
    watchFacePushManager.listWatchFaces().installedWatchFaceDetails
        .firstOrNull { it.packageName == "com.example.watchfacepush.green" }?.slotId
        ?: throw IllegalArgumentException("No green watch face found")
try {
    watchFacePushManager.updateWatchFace(slotId, redParcelFileDesc, redValidationToken)
} catch (e: WatchFacePushManager.UpdateWatchFaceException) {
    Log.e(TAG, "Something went wrong updating the watch face", e)
}

Как удалить циферблат

Чтобы удалить циферблат:

// Remove the com.example.watchfacepush.green watch face.
val slotId =
    watchFacePushManager.listWatchFaces().installedWatchFaceDetails
        .firstOrNull { it.packageName == "com.example.watchfacepush.green" }?.slotId
        ?: throw IllegalArgumentException("No green watch face found")

try {
    watchFacePushManager.removeWatchFace(slotId)
} catch (e: WatchFacePushManager.RemoveWatchFaceException) {
    Log.e(TAG, "Something went wrong removing the watch face", e)
}

Это значит, что циферблат всегда можно найти в системном инструменте выбора циферблатов. Вы можете разместить логотип и даже кнопку для запуска приложения из Marketplace на телефоне.

Проверьте, активен ли циферблат

Важно определить, установлен ли на устройстве активный циферблат. Если да, то пользователю нужно будет только заменить его в приложении магазина, чтобы выбрать другой. Однако если в магазине не задан активный циферблат, приложение для телефона должно предлагать пользователю дополнительные инструкции. Подробнее о том, как это реализовано в приложении "Телефон"…

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

suspend fun hasActiveWatchFace() = watchFacePushManager.listWatchFaces()
    .installedWatchFaceDetails
    .any {
        watchFacePushManager.isWatchFaceActive(it.packageName)
    }

Как задать циферблат по умолчанию

Функция "Отправка циферблата" позволяет установить циферблат по умолчанию при установке приложения из магазина. Это не делает циферблат активным (см. раздел о том, как задать активный циферблат), но добавляет его в системный выбор циферблатов.

Чтобы использовать эту функцию:

  1. В сборке приложения Wear OS укажите путь к циферблату по умолчанию: assets/default_watchface.apk
  2. Добавьте в файл AndroidManifest.xml следующую запись:

    <meta-data
        android:name="com.google.android.wearable.marketplace.DEFAULT_WATCHFACE_VALIDATION_TOKEN"
        android:value="@string/default_wf_token" />

Как установить активный циферблат

Функция Watch Face Push позволяет приложению из магазина устанавливать активный циферблат.

Это означает, что приложение может сделать активным циферблат из каталога, если текущий активный циферблат не относится к каталогу. Если на торговой площадке уже есть активный циферблат, его можно заменить на другой, вызвав функцию updateWatchFace.

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

  1. Получите разрешение Android, необходимое для установки активного циферблата.
  2. Вызовите метод setWatchFaceAsActive.

Как получить разрешения на установку активного циферблата

Требуемое разрешение: SET_PUSHED_WATCH_FACE_AS_ACTIVE. Его необходимо добавить в манифест:

<!-- Required to be able to call the setWatchFaceAsActive() method. -->
<uses-permission android:name="com.google.wear.permission.SET_PUSHED_WATCH_FACE_AS_ACTIVE" />

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

Сделать циферблат активным

После того как разрешение будет предоставлено, вызовите функцию setWatchFaceAsActive с идентификатором слота циферблата, который должен быть активен.

После этого в приложении для телефона должны появиться инструкции по установке активного циферблата вручную.

Чтение дополнительных метаданных из APK-файла циферблата

Объект WatchFaceSlot также позволяет получать дополнительную информацию, которую можно показывать на циферблате.

Это может быть особенно полезно, если у вас есть несколько незначительно отличающихся вариантов одного циферблата. Например, можно задать циферблат следующим образом:

  • Название пакета: com.myapp.watchfacepush.mywatchface
  • Версия пакета: 1.0.0

Но этот циферблат может быть представлен в виде четырех разных APK, которые почти идентичны, но имеют разные цвета по умолчанию: красный, желтый, зеленый и синий, заданные в элементе ColorConfiguration в XML-файле формата Watch Face Format.

Это небольшое изменение отражается в каждом из четырех APK:

<!-- For watch face com.myapp.watchfacepush.mywatchface -->
<property
    android:name="default_color"
    android:value="red" />

С помощью дополнительного параметра приложение может определить, какой из этих вариантов установлен:

val color = watchFaceDetails
    .getMetaData("com.myapp.watchfacepush.mywatchface.default_color")
    .invoke()
Log.i(TAG, "Default color: $color")

Что нужно учесть

При реализации функции Watch Face Push в приложении важно учитывать энергопотребление, кеширование, обновление встроенных циферблатов и предоставление репрезентативного циферблата по умолчанию.

Питание

При разработке приложений для Wear OS важно учитывать энергопотребление. Для компонента Wear OS приложения из каталога Marketplace:

  1. Приложение должно работать как можно реже и как можно меньше (если пользователь не взаимодействует с ним напрямую). например:
    • Минимизация пробуждения приложения из приложения "Телефон"
    • Как свести к минимуму выполнение заданий WorkManager
  2. Настройте расписание для отчетов Аналитики на время зарядки часов.
    1. Если вы хотите сообщать статистику использования из приложения для Wear OS или другие показатели, используйте WorkManager с ограничением requiresCharging.
  3. Настройте расписание обновлений, чтобы они выполнялись, когда часы заряжаются и подключены к Wi-Fi.
    1. Вы можете проверить версии установленных циферблатов и настроить их автоматическое обновление. Для requiresNetworkType снова используйте ограничение requiresCharging и тип сети UNMETERED.
    2. Когда устройство заряжается, оно, скорее всего, подключено к Wi-Fi. Запросите Wi-Fi, чтобы быстро скачать обновленные APK-файлы, и отключитесь от сети, когда все будет готово.
    3. Это же правило действует, если в магазине предлагается циферблат дня. Загрузите его, пока часы заряжаются.
  4. Не планируйте задачи для проверки активного циферблата:
    1. Периодическая проверка того, какой циферблат активен на торговой площадке, и какой именно это циферблат, приводит к разрядке батареи. Не используйте этот подход.
  5. Не использовать уведомления на часах:
    1. Если ваше приложение использует уведомления, настройте их так, чтобы они приходили на телефон. В этом случае пользователь сможет нажать на уведомление и продолжить работу в приложении на телефоне. Настройте уведомления так, чтобы они не передавались в приложение для часов, с помощью setLocalOnly.

Кеширование

В примере с канонической торговой площадкой циферблаты передаются с телефона на часы. Обычно это подключение по Bluetooth, которое может быть довольно медленным.

Чтобы улучшить взаимодействие с пользователем и сэкономить энергию, необходимую для повторной передачи данных, рекомендуем реализовать на устройстве Wear OS небольшой кеш для хранения нескольких APK-файлов.

Если пользователь попробует другой циферблат, а затем решит вернуться к предыдущему, это произойдет практически мгновенно.

Аналогичным образом можно предварительно загружать циферблат дня или другие циферблаты, пока устройство Wear OS заряжается.

Как обновить встроенные циферблаты

В приложении может быть объект циферблата по умолчанию, как описано выше. Обратите внимание, что циферблат устанавливается в систему при установке приложения, но не обновляется, если более новая версия входит в состав обновления приложения.

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

Представительский циферблат по умолчанию

Циферблат по умолчанию – отличный способ привлечь внимание пользователей к вашему магазину приложений. Он устанавливается вместе с магазином, поэтому его можно найти в галерее циферблатов.

При работе со стандартными циферблатами учитывайте следующее:

  • Не используйте removeWatchFace, если пользователь решил удалить циферблат из вашего приложения. В этом случае верните циферблат по умолчанию с помощью updateWatchFace. Это поможет пользователям найти ваш циферблат и установить его из галереи.
  • Сделайте циферблат по умолчанию простым и узнаваемым, используя логотип и фирменные цвета. Это поможет пользователям найти его в галерее циферблатов.
  • Добавьте на стандартный циферблат кнопку, чтобы открывать приложение "Телефон". Это можно сделать в два этапа:

    1. Добавьте на циферблат элемент Launch, чтобы запускать намерение с помощью приложения для Wear OS, например:

      <Launch target="com.myapp/com.myapp.LaunchOnPhoneActivity" />

    2. В LaunchOnPhoneActivity запустите приложение "Телефон", используя сочетание клавиш RemoteActivityHelper.