向表盘添加复杂功能

表盘复杂功能可显示来自数据提供程序的数据。利用 Complications API,表盘可以选择要用于获取基础数据的数据提供程序。这样一来,表盘不但可以显示时刻,还可以显示其他信息,而且无需通过代码来获取数据。

利用 Complications API,用户也可以自行选择数据提供程序。此外,Wear OS by Google 谷歌提供了一个用于选择数据源的界面

复杂功能

如需向表盘添加复杂功能,请执行以下操作:

设置表盘的默认提供程序

表盘可以指定在用户选择提供程序之前使用的默认提供程序。在 WatchFaceService.Engine 中使用 setDefaultComplicationProvider() 方法设置默认提供程序。此方法可以随时调用,但如果用户已经为给定的复杂功能选择相应提供程序,则此方法不会执行任何操作。

对于大多数提供程序而言,务必要在数据流入表盘之前向其授予 RECEIVE_COMPLICATION_DATA 权限。不过,部分系统提供程序是安全的,因为这些提供程序仅提供表盘已经可以自行获取的信息。安全的提供程序无需表盘获得发送数据的权限(参阅系统提供程序)。这些提供程序可优先用作默认选项,因为可以即时提供数据。

此外,如果一个表盘与某个提供程序具有合作关系,并希望将其用作默认提供程序,则该表盘可以请求该提供程序将其列为安全的表盘。

系统提供程序

系统包含可用作默认选项的提供程序。WatchFaceService.Engine 类中的 setDefaultSystemComplicationProvider() 方法可以为复杂功能设置默认的系统提供程序。该方法采用代表系统提供程序的 ID(整数形式)。可用 ID 列在 SystemProviders 类中。

下表包含关于部分受支持系统提供程序的详细信息:

SystemProviders 类中的方法名称 安全 可以是默认值 备注
dateProvider() 标准系统日期提供程序。点按将打开标准的“日程”应用。
currentTimeProvider() 标准系统“时间和日期”提供程序。无点按操作。
batteryProvider() 标准系统电池提供程序。无点按操作。
stepCountProvider() 根据 readDailyTotal 所提供的报告,显示每日总步数。
unreadCountProvider() 显示信息流中的未读通知数。
worldClockProvider() 将默认为伦敦或纽约。可以点按以更改时区。
appsProvider() 最初将显示“应用”图标,可以点按以选择应用。
nextEventProvider() 是(但不是安全提供程序) 标准系统“下一个活动”提供程序。点按将打开标准的“日程”应用。

允许用户选择数据提供程序

Wear OS(通过 Activity)提供了一个界面,使用户可以为特定的复杂功能选择提供程序。表盘可以调用 createProviderChooserHelperIntent 方法来获取可用于显示选择器界面的 intent。

在调用 createProviderChooserHelperIntent时,表盘将提供一个表盘复杂功能 ID 和一个受支持类型的列表。这些类型应当按照优先级顺序列示,提供更多信息的类型(例如范围值)通常具有更高的优先级。

在用户选择数据提供程序时,配置将自动保存;不需要表盘提供其他任何信息。

如需了解用于设置界面的功能完善的推荐代码,请参阅表盘示例应用

该推荐代码包含以下功能:

  • 用于复杂功能设置的标准界面。
  • 轻松访问其他设置。

查看该代码的起点是 AnalogComplicationConfigActivity 类,它具有 getDataToPopulateAdapter() 方法,此方法可以返回界面中可用设置条目的列表。

打开提供程序选择器

表盘必须拥有以下权限才可以接收复杂功能数据并打开提供程序选择器:

    com.google.android.wearable.permission.RECEIVE_COMPLICATION_DATA
    

未获得上述权限的表盘将无法启动提供程序选择器。

为简化请求权限和启动选择器的操作,穿戴式设备支持库中提供了 ComplicationHelperActivity 类。在几乎所有情况下,应使用此类而不是 ProviderChooserIntent 类来启动选择器。

