配置 Wear OS 应用以实现表盘推送

借助表盘推送功能,您的应用可以管理 Wear OS 设备上的表盘。这包括添加、更新和移除表盘主题,以及设置当前表盘主题。将 Wear OS 应用配置为使用 Watch Face Push API。

设置

添加必要的依赖项:

implementation("androidx.wear.watchface:watchface-push:1.3.0-alpha07")

将以下内容添加到 AndroidManifest.xml 中:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

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

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

</manifest>

获取对 manager 实例的引用

获取 WatchFacePushManager 的实例:

val manager = WatchFacePushManager(context)

WatchFacePushManager 提供对与表盘推送交互的所有方法的访问权限。

使用槽

使用表盘推送时,一个关键概念是。槽是用于寻址应用所属已安装表盘的方法。系统会设置购物平台可拥有的槽数上限;在 Wear OS 6 中,此上限为 1。

更新或移除表盘时,slotId 用于标识要执行操作的表盘。

列表表盘

如需列出已安装的表盘集,请使用 listWatchFaces()

val response = watchFacePushManager.listWatchFaces()
val installedList = response.installedWatchFaceDetails
val remainingSlots = response.remainingSlots

这样,您就可以确定该槽位是否可用,或者添加其他表盘是否需要替换现有表盘。该列表还会显示已安装表盘的详细信息。例如,如需检查是否安装了给定表盘软件包,请执行以下操作:

suspend fun isInstalled(packageName: String) = watchFacePush.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: AddWatchFaceException) {
    // Something went wrong adding the watch face.
}

更新表盘

更新表盘主题后,您可以将给定槽位的内容替换为新软件包。这可以是将同一表盘升级到较新版本,也可以是将表盘完全替换为其他表盘。

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

try {
    watchFacePushManager.updateWatchFace(slotId, redParcelFileDesc, redValidationToken)
} catch (e: UpdateWatchFaceException) {
    // Something went wrong updating the watch face.
}

移除表盘主题

如需移除表盘,请执行以下操作:

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

try {
    watchFacePushManager.removeWatchFace(slotId)
} catch (e: RemoveWatchFaceException) {
    // Something went wrong removing the watch face.
}

这样可以确保您的表盘主题始终可在系统表盘选择器中找到,可以醒目地显示您的徽标,甚至可以显示用于在手机上启动您的 Marketplace 应用的按钮。

检查表盘是否处于活动状态

确定您的购物平台是否已设置当前表盘主题对于确保用户获得顺畅的体验至关重要:如果购物平台已设置当前表盘主题,那么如果用户希望选择其他表盘主题,只需通过购物平台应用替换当前表盘主题即可生效。不过,如果购物平台未设置活跃表盘,手机应用必须向用户提供更多指导。如需详细了解如何处理此用户体验,请参阅有关电话应用的部分。

如需确定购物平台是否设置了当前表盘主题,请执行以下操作:

提供默认表盘

借助表盘推送功能,您可以在用户安装您的购物平台应用时安装默认表盘。这本身不会将该默认表盘设置为活动表盘(请参阅设置活动表盘),但会确保您的表盘在系统表盘选择器中可用。

若要使用该功能:

  1. 在 Wear OS 应用 build 中,将默认表盘添加到路径中:assets/default_watchface.apk
  2. 将以下条目添加到 AndroidManifest.xml

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

设置当前表盘主题

表盘推送可让购物平台应用设置当前表盘。

具体而言,这意味着,如果当前处于活动状态的表盘不属于购物平台,应用可以将其设为属于购物平台的表盘。请注意,如果购物平台已有当前表盘,则通过调用 updateWatchFace 将其更改为其他表盘,以便将表盘槽的内容替换为其他表盘。

设置当前表盘主题分为两个阶段:

  1. 获取设置当前表盘所需的 Android 权限。
  2. 调用 setWatchFaceAsActive 方法。

获取设置当前表盘主题的权限

所需权限为 SET_PUSHED_WATCH_FACE_AS_ACTIVE,必须添加到清单中:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    ...
    <uses-permission android:name="com.google.wear.permission.SET_PUSHED_WATCH_FACE_AS_ACTIVE" />
</manifest>

由于这是一项运行时权限,因此您的应用必须在运行时向用户请求此权限(不妨考虑使用 Accompanist 库来帮助实现此目的)。

将表盘主题设为当前表盘主题

授予权限后,对应应处于活动状态的表盘的槽 ID 调用 setWatchFaceAsActive

watchFacePushManager.setWatchFaceAsActive(slotId)

使用此方法后,您的手机应用应改为提供有关如何手动设置活动表盘的指导。

从表盘 APK 读取其他元数据

WatchFaceSlot 对象还提供了获取您可以在表盘上声明的其他信息的方法。

这在您有同一表盘的细微变体的情况下尤其有用。例如,您可以定义一个表盘:

  • 软件包名称:com.myapp.watchfacepush.mywatchface
  • 软件包版本:1.0.0

不过,此表盘可能分为四个不同的 APK,它们几乎完全相同,但具有不同的默认颜色:红色、黄色、绿色蓝色,这些颜色是在表盘格式 XML 中的 ColorConfiguration 中设置的。

然后,这项细微的变化会反映在 4 个 APK 中:

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

使用自定义属性可让您的应用确定已安装哪个变体:

watchFaceDetails
    .getMetaDataValues("com.myapp.watchfacepush.mywatchface.default_color")
    .invoke()

注意事项

在应用中实现表盘推送时,需要注意以下重要事项,包括关注功耗、缓存、更新捆绑的表盘,以及提供代表性默认表盘。

电源

任何在 Wear OS 上运行的应用都需要考虑耗电量。对于购物平台应用的 Wear OS 组件:

  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 桥接到手表应用。

缓存

在规范的购物平台示例中,表盘会从手机传输到手表。此连接通常是蓝牙连接,速度可能非常慢。

为了提供更好的用户体验并节省重新传输功耗,不妨考虑在 Wear OS 设备中实现小型缓存来存储少量 APK。

如果用户尝试了其他表盘,但随后决定恢复到之前选择的表盘,则此操作几乎是即时的。

同样,这也可以用于预缓存今日表盘或类似方案(在 Wear OS 设备充电时下载表盘)。

更新捆绑的表盘

您的应用可以包含默认表盘资源(如前所述)。请务必注意,虽然此表盘会在安装您的购物平台应用时安装到系统中,但如果购物平台应用的任何更新中捆绑了较新版本,表盘不会更新。

如需处理这种情况,您的购物平台应用应监听 MY_PACKAGE_REPLACED 广播操作,并检查是否需要更新文件包资源中的任何捆绑表盘。

代表性的默认表盘

默认表盘是帮助用户发现和使用您的购物平台的绝佳方式:表盘会在您的购物平台安装时一并安装,以便用户在表盘图库中找到它。

使用默认表盘时,请注意以下几点:

  • 如果用户选择从您的购物平台应用中卸载表盘,请勿使用 removeWatchFace。在这种情况下,请改用 updateWatchFace 将表盘还原为默认表盘。这有助于用户在图库中找到您的表盘并进行设置。
  • 通过徽标和主题设置,让默认表盘简单易用且一目了然。这有助于用户在表盘库中找到它。
  • 向默认表盘添加一个按钮,用于打开“电话”应用。这可分两个阶段完成:

    1. 向表盘添加 Launch 元素,以使用 Wear OS 应用启动 intent,例如:

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

    2. LaunchOnPhoneActivity 中,使用 RemoteActivityHelper 启动电话应用。