向复杂功能提供数据

复杂功能数据源会通过提供表盘可呈现的文本、图片和数字,向表盘复杂功能提供信息。

数据源服务扩展了 SuspendingComplicationDataSourceService,可直接将有用的信息提供给表盘。

使用入门

将以下依赖项添加到应用模块:

dependencies {
  implementiation("androidx.wear.watchface:watchface-complications-data-source-ktx:1.2.1")
}

创建数据源服务

当 Wear OS 系统需要复杂功能数据时,它会向您的数据源发送更新请求。 为了响应更新请求,您的数据源必须实现 SuspendingComplicationDataSourceService 类的 onComplicationRequest() 方法。

Wear OS 系统会在需要来自数据源的数据时调用 onComplicationRequest(),例如在使用数据源的复杂功能变为活动状态时,或经过一段固定时间后。

注意:当数据源提供数据时,表盘会接收原始值。表盘负责设置数据的显示格式。

以下代码段展示了一个实现示例:

class MyComplicationDataSourceService : SuspendingComplicationDataSourceService() {
    override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationData? {
        // Retrieve the latest info for inclusion in the data.
        val text = getLatestData()
        return shortTextComplicationData(text)
    }

    override fun getPreviewData(type: ComplicationType): ComplicationData? {
        return shortTextComplicationData("Event 1")
    }

    private fun shortTextComplicationData(text: String) =
        ShortTextComplicationData.Builder(
            text = PlainComplicationText.Builder(text).build(),
            contentDescription = PlainComplicationText.Builder(text).build()
        )
            // Add further optional details here such as icon, tap action, and title.
            .build()

    // ...
}

清单声明和权限

数据源必须在其应用清单中包含特定的声明,Android 系统才会将其视为数据源。本部分介绍了数据源必需的设置。

在应用清单中,声明相应服务并添加更新请求操作 intent 过滤器。清单还必须通过添加 BIND_COMPLICATION_PROVIDER 权限来保护相应服务,以确保只有 Wear OS 系统可以绑定到提供程序服务。

此外,在提供单色白色图标的 service 元素中添加 android:icon 属性。我们建议为此类图标使用矢量可绘制对象。此图标表示数据源,会显示在复杂功能选择器中。

下面是一个例子:

<service
    android:name=".snippets.complication.MyComplicationDataSourceService"
    android:exported="true"
    android:label="@string/my_complication_service_label"
    android:icon="@drawable/complication_icon"
    android:permission="com.google.android.wearable.permission.BIND_COMPLICATION_PROVIDER">
    <intent-filter>
        <action android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST" />
    </intent-filter>

    <!-- Supported types should be comma-separated e.g. SHORT_TEXT,SMALL_IMAGE -->
    <meta-data
        android:name="android.support.wearable.complications.SUPPORTED_TYPES"
        android:value="SHORT_TEXT" />
    <meta-data
        android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
        android:value="300" />

    <!--
        Optionally, the complication can be configured by the user by specifying a
        configuration activity.
    -->
    <meta-data
        android:name="android.support.wearable.complications.PROVIDER_CONFIG_ACTION"
        android:value="MY_CONFIG_ACTION" />

</service>

元数据元素

在清单文件中,请注意以下元数据元素:

  • android:name="android.support.wearable.complications.SUPPORTED_TYPES": 指定数据源支持的复杂功能数据类型。
  • android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS": 指定系统应多久检查一次数据更新。

当您的复杂功能数据源处于活动状态时,UPDATE_PERIOD_SECONDS 可用于指定您希望系统检查是否有数据更新的频率。如果复杂功能中显示的信息不需要定期更新,例如当您使用推送更新时,请将该值设为 0

如果您未将 UPDATE_PERIOD_SECONDS 设为 0,则必须至少设为 300(5 分钟),这是系统为了节省设备电池电量而执行的最短更新周期。另请注意,当设备处于氛围模式或未佩戴时,更新请求的频率会降低。

添加配置 Activity

如果需要,数据源可以包含配置 activity,当用户从复杂功能选择器中选择该特定数据源时,系统会向用户显示该 activity。例如,世界时钟数据源可能具有配置 activity,允许用户选择要显示的城市或时区。

示例清单包含一个具有 PROVIDER_CONFIG_ACTION 键的 meta-data 元素。此元素的值是用于启动配置 activity 的操作。