请求必要权限

要使用 ComplicationHelperActivity,请将其添加到清单文件中的表盘中:

    <activity android:name="android.support.wearable.complications.ComplicationHelperActivity"/>
    

要启动提供程序选择器,请调用 ComplicationHelperActivity.createProviderChooserHelperIntent 方法来获取 intent。

可以将新 intent 与 startActivitystartActivityForResult 结合使用来启动选择器。

以下示例将新 Intent 与 startActivityForResult 结合使用:

Kotlin

    startActivityForResult(
            ComplicationHelperActivity.createProviderChooserHelperIntent(
                    activity,
                    watchFace,
                    complicationId,
                    ComplicationData.TYPE_LARGE_IMAGE
            ),
            PROVIDER_CHOOSER_REQUEST_CODE
    )
    

Java

    startActivityForResult(
      ComplicationHelperActivity.createProviderChooserHelperIntent(
         getActivity(),
         watchFace,
         complicationId,
         ComplicationData.TYPE_LARGE_IMAGE),
      PROVIDER_CHOOSER_REQUEST_CODE);
    

帮助程序 Activity 会在启动之后检查是否已授予权限。如果未授予权限,帮助程序 Activity 将发起一个运行时权限请求。如果权限请求被接受(或者不需要),将显示提供程序选择器。

如果将 startActivityForResult 与 Intent 结合使用,传回调用 Activity 的结果的代码将为 RESULT_OK(已成功设置提供程序)或 RESULT_CANCELLED(未设置提供程序)。

如果设置了提供程序,选定提供程序的 ComplicationProviderInfo 类将包含在结果的数据 Intent 中,作为一个带有 ProviderChooserIntent#EXTRA_PROVIDER_INFO 键的额外项。

接收复杂功能数据

为了开始接收复杂功能数据,表盘将通过一个表盘复杂功能 ID 列表在 WatchFaceService.Engine 类中调用 setActiveComplications()。表盘会创建这些 ID,对复杂功能可以在表盘上显示的位置进行唯一标识,并将这些 ID 传递至 createProviderChooserIntent() 方法以允许用户决定各个复杂功能的显示位置。复杂功能数据通过 onComplicationDataUpdate() 回调进行传递。

一般来说,表盘需要上述权限才能收到复杂功能数据,但也有一些例外情况。具体来说,只有满足以下某个条件,表盘才能接收来自提供程序的数据:

  • 相应提供程序是一个“安全”系统提供程序,
  • 相应提供程序和表盘来自于同一个应用,
  • 相应提供程序将相应表盘作为“安全”表盘列入白名单中,或者
  • 相应表盘拥有权限

原本提供程序会将 ComplicationData 发送到表盘,但如果以上条件都不满足,系统将改为发送 TYPE_NO_PERMISSION 类型的数据。此类型包括一个图标(感叹号)和短文本(“--”),以便将其作为短文本类型或图标类型进行渲染。

当表盘收到 TYPE_NO_PERMISSION 数据后,表盘应对数据进行相应渲染,以便用户可以看到使复杂功能正常运行需要执行的操作。如果可能,点按处于此状态下的复杂功能可发出权限请求。如果帮助程序 Activity 已添加到表盘应用中,可以使用 ComplicationHelperActivity.createPermissionRequestHelperIntent() 请求权限。

如果用户接受通过帮助程序 Activity 创建的权限请求,将自动为表盘上的所有活动复杂功能请求更新,允许 TYPE_NO_PERMISSION 数据被真实数据替换。

渲染复杂功能

只要预期字段得到表示,表盘就可能根据需要渲染数据;应始终包含必填字段。根据类型的不同,也应包含一些可选字段(请参阅下中的“备注”列)。

我们为自己的样式提供了设计指南,作为标准复杂功能的建议,不过开发者既可以使用他们自己的样式,也可以通过不同方式将数据整合到表盘中。

绘制复杂功能

您可以利用 ComplicationDrawable 类在画布上渲染整个复杂功能。

该类支持所有六个主要复杂功能类型,并为您执行以下操作:

  • 处理复杂功能的布局和样式的各个方面。
  • 在边界内绘制背景、图标、文字等。
  • 允许您设置多个选项。这包括但不限于以下项目的选项:背景颜色、边角形状和半径、边框(或缺少边框)、文字颜色和字体。
  • 解码并缓存图像。

如果您以 API 级别 24 为目标,可以在 XML 中将 ComplicationDrawable 对象定义为一种资源。或者,您也可以通过编程方式创建一个 ComplicationDrawable 对象。您可以使用 draw() 方法绘制一个复杂功能,并为交互模式和微光模式设置样式选项。

ComplicationDrawable 将使用防烙印安全图标和图像(如果已提供并且设备需要的话)。要执行此操作,请在收到设备属性时调用 ComplicationDrawable.setBurnInProtection() 方法。

如需了解有关绘制复杂功能的详细说明和示例,请参阅 ComplicationDrawable,其中包括示例 XML。有关利用此类并包含示例 XML 的示例表盘,请参阅表盘示例应用中的 AnalogComplicationWatchFaceService 示例。

如果您不使用 ComplicationDrawable 对象,请为复杂功能的文本使用 TextRenderer

渲染文本

TextRenderer 类旨在用于复杂功能,并且可以简化画布上的文本绘制。该类包含以下功能:

  • 如果请求文本大小的边界不足以显示七个字符(短文本字段中可包含的最大字符数),该类会将文本缩减,直至可在文本边界内显示为止。
  • 文本可以越过指定的行数。
  • 如果文本大小不合适,则可能会被省略一部分。
  • 针对“始终开启屏幕”(微光模式)对渲染进行调整。

初始化表盘引擎时,您可以创建一个 TextRenderer 对象并将其传入您希望 TextRenderer 对象使用的 TextPaint 对象。TextPaint 对象可以定义字体、文本大小和颜色等。您应为每个字段创建一个 TextRenderer 对象,例如,为文本字段和标题字段各创建一个。

如需了解示例代码,包括用于在想要渲染的文本上指定边界的代码,请参阅 TextRenderer

点按复杂功能

使用 ComplicationDrawable.onTap() 方法,可让表盘向复杂功能传递点按事件。这一方法建立在现有功能(点按表盘会触发 WatchFaceService.Engine.onTapCommand() 方法)的基础上。

您可以通过调用 onTap 将坐标传递至 ComplicationDrawable。这将启动与包含相应点按坐标的 ComplicationDrawable 相关联的操作。调用该方法后,如果 ComplicationDrawable 启动了相关联的操作,您将收到返回值 true。

使用 setHighlightDuration() 方法可以在调用 onTap 方法后设置复杂功能保持突出显示状态的时长。

如果您未对复杂功能使用 ComplicationDrawable,则需要自行检测点按并触发点按操作 PendingIntent。如需了解如何创建响应用户点按的表盘,请参阅创建互动式表盘

复杂功能类型

复杂功能类型决定了在复杂功能中显示的数据类型。例如,如果关键数据为短字符串,可以使用 SHORT_TEXT 类型。在 SHORT_TEXT 类型的示例中,可选数据是图标和短标题。

数据提供程序使用复杂功能类型的方式与表盘提供程序使用这些类型的方式有所不同:

  • 数据提供程序会选择要提供的复杂功能数据类型。例如,步数提供程序可能支持 RANGED_VALUESHORT_TEXT 类型,而“下一会议”提供程序可能支持 SHORT_TEXTLONG_TEXT 类型。数据提供程序也会选择要包含这些类型的哪些可选字段。
  • 表盘提供程序选择要支持的复杂功能类型数量。例如,表盘中的圆形复杂功能可能支持 SHORT_TEXTICONRANGED_VALUE 类型,而表盘上的量表可能仅支持 RANGED_VALUE 类型。

