向表盘添加复杂功能

表盘复杂功能可显示数据提供程序的数据。利用 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,这个 intent 可用于显示选择器界面。

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

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

请参阅表盘示例应用,了解界面设置的全功能建议代码。

该代码具备以下特性:

  • 一个用于复杂功能设置的标准接口。
  • 易于访问其他设置。

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

打开提供程序选择器

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

com.google.android.wearable.permission.RECEIVE_COMPLICATION_DATA

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

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

请求必要权限

要使用 ComplicationHelperActivity,请在 manifest 文件中将其添加到表盘:

<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 类型的 Short title 字段不是必填字段,这样可以在不包含文本的情况下显示量表。

复杂功能类型示例

下面显示了复杂功能类型的示例:

复杂功能类型

类型和字段

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

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

下表中的类型适合空白数据,并且可以针对任何复杂功能显示位置发送。这些类型没有字段,并且不需要包含到受支持类型的列表中。这些类型让表盘可以区分以下三种情况:

  • 未选择提供程序
  • 用户已为显示位置选择“空白”
  • 提供程序没有要发送的数据

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

下表中介绍了适合“空白”数据的复杂功能类型的详细信息:

复杂功能类型 说明
TYPE_NOT_CONFIGURED 由系统在某个复杂功能已激活但用户尚未选择提供程序时发送,未设置默认值。

无法由提供程序发送。

TYPE_EMPTY 由系统在以下情况下发送:某个复杂功能已激活并且用户已选择“空白”而非提供程序,或者表盘未选择提供程序而是选择此类型作为默认值。

无法由提供程序发送。

TYPE_NO_DATA 由系统在某个复杂功能(具有提供程序)已激活时发送,用于在从提供程序接收实际数据之前清除复杂功能。

在提供程序没有要发送的实际数据时应由提供程序发送。

为复杂功能数据使用字段

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

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

字段 说明
Short text 小型复杂功能的主要文本字段。此字段的最大长度不应超过七个字符(包括任何随时间而变的文本)。表盘应当可以渲染任何七字符字符串。字符串的宽度各不相同,具体取决于使用的字符。表盘应当调整文本大小以让其适应复杂功能。如果文本超过七个字符,可能会被截断。
Icon 表示数据或数据源的单色图像。必须可以着色。建议为此字段使用矢量图。
Burn-in protection icon 在使用防烙印的设备上,用于启用要在微光模式下显示的图标的字段。在微光模式下,使用防烙印的设备上的表盘不应显示纯色像素块。Burn-in protection icon 字段对包含 icon 字段的任何复杂功能类型来说都是可选字段。Burn-in protection icon 字段不应包含任何纯色像素块。如果提供程序的标准图标不适合防烙印,Burn-in protection icon 字段应由提供程序提供。如果表盘在启用防烙印的设备的微光模式下渲染,它应使用 Burn-in protection icon 字段(如适用),而不是 icon 字段。
Burn-in protection small image 在使用防烙印的设备上,用于启用要在微光模式下显示的图像的字段。在微光模式下,使用防烙印的设备上的表盘不应显示纯色像素块。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 title 小型复杂功能的说明性字段。只有在与 Short text 字段组合时才有意义。此字段的最大长度不应超过七个字符(包括任何随时间而变的文本)。表盘应当可以渲染任何七字符字符串。字符串的宽度各不相同,具体取决于使用的字符。表盘应当调整文本大小以让其适应复杂功能。如果文本超过七个字符,可能会被截断。
Long text 适用于基于文本的大型复杂功能的主要数据字段。
Long title 适用于基于文本的大型复杂功能的说明性字段。只有在与 Long text 组合时才有意义。
Value 数据的数字(浮点)表示形式。预计可以相对于 Min valueMax value 字段的边界描绘(但不需要介于这些边界之间)。
Min value 应在其中描绘 Value 的范围的下边界。只有在与 ValueMax value 组合时才有意义。
Max value 应在其中描绘 Value 的范围的上边界。只有在与 ValueMin value 组合时才有意义。
Small image 用于表示数据或数据源的小图像。可以是全色。不应填充整个表盘。
Large image 一种具有足够的分辨率来填充表盘的图像。可以是全色。

测试复杂功能类型

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

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

测试套件是一个数据提供程序,以示例形式提供,它可以循环切换给定复杂功能类型的有效字段组合。

要使用测试套件,请执行以下操作:

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

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