为 Watch Face Push 配置 Wear OS 应用

通过 Watch Face Push,您的应用可以管理 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>

获取管理器实例的引用

获取 WatchFacePushManager 实例

val manager = WatchFacePushManager(context)

WatchFacePushManager 提供了与 Watch Face Push 交互的所有方法的访问权限。

使用槽位

使用 Watch Face Push 时的一个关键概念是 槽位。槽位是一种寻址属于您应用的已安装表盘的方式。系统会设置一个商店可以拥有的最大槽位数量;对于 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.
}

这可确保您的表盘始终可以在系统表盘选择器中找到,可以突出显示您的徽标,甚至可以提供一个按钮,用于在手机上启动您的商店应用。

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

确定您的商店是否已设置活动表盘对于确保用户获得流畅体验非常重要:如果商店已设置活动表盘,那么用户如果希望选择另一个表盘,只需通过商店应用替换当前表盘即可生效。但是,如果商店未设置活动表盘,手机应用必须向用户提供更多指导。如需详细了解如何处理此用户体验,请参阅手机应用部分。

要确定商店是否已设置活动表盘

提供默认表盘

Watch Face Push 提供了在安装您的商店应用时安装默认表盘的功能。这本身并不会将该默认表盘设为活动状态(请参阅设置活动表盘),但会确保您的表盘在系统表盘选择器中可用。

要使用此功能

  1. 在您的 Wear OS 应用构建中,将默认表盘包含在路径: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" />
    

设置活动表盘

Watch Face Push 提供了商店应用设置活动表盘的方法。

这具体意味着,如果当前活动表盘不属于商店,应用可以将活动表盘设置为属于商店的表盘。请注意,如果商店已拥有活动表盘,则通过调用 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 中设置的。

这种细微差异将反映在四个 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()

注意事项

在应用中实现 Watch Face Push 时,重要的注意事项包括关注功耗、缓存、更新捆绑的表盘以及提供一个有代表性的默认表盘。

功耗

对于在 Wear OS 上运行的任何应用而言,功耗都是一个关键的考虑因素。对于您的商店应用的 Wear OS 组件

  1. 您的应用应尽可能少地、不频繁地运行(除非用户直接与应用互动)。这包括
    • 最大程度地减少从手机应用唤醒应用
    • 最大程度地减少 WorkManager 作业的运行
  2. 将所有分析报告安排在手表充电时进行:
    1. 如果您想从 Wear OS 应用或其他任何指标报告使用统计信息,请将 WorkManager 与 requiresCharging 约束结合使用。
  3. 在手表充电时安排更新并利用 WLAN:
    1. 您可能想检查已安装表盘的版本并自动更新它们。同样,对于 requiresCharging 约束和 requiresNetworkType,请使用 UNMETERED 网络类型。
    2. 充电时,设备很可能可以访问 WLAN。请求 WLAN 以快速下载更新的 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 启动手机应用。