ComplicationData 对象将始终具有一种复杂功能类型。每种复杂功能类型都有必填和可选字段。通常,必填字段代表数据的主要部分;大多数类型的名称都取自必填字段。

给定的类型可能包含不同的字段集。例如,SHORT_TEXT 可能只是一段文字、也可能是标题和文字,或者是图标和文字。支持给定类型的复杂功能必须能够显示所有预计的变体。不过,一些可选字段不需要显示(请参阅下表中的备注列)。例如,RANGED_VALUE 类型的短标题字段不是必填字段,这样可以在不包含文本的情况下显示量表。

复杂功能类型示例

以下将显示复杂功能类型的示例:

复杂功能类型

类型和字段

下表介绍了 ComplicationData 对象的类型和字段。如果表盘请求复杂功能类型无效的字段,则系统会返回该字段的默认值。例如,如果表盘尝试访问 SHORT_TEXT 类型的 Long text 字段,系统将返回 Long text 字段的默认值 (null)。

类型 必填字段 选填字段 备注
SHORT_TEXT 短文本 图标
防烙印图标
短标题
如果提供了其中一种或两种类型,预计会显示图标/短标题中的一个。
ICON 图标 防烙印保护图标 在不需要文本时使用。该图标预计为单色,并且可能根据表盘进行着色。
RANGED_VALUE
最小值
最大值
图标
防烙印图标
短文本
短标题
不能保证会显示选填字段。如果您想自行绘制进度条,可以使用 setRangedValueProgressHidden() 方法隐藏 ComplicationDrawable 类提供的进度条。
LONG_TEXT 长文本 长标题
图标
防烙印图标
小图片
如果提供了相应字段,预计会显示标题。
SMALL_IMAGE 小图片 小图片具有以下两种样式之一:照片样式图标样式。照片样式的图像应当可以填充空间并且可以裁剪;图标样式的图像不应裁剪,并且可能有内边距。在带有防烙印或低位微光模式的设备上,图像变化可能产生不适合在微光模式下显示的图像。当启用防烙印或低位微光模式时,表盘可能会使用 Burn-in protection small image(因为它是安全的)。否则,由于表盘很难确定适合程度,因此不应显示相应图像。
LARGE_IMAGE 大图片 这种图片的大小应当足以填充表盘。在带有防烙印或低位微光模式的设备上,图像变化可能产生不适合在微光模式下显示的图像。由于表盘很难确定图像是否适合显示,因此如果已启用防烙印或低位微光模式,表盘就不应在微光模式下显示图像。

下表中的类型适合空数据,并且可以针对任何复杂功能插槽发送。这些类型没有对应的字段,也不需要包含在受支持类型的列表中。这些类型可以让表盘与以下三种情况区分开来:

  • 未选择任何提供程序
  • 用户已为插槽选择“空”
  • 提供程序没有任何要发送的数据

提供程序不应发送 TYPE_EMPTY 以响应更新请求。提供程序应改为发送 TYPE_NO_DATA

下表列出了有关“空”数据的复杂功能类型的详情:

复杂功能类型 说明
TYPE_NOT_CONFIGURED 在启用复杂功能后,但用户尚未选择提供程序并且未设置任何默认项的情况下,系统会发送该类型。

无法由提供程序发送。

TYPE_EMPTY 在启用复杂功能后并且用户选择“空”而非提供程序,或者在表盘未选择任何提供程序,而此类型作为默认项的情况下,系统会发送此类型。

无法由提供程序发送。

TYPE_NO_DATA 在启用复杂功能(具有提供程序)后,系统发送该类型以在接收提供程序的真实数据之前清除复杂功能。

如果提供程序没有要发送的真实数据,相应提供程序应发送该类型。

为复杂功能数据使用字段

ComplicationData 对象的字段具有不同的功能。例如,文本字段包含主要数据,而标题字段具有描述性;步数复杂功能可能具有值为“2,543”的文本字段值以及值为“步”的标题字段。

下表包含 ComplicationData 对象中字段的说明。这些字段不一定会被填充,具体取决于复杂功能类型。

字段 说明
短文本 针对小型复杂功能的主要文本字段。该字段的最大长度不得超过 7 个字符(包括任何不同时间的文本)。表盘应当可以渲染任何七字符字符串。字符串的宽度各不相同,具体取决于所使用的字符。表盘应当调整文本大小以让其适应复杂功能。如果文本超过 7 个字符,就可能会被截断。
图标 表示数据或数据源的单色图像。必须可着色。建议针对此字段使用矢量可绘制对象。
防烙印保护图标 可让图标在使用防烙印保护的设备上的微光模式下显示。在微光模式下,使用防烙印保护的设备上的表盘不应显示纯色像素块。Burn-in protection icon 字段对包含 icon 字段的任何复杂功能类型来说都是可选字段。Burn-in protection icon 字段不应包含任何纯色像素块。如果提供程序的标准图标不适合防烙印,Burn-in protection icon 字段应由提供程序提供。如果表盘在启用防烙印的设备的微光模式下渲染,它应使用 Burn-in protection icon 字段(如适用),而不是 icon 字段。
防烙印保护小图片 可让图片在使用防烙印保护的设备上的微光模式下显示。在微光模式下,使用防烙印保护的设备上的表盘不应显示纯色像素块。Burn-in protection small image 字段对包含 small image 字段的任何复杂功能类型来说都是可选字段。Burn-in protection small image 字段不应包含任何纯色像素块。如果提供程序的标准小图片不适用于防烙印保护,则相应提供程序应提供 Burn-in protection small image 字段。如果表盘在启用防烙印的设备的微光模式下渲染,它应使用 Burn-in protection small image 字段(如适用),而不是 small image 字段。
短标题 针对小型复杂功能的描述性字段。只有在与 Short text 字段组合时才有意义。该字段的最大长度不得超过 7 个字符(包括任何不同时间的文本)。表盘应当可以渲染任何七字符字符串。字符串的宽度各不相同,具体取决于所使用的字符。表盘应当调整文本大小以让其适应复杂功能。如果文本超过 7 个字符,就可能会被截断。
长文本 针对大型、基于文本的复杂功能的主要数据字段。
长标题 针对大型、基于文本的复杂功能的描述性字段。可能只有在与长文本结合使用时才有意义。
数据的数字(浮点数)呈现形式。预计将相对于“最小值”和“最大值”字段的边界进行描述(但不必在这些边界之间)。
最小值 应描述“值”所处范围的下限。只有在将“值”和“最大值”相结合时才有意义。
最大值 应描述“值”所处范围的上限。只有在将“值”和“最小值”相结合时才有意义。
小图片 用于表示数据或数据源的小图片。可以是全色。不应填充整个表盘。
大图片 分辨率足以填充表盘的图片。可以是全色。

测试复杂功能类型

每种复杂功能类型都具有多个字段,如文本和图标。如果您的表盘支持一种复杂功能类型,则您需要支持所有有效的字段组合。

您可以测试复杂功能数据在表盘上的显示方式。具体来说,您可以使用测试套件测试复杂功能类型的显示。因此,您不需要编写代码来测试 ComplicationData 对象的有效字段组合。

该测试套件是一个数据提供程序(作为示例应用提供),可以循环切换给定复杂功能类型的有效字段组合。

如需使用该测试套件,请执行以下操作:

  1. 在设备或模拟器上安装测试套件 APK。
  2. 访问您的表盘并点按其主设置图标。
  3. 使用设置界面以选择测试套件:WearComplication-ProviderTestSuite
  4. 选择要测试的复杂功能数据类型。
  5. 点按复杂功能以查看数据类型的变化。
  6. 反复点按相应复杂功能以确认所有相关字段组合均已正确显示。

例如,如果复杂功能支持短文本,请点按相应复杂功能以查看短文本的所有主要字段组合。