向 Wear OS 上的表盘复杂功能提供数据

1. 向复杂功能提供数据

在此 Codelab 中,您将学习如何构建复杂功能数据源。

概念和设置

在此 Codelab 结束时,您将了解如何向 Wear OS 上的表盘复杂功能提供数据。

概念

复杂功能是表盘上除小时和分钟之外的功能。例如,下图中的表盘就包含四个复杂功能。

39f4ebe8dc4800b0.png

Complications API 既适用于表盘,也适用于数据源应用:

  • 复杂功能数据源会提供数据,例如电池电量、天气、步数等
  • 表盘开发者可以在其表盘上显示复杂功能中的相关数据
  • 用户选择想要用于复杂功能的数据源

Screen Shot 2016-05-17 at 5.14.50 PM.png

在此 Codelab 中,我们将介绍如何创建复杂功能数据源。如果您还有兴趣为表盘添加复杂功能,请参阅我们提供的表盘示例

立即开始吧!

克隆初始项目代码库

为了帮助您快速上手,我们准备了一个项目,供您在此基础上进行构建,其中包含此 Codelab 所需的一些基本代码和应用设置。

如果您已安装 Git,请运行以下命令(可在终端/命令行中输入 git --version 来检查是否已安装 Git,并验证其是否正确执行):

 git clone https://github.com/android/codelab-complications-data-source.git

如果您未安装 Git,可以下载包含项目代码的 ZIP 文件:

导入项目

启动 Android Studio,然后在欢迎屏幕中选择“Open an existing Android Studio project”。打开项目目录,然后在 complications-data-source 目录中双击 build.gradle 文件。

如果您处于 Android 视图,那么在项目窗口的左上角应该会看到类似以下屏幕截图所示的一组文件夹图标。(如果您处于 Project 视图,那么展开 complications-data-source 项目才能看到这组文件夹图标。)

786caabc75caee70.png

您可以看到两个文件夹图标。两者都代表模块。请注意,首次打开项目时,Android Studio 可能需要数秒时间在后台编译项目。在此期间,您会在 Android Studio 底部的状态栏中看到一个旋转图标:

27f04b5598a2f95e.png

请等到进程完成后再更改代码,以便 Android Studio 拉取所有必要的组件。

了解初始项目

您已经完成准备工作,可以开始向复杂功能提供数据了。我们将从 base 模块开始。您将在每个步骤向 base 中添加代码。

在此 Codelab 中,您可参照 complete 模块来检查自己的开发工作(如果遇到问题,也可参考此模块)。

数据源关键组件概览

  • ComplicationTapBroadcastReceiver:用于通过 PendingIntent 更新复杂功能数据的类。
  • CustomComplicationDataSourceService:用于向复杂功能提供数据的类。该文件位于 base/java/com/example/android/wearable/complicationsdatasource 目录中。在 Android Studio 中,它位于 base/java/com.example.android.wearable.complicationsdatasource 下。在该类中,我们将主要创建四个方法:
  • onComplicationActivated:在使用您的数据激活复杂功能时调用。
  • getPreviewData:在编辑器界面中预览所用复杂功能的数据(通常只是静态内容)。
  • onComplicationRequest:我们的大部分开发工作都将涉及该方法。每当处于活动状态的复杂功能需要从您的来源更新数据时,系统就会调用此方法。
  • onComplicationDeactivated:在复杂功能停用时调用。

模拟器设置

如果您在设置 Wear OS 模拟器时需要帮助,请参阅“创建和运行穿戴式应用”页面上的启动模拟器并运行 Wear 应用部分。

运行初始项目

让我们在手表上运行该应用。

  • 连接 Wear OS 设备或启动模拟器。
  • 在工具栏中,从下拉菜单中选择“base”配置,然后点击旁边的绿色三角形(运行)按钮:

a04699aa4cf2ca12.png

  • 如果您收到一个类似如下所示的错误 (Error Launching activity),请更改默认的启动 Activity(具体说明如下)。6ea74bcba8278349.png

相反,如果系统在启动应用时提示使用 Activity,请选择 Do not launch Activity

  • 如需更改默认的启动 Activity(必要时,从上一步开始),点击绿色箭头左侧的下拉选择器,然后点击 Edit Configurations

1e3e1dc73655ccd8.png

选择 base,您随即会看到一个类似如下所示的窗口。选择 Launch Options 部分下的 Nothing,然后点击“Run”。以后,如果您想要尝试启动另一个模块,也需要执行此操作。

5e98572969d8228.png

  • 选择您的 Android 设备或模拟器,然后点击“OK”。系统将会在 Wear OS 设备或模拟器上安装相应服务。
  • 几秒钟后,您的服务即已构建并可以部署了。您会在 Android Studio 底部的状态栏中看到一个旋转图标。
  • 如果您还没有在 Android Studio 左下角的 Build 标签页中看到旋转图标,请选择该标签页,然后您就可以看到安装进度了。在安装进程结束时,您应该会看到如下消息:Build: completed

5ea92276833c0446.png

  • 选择能让您选择复杂功能的表盘。在我们的例子中,我们选择了 Elements Digital。不过,您的手表可能未提供此表盘。

a5cf2c605206efe2.png

请注意,由于这是您第一次运行这个表盘,因此您需要从“Add more watch faces”中选择该表盘。选择一次后,它便会以选项的形式随此选项一起显示。

  • 现在,您选择的表盘应该会出现在“Favorite”菜单的中心位置(见下图)。请点击底部的齿轮图标。

f17fb6b4cfe06182.png

  • 对于此表盘,您应选择 Data。对于您在使用的自定义表盘,界面可能会有所不同。

aef4fca32751a15a.png

  • 选择任意位置,即任意 +(复杂功能)。

461f8a704fbc6496.png

  • 最后,向下滚动并选择 Complications Data Source Codelab 服务。(选择该服务后,您可能需要向左滑动几次或用手掌盖住设备才能退出)。

b4d0d14140ce0120.png

  • 在您的输出中,您应该会看到“onComplicationActivated()”和“onComplicationRequest ()”这两条日志消息(尽管在复杂功能所在位置中不会显示任何内容)。
  • 如果您没有看到日志消息,请按工具栏中的绿色三角形按钮,尝试重新部署表盘。
  • 如果您不熟悉如何查看 Log 数据,请点击 Android Studio 底部被标记为 6: Logcat 的标签页。将下拉菜单设置为您的设备/模拟器和软件包名称 com.example.android.wearable.complicationsdatasource(如下方屏幕截图所示)。

af9cf164f9c598fc.png

“但是等一下!我选择的数据槽里没有显示任何内容!”不用担心,我们还没有提供任何数据。我们将在接下来的步骤中添加数据。

在某些手表上,Elements 表盘已启用复杂功能,因此您可能会在手表上看到填充了内容的复杂功能。此外,如果您的模拟器上显示带删除线的云朵,而不是飞机图标,您也不必担心。此 Codelab 不需要连接到手机或互联网。

52da39817e329e7a.png

总结

在此步骤中,您学习了以下内容:

  • Wear OS 以及向复杂功能提供数据背后的概念
  • 关于参考起点(base 模块)的基础知识
  • 部署并运行表盘

后续步骤

让我们开始提供一些数据。

2. 提供 Short Text 数据

代码步骤 2

在此步骤中,我们将开始提供数据。复杂功能接受多种类型的数据。在此步骤中,我们将返回 Short Text 数据类型。

如果您对此处讨论的概念感到困惑,请参阅 complete 模块,了解如何实施这些步骤。

指定数据源支持的数据类型

打开 AndroidManifest.xml 文件,然后查看 CustomComplicationDataSourceService 服务。请注意 intent 过滤器:

<action android:name=
    "android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST"/>

这会告知系统,您的服务会扩展 ComplicationDataSourceServiceSuspendingComplicationDataSourceService(支持 Kotlin 协程的变体),并且可以为复杂功能发送数据。

接下来是用于指定我们所支持数据类型的 meta-data 元素。在本例中,我们支持 SMALL_IMAGE,但在这一步,请将其更改为 SHORT_TEXT。将第一个 meta-data 元素更改为以下内容:

<meta-data
    android:name="android.support.wearable.complications.SUPPORTED_TYPES"
    android:value="SHORT_TEXT"/>

提供数据

如前所述,启用数据源时会调用 onComplicationActivated()。此时非常适合执行在每次启用时需要完成的基本设置。在此 Codelab 中,我们并未执行上述操作,因为我们的示例相对简单。

处于活动状态的复杂功能会在 onComplicationRequest() 调用中请求更新后的数据。

触发 onComplicationRequest() 方法的原因多种多样:

  • 处于活动状态的表盘复杂功能更改为使用此来源
  • 使用此来源的复杂功能变为活动状态
  • 您通过 ComplicationDataSourceUpdateRequester.requestUpdate()ComplicationDataSourceUpdateRequester.requestUpdateAll()自己的类中触发了更新
  • 您在清单中指定的时间段已过

打开 CustomComplicationDataSourceService .kt 并将光标向下移动到 onComplicationRequest() 方法。删除“return null”代码行,然后复制以下代码并将其粘贴到初始 Log.d() 调用下:

// Retrieves your data, in this case, we grab an incrementing number from Datastore.
val number: Int = applicationContext.dataStore.data
    .map { preferences ->
        preferences[TAP_COUNTER_PREF_KEY] ?: 0
    }
    .first()

val numberText = String.format(Locale.getDefault(), "%d!", number)

在本例中,我们将从代表数据的 DataStore 中检索存储的 int。通过调用您的数据库即可轻松实现这一目的。

为了与 DataStore 进行交互,您将需要一个对它生成的 Flow 进行收集的协程。您可能会注意到,onComplicationRequest() 是一个 suspend 函数,因此我们可以通过 Flow 收集数据,而无需专门启动协程。

检索到整数值后,我们便会将这个值转换为简单字符串,以便为将其转换为 ComplicationData 对象(即复杂功能可以理解的数据类型)做准备。

接下来,复制代码并将其粘贴到您刚刚添加的代码下方。

return when (request.complicationType) {

    ComplicationType.SHORT_TEXT -> ShortTextComplicationData.Builder(
        text = PlainComplicationText.Builder(text = numberText).build(),
        contentDescription = PlainComplicationText
            .Builder(text = "Short Text version of Number.").build()
    )
        .build()

    else -> {
        if (Log.isLoggable(TAG, Log.WARN)) {
            Log.w(TAG, "Unexpected complication type ${request.complicationType}")
        }
        null
    }
}

在此代码中,我们将根据复杂功能类型返回 ComplicationData 对象,也就是说,我们将为数据类型 SHORT_TEXT 返回 ShortTextComplicationDataComplicationData 的子类)。

给定的数据类型可能包含不同的字段。例如,SHORT_TEXT 可能只是一段文字,也可能是标题和文字,或者是单色图片和文字(均应包含内容说明,以实现无障碍功能)。

在我们的示例中,我们只设置必需字段,而不设置可选字段。如需详细了解这些类型和字段,请参阅我们的文档

您可能会想知道,我们为什么使用 when 语句来创建数据。在后面的步骤中,我们将根据系统请求的类型支持不同格式的数据。如果现在使用 when 语句,我们以后便可以轻松地添加新的数据类型(LONG_TEXTRANGED_VALUE 等)。

最后,如果我们不支持该数据类型,则会返回 null。

最终的方法应如下所示:

override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationData? {
    Log.d(TAG, "onComplicationRequest() id: ${request.complicationInstanceId}")

    // Retrieves your data, in this case, we grab an incrementing number from Datastore.
    val number: Int = applicationContext.dataStore.data
        .map { preferences ->
            preferences[TAP_COUNTER_PREF_KEY] ?: 0
        }
        .first()

    val numberText = String.format(Locale.getDefault(), "%d!", number)

    return when (request.complicationType) {

        ComplicationType.SHORT_TEXT -> ShortTextComplicationData.Builder(
            text = PlainComplicationText.Builder(text = numberText).build(),
            contentDescription = PlainComplicationText
                .Builder(text = "Short Text version of Number.").build()
        )
            .build()

        else -> {
            if (Log.isLoggable(TAG, Log.WARN)) {
                Log.w(TAG, "Unexpected complication type ${request.complicationType}")
            }
            null
        }
    }
}

再次运行应用

在第一步中,您学习了如何在设备或模拟器上安装复杂功能数据服务。现在,让我们再来一次!安装您的应用并重新选择复杂功能,也就是滑动表盘,选择齿轮图标,转到同一复杂功能,然后选择 Complications Data Source Codelab。您应该会看到类似下图的内容:

caae484f1f2508fd.png

总结

在这一步骤中,您学到了以下内容:

  • 如何指定来源可以支持的数据类型
  • 当处于活动状态的复杂功能在使用数据时,该多久请求一次数据
  • 在哪里向 Wear OS 提供数据

后续步骤

我们来试试支持其他数据类型。

3. 触发复杂功能数据更新

代码步骤 3

在此步骤中,我们将在用户点按复杂功能时触发数据更新。

如果您对此处讨论的概念感到困惑,请参阅 complete 模块,了解如何实施这些步骤。

指定复杂功能刷新数据的频率

打开 AndroidManifest.xml 文件,然后再次查看 CustomComplicationDataSourceService 服务。

请注意 meta-data 元素中的 UPDATE_PERIOD_SECONDS 字段。此字段用于指定您希望在数据源处于活动状态时系统检查数据更新的频率。

目前,该字段设置为 600 秒(即 10 分钟)。我们希望更新复杂功能来响应用户操作,因此需要提高更新频率。尽管我们可以缩短这个周期,但如果时间不到几分钟,系统可能无法触发更新。

更好的方法是采用“推送形式”,指示系统正好在数据发生变化时更新。

将更新频率从 600 更改为 0,即表示在数据发生变化时直接 ping 系统,而不依赖于定期更新。请注意,元数据是必需的。

<meta-data
    android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
    android:value="0"/>

告知系统有新的可用复杂功能数据

打开 ComplicationTapBroadcastReceiver.kt。这个 BroadcastReceiver 类会在触发时更新复杂功能数据。(请注意,我们只会将数据保存到 DataStore。)

该类还提供了用于构造 PendingIntent 的辅助方法(作为 BroadcastReceiver 来触发)。

现在,onReceive() 方法从 intent 中提取数据源和复杂功能 ID,并更新 DataStore 中的整数。我们需要告知复杂功能数据已更新。

移至 onReceive() 方法的底部。在最后一个代码块上方,您应该会看到注释“Request an update for the...”复制代码并将其粘贴到该注释的下方。

// Request an update for the complication that has just been tapped, that is,
// the system call onComplicationUpdate on the specified complication data
// source.
val complicationDataSourceUpdateRequester =
    ComplicationDataSourceUpdateRequester.create(
        context = context,
        complicationDataSourceComponent = dataSource
    )
complicationDataSourceUpdateRequester.requestUpdate(complicationId)

该代码会告知 Wear OS 复杂功能的数据已更新。为此,我们需要以下三项数据:

  • context - Context 可用作 onReceive() 方法的参数。
  • complicationDataSourceComponent - 复杂功能的 DataSource 会作为 ExtraBroadcastReceiver 中传入,从而触发此 PendingIntent
  • complicationId - 表盘为复杂功能所在位置分配的唯一整数。int 会作为 ExtraPendingIntent 中传入,从而触发此 BroadcastReceiver

这一步就完成了,您的最终方法应如下所示:

override fun onReceive(context: Context, intent: Intent) {

    // Retrieve complication values from Intent's extras.
    val extras = intent.extras ?: return
    val dataSource = extras.getParcelable<ComponentName>(EXTRA_DATA_SOURCE_COMPONENT) ?: return
    val complicationId = extras.getInt(EXTRA_COMPLICATION_ID)

    // Required when using async code in onReceive().
    val result = goAsync()

    // Launches coroutine to update the DataStore counter value.
    scope.launch {
        try {
            context.dataStore.edit { preferences ->
                val currentValue = preferences[TAP_COUNTER_PREF_KEY] ?: 0

                // Update data for complication.
                val newValue = (currentValue + 1) % MAX_NUMBER

                preferences[TAP_COUNTER_PREF_KEY] = newValue
            }

            // Request an update for the complication that has just been tapped, that is,
            // the system call onComplicationUpdate on the specified complication data
            // source.
            val complicationDataSourceUpdateRequester =
                ComplicationDataSourceUpdateRequester.create(
                    context = context,
                    complicationDataSourceComponent = dataSource
                )
            complicationDataSourceUpdateRequester.requestUpdate(complicationId)
        } finally {
            // Always call finish, even if cancelled
            result.finish()
        }
    }
}

向复杂功能添加点按操作

我们的 BroadcastReceiver 不仅会更新数据,还会告知系统有新数据可用(请参见上一步)。我们需要为复杂功能添加点按操作来触发 BroadcastReceiver

打开 CustomComplicationDataSourceService.kt,然后向下移至 onComplicationRequest() 方法。

在第一个 Log.d() 语句与从 DataStore 中检索到的整数之间,复制并粘贴以下代码:

// Create Tap Action so that the user can trigger an update by tapping the complication.
val thisDataSource = ComponentName(this, javaClass)
// We pass the complication id, so we can only update the specific complication tapped.
val complicationPendingIntent =
    ComplicationTapBroadcastReceiver.getToggleIntent(
        this,
        thisDataSource,
        request.complicationInstanceId
    )

记得在上一步中,我们需要这两个数据(数据源和复杂功能 ID)才能让 BroadcastReceiver 正常运行。在此处,我们将两者作为 Extra 从 PendingIntent 进行传入。

接下来,我们需要将 PendingIntent 分配给复杂功能的点按事件。

找到 ST 的 when 语句,然后在 .build() 调用上方添加下面这行代码。

    .setTapAction(complicationPendingIntent)

代码块现在应如下所示:

ComplicationType.SHORT_TEXT -> ShortTextComplicationData.Builder(
    text = PlainComplicationText.Builder(text = numberText).build(),
    contentDescription = PlainComplicationText
        .Builder(text = "Short Text version of Number.").build()
)
    .setTapAction(complicationPendingIntent)
    .build()

这仅添加了一行,即 .setTapAction() 方法。该方法会将新的 PendingIntent 分配给复杂功能的点按操作。

这一步就完成了。最终的方法应如下所示:

override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationData? {
    Log.d(TAG, "onComplicationRequest() id: ${request.complicationInstanceId}")

    // Create Tap Action so that the user can trigger an update by tapping the complication.
    val thisDataSource = ComponentName(this, javaClass)
    // We pass the complication id, so we can only update the specific complication tapped.
    val complicationPendingIntent =
        ComplicationTapBroadcastReceiver.getToggleIntent(
            this,
            thisDataSource,
            request.complicationInstanceId
        )

    // Retrieves your data, in this case, we grab an incrementing number from Datastore.
    val number: Int = applicationContext.dataStore.data
        .map { preferences ->
            preferences[TAP_COUNTER_PREF_KEY] ?: 0
        }
        .first()

    val numberText = String.format(Locale.getDefault(), "%d!", number)

    return when (request.complicationType) {

        ComplicationType.SHORT_TEXT -> ShortTextComplicationData.Builder(
            text = PlainComplicationText.Builder(text = numberText).build(),
            contentDescription = PlainComplicationText
                .Builder(text = "Short Text version of Number.").build()
        )
            .setTapAction(complicationPendingIntent)
            .build()

        else -> {
            if (Log.isLoggable(TAG, Log.WARN)) {
                Log.w(TAG, "Unexpected complication type ${request.complicationType}")
            }
            null
        }
    }
}

再次运行应用

安装您的应用并重新选择复杂功能,也就是滑动表盘,选择齿轮图标,转到同一复杂功能,然后选择 Complications Data Source Codelab 来源。您应该会看到与之前相同的内容。不过,现在您可以点按复杂功能来更新数据。

a9d767e37161e609.png

总结

在这一步骤中,您学到了以下内容:

  • 如何通知系统您的复杂功能数据已更新
  • 如何将 PendingIntent 与复杂功能的点按操作相关联

后续步骤

我们来试试支持其他数据类型。

4. 提供 Long Text 数据

代码步骤 4

在向复杂功能提供数据时,建议您支持更多类型的数据,并查看不同类型的数据在复杂功能中的显示效果。

指定其他受支持的数据类型

再次打开 AndroidManifest.xml 文件,然后查看 CustomComplicationDataSourceService 服务的声明。

SUPPORTED_TYPES 这个 meta-data 元素从 SHORT_TEXT 更改为 LONG_TEXT。您的更改应如下所示:

<meta-data
    android:name="android.support.wearable.complications.SUPPORTED_TYPES"
    android:value="LONG_TEXT"/>

添加对 LONG TEXT 的支持

打开 CustomComplicationDataSourceService.kt,向下移至 onComplicationRequest() 方法中的 when 语句,然后在 TYPE_SHORT_TEXT case 的末尾和默认 case 之间添加以下代码。

ComplicationType.LONG_TEXT -> LongTextComplicationData.Builder(
    text = PlainComplicationText.Builder(text = "Number: $numberText").build(),
    contentDescription = PlainComplicationText
        .Builder(text = "Long Text version of Number.").build()
)
    .setTapAction(complicationPendingIntent)
    .build()

when 语句应如下所示:

return when (request.complicationType) {

    ComplicationType.SHORT_TEXT -> ShortTextComplicationData.Builder(
        text = PlainComplicationText.Builder(text = numberText).build(),
        contentDescription = PlainComplicationText
            .Builder(text = "Short Text version of Number.").build()
    )
        .setTapAction(complicationPendingIntent)
        .build()

    ComplicationType.LONG_TEXT -> LongTextComplicationData.Builder(
        text = PlainComplicationText.Builder(text = "Number: $numberText").build(),
        contentDescription = PlainComplicationText
            .Builder(text = "Long Text version of Number.").build()
    )
        .setTapAction(complicationPendingIntent)
        .build()

    else -> {
        if (Log.isLoggable(TAG, Log.WARN)) {
            Log.w(TAG, "Unexpected complication type ${request.complicationType}")
        }
        null
    }
}

您可能已经注意到,我们只是以新的格式重新打包了相同的数据。我们来看看它是什么样的。

如何查看进度和调试

安装您的服务,但这次先选择底槽复杂功能,然后再选择复杂功能服务来源:

518b646d3c3f3305.png

您应该会看到类似下图的内容。请注意,每个复杂功能都存储在不同的键中,因此如果您在多个位置设置复杂功能,可能会看到不同的值:

17ec0506f1412676.png

总结

在此步骤中,您学习了以下内容:

  • 如何更改和支持不同的复杂功能数据类型

后续步骤

在组合到一起之前,我们希望支持一种额外的数据类型。

5. 提供 Ranged Text 数据

代码步骤 5

在向复杂功能提供数据的同时,让我们继续探索如何支持更多类型的数据。

指定其他受支持的数据类型

再次打开 AndroidManifest.xml 文件,然后查看 CustomComplicationDataSourceService 服务。

SUPPORTED_TYPES 这个 meta-data 元素更改为 RANGED_VALUE。您的更改应如下所示:

<meta-data
    android:name="android.support.wearable.complications.SUPPORTED_TYPES"
    android:value="RANGED_VALUE"/>

添加对范围值的支持

范围值不仅可以显示文本,还能直观地显示您的值与最小值/最大值之间的差距。对于显示设备剩余电池电量或您为达成目标而剩余的步数,此类复杂功能非常有用。

1fe1943a5ad29076.png

打开 CustomComplicationDataSourceService .kt,将光标向下移至 onComplicationRequest() 方法中的 when 语句,然后在 TYPE_LONG_TEXT case 和默认 case 之间添加以下代码:

ComplicationType.RANGED_VALUE -> RangedValueComplicationData.Builder(
    value = number.toFloat(),
    min = 0f,
    max = ComplicationTapBroadcastReceiver.MAX_NUMBER.toFloat(),
    contentDescription = PlainComplicationText
        .Builder(text = "Ranged Value version of Number.").build()
)
    .setText(PlainComplicationText.Builder(text = numberText).build())
    .setTapAction(complicationPendingIntent)
    .build()

您的 when 语句应如下所示:

return when (request.complicationType) {

    ComplicationType.SHORT_TEXT -> ShortTextComplicationData.Builder(
        text = PlainComplicationText.Builder(text = numberText).build(),
        contentDescription = PlainComplicationText
            .Builder(text = "Short Text version of Number.").build()
    )
        .setTapAction(complicationPendingIntent)
        .build()

    ComplicationType.LONG_TEXT -> LongTextComplicationData.Builder(
        text = PlainComplicationText.Builder(text = "Number: $numberText").build(),
        contentDescription = PlainComplicationText
            .Builder(text = "Long Text version of Number.").build()
    )
        .setTapAction(complicationPendingIntent)
        .build()

    ComplicationType.RANGED_VALUE -> RangedValueComplicationData.Builder(
        value = number.toFloat(),
        min = 0f,
        max = ComplicationTapBroadcastReceiver.MAX_NUMBER.toFloat(),
        contentDescription = PlainComplicationText
            .Builder(text = "Ranged Value version of Number.").build()
    )
        .setText(PlainComplicationText.Builder(text = numberText).build())
        .setTapAction(complicationPendingIntent)
        .build()

    else -> {
        if (Log.isLoggable(TAG, Log.WARN)) {
            Log.w(TAG, "Unexpected complication type ${request.complicationType}")
        }
        null
    }
}

再次强调一下,我们只是以新的格式重新打包了相同的数据。我们来看看它是什么样的。

如何查看进度和调试

安装您的服务,然后选择其他位置。

461f8a704fbc6496.png

现在,您应该会看到如下内容:

ffa6ea8f2ed3eb2a.png

您可以看到一个以数字为中心的圆圈,其中突出显示了该圆圈 3/20 的部分。

总结

在此步骤中,您学习了以下内容:

  • 如何更改和支持不同的复杂功能数据类型

后续步骤

我们将通过启用所有数据类型变体来结束此 Codelab。

6. 提供所有三种数据类型

代码步骤 6

我们的复杂功能数据源现在支持三种数据变体(即 RANGED_VALUE、SHORT_TEXTLONG_TEXT)。

在这最后一步中,我们会告知系统我们支持所有三种变体。

指定多个受支持的数据类型

再次打开 AndroidManifest.xml 文件,然后查看 CustomComplicationDataSourceService 服务。

SUPPORTED_TYPES 这个 meta-data 元素更改为 RANGED_VALUE,SHORT_TEXT,LONG_TEXT。现在,您的更改应如下所示:

<meta-data
    android:name="android.support.wearable.complications.SUPPORTED_TYPES"
    android:value="RANGED_VALUE,SHORT_TEXT,LONG_TEXT"/>

查看进度

安装服务。

b3a7c0c8063c2f60.png

在这种情况下,表盘会优先选择范围数据类型,而非短文本和长文本类型,但如果复杂功能仅支持短文本类型,那么数据仍会显示,因为表盘支持所有三种数据类型。请注意,表盘本身会指定复杂功能支持的数据类型以及这些类型的优先顺序。

总结

在此步骤中,您学习了以下内容:

  • 如何支持多个复杂功能数据类型

7. 大功告成!接下来做什么?

您可以在复杂功能中支持更多的数据类型(包括小图片、大图片和图标)。不妨自行实现其中的一些类型,对此 Codelab 进行扩展。

如需详细了解如何为表盘开发复杂功能以及如何创建复杂功能数据源,请参阅表盘复杂功能

如需详细了解如何开发 Wear OS 表盘,请访问 https://developer.android.com/training/wearables/watch-faces/index.html