创建配置 activity,并在清单文件中添加与该 activity 的操作相匹配的 intent 过滤器。

<intent-filter>
    <action android:name="MY_CONFIG_ACTION" />
    <category android:name="android.support.wearable.complications.category.PROVIDER_CONFIG" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

activity 可以通过其 onCreate() 方法内的 intent 获取正在配置的复杂功能槽的详细信息:

// Keys defined on ComplicationDataSourceService
val id = intent.getIntExtra(EXTRA_CONFIG_COMPLICATION_ID, -1)
val type = intent.getIntExtra(EXTRA_CONFIG_COMPLICATION_TYPE, -1)
val source = intent.getStringExtra(EXTRA_CONFIG_DATA_SOURCE_COMPONENT)

配置 activity 必须与提供程序位于同一个软件包中。配置 activity 必须返回 RESULT_OKRESULT_CANCELED,以告知系统是否应设置数据源:

setResult(RESULT_OK) // Or RESULT_CANCELED to cancel configuration
finish()

使用推送更新

除了在应用清单中指定更新间隔,您还可以使用 ComplicationDataSourceUpdateRequester 实例来动态启动更新。 如需请求更新,请调用 requestUpdate()

注意:为了节省设备的电池电量,从 ComplicationDataSourceUpdateRequester 实例调用 requestUpdate() 的平均频率不得超过 5 分钟一次。

提供具有时效性的值

一些复杂功能需要显示与当前时间相关的值。示例包括当前日期、距下次会议召开还剩的时间或另一个时区的时间。

请不要每秒或每分钟更新一次复杂功能来确保这些值保持最新状态,而是使用具有时效性的文本指定相对于当前日期或时间的值。您可以使用以下类来创建此类具有时效性的值:

时间轴数据

对于在预定义时间提供一系列值的复杂功能数据源,请使用 SuspendingTimelineComplicationDataSourceService

例如,日历应用的“下一个活动”数据源: 数据源可以提供一次活动时间表,而不是让系统定期轮询数据源以获取下一个活动, 然后,如果日历发生变化,数据源可以启动更新。这样可以最大限度地减少系统负载,并让功能块及时显示正确的事件:

class MyTimelineComplicationDataSourceService : SuspendingTimelineComplicationDataSourceService() {
    override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationDataTimeline? {
        if (request.complicationType != ComplicationType.SHORT_TEXT) {
            return ComplicationDataTimeline(
                defaultComplicationData = NoDataComplicationData(),
                timelineEntries = emptyList()
            )
        }
        // Retrieve list of events from your own datasource / database.
        val events = getCalendarEvents()
        return ComplicationDataTimeline(
            defaultComplicationData = shortTextComplicationData("No event"),
            timelineEntries = events.map {
                TimelineEntry(
                    validity = TimeInterval(it.start, it.end),
                    complicationData = shortTextComplicationData(it.name)
                )
            }
        )
    }

    override fun getPreviewData(type: ComplicationType): ComplicationData? {
        return shortTextComplicationData("Event 1")
    }

    private fun shortTextComplicationData(text: String) =
        ShortTextComplicationData.Builder(
            text = PlainComplicationText.Builder(text).build(),
            contentDescription = PlainComplicationText.Builder(text).build()
        )
            // Add further optional details here such as icon, tap action, title etc
            .build()

    // ...
}

SuspendingTimelineComplicationDataSourceService 的行为如下:

  • 当当前时间位于时间轴中某个条目的开始时间和结束时间之间时,表盘会使用该值。
  • 如果当前时间不在时间轴中的任何条目内,系统会使用默认值。例如,在日历应用中,这可能是“无活动”。
  • 如果当前时间属于多个活动的时间范围,系统会使用时间最短的活动。

提供动态价值

从 Wear OS 4 开始,一些复杂功能可以根据平台直接提供的值显示刷新更频繁的值。如需在复杂功能中提供此功能,请使用接受动态值 ComplicationData 字段。平台会频繁评估和更新这些值,而无需复杂功能提供程序运行。

示例字段包括 GoalProgressComplicationData 的动态值字段 DynamicComplicationText,它们可用于任何 ComplicationText 字段。这些动态值基于 androidx.wear.protolayout.expression 库。

在某些情况下,平台无法评估动态值: