向复杂功能公开数据

表盘复杂功能可显示数据提供程序提供的数据。数据提供程序会向表盘提供包含文本、字符串、图像和数字的原始字段。

数据提供程序 service 扩展了 ComplicationProviderService,可直接在表盘上为用户提供实用信息。

创建数据提供程序应用

当需要更新复杂功能数据时,Wear OS by Google 会向数据提供程序应用发送更新请求。

为了响应来自系统的更新请求,您的数据提供程序应用必须实现 ComplicationProviderService 类的 onComplicationUpdate() 函数。此函数将在系统想要从您的提供程序获取数据时调用 - 可能是使用您的提供程序的复杂功能变成活动时,也可能是经过固定的时间后。 ComplicationManager 对象将以参数形式传递到 onComplicationUpdate 函数中,可用于将数据送回系统。

:当您以复杂功能数据提供程序形式提供数据时,表盘将接收您发送的原始值,以便可以在表盘上绘制这些数据。

以下代码段演示 onComplicationUpdate 函数的示例实现:

Kotlin

override fun onComplicationUpdate(
        complicationId: Int,
        dataType: Int,
        complicationManager: ComplicationManager
) {

    Log.d(TAG, "onComplicationUpdate() id: $complicationId")

    // Used to create a unique key to use with SharedPreferences for this complication.
    val thisProvider = ComponentName(this, javaClass)

    // Retrieves your data, in this case, we grab an incrementing number from SharedPrefs.
    val preferences = getSharedPreferences(
            ComplicationTapBroadcastReceiver.COMPLICATION_PROVIDER_PREFERENCES_FILE_KEY,
            0
    )

    val number: Int = preferences.getInt(
            ComplicationTapBroadcastReceiver.getPreferenceKey(thisProvider, complicationId),
            0
    )
    val numberText = String.format(Locale.getDefault(), "%d!", number)

    when (dataType) {
        ComplicationData.TYPE_SHORT_TEXT ->
            ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT)
                    .setShortText(ComplicationText.plainText(numberText))
                    .build().also { complicationData ->
                        complicationManager.updateComplicationData(complicationId, complicationData)
                    }
        else -> {
            if (Log.isLoggable(TAG, Log.WARN)) {
                Log.w(TAG, "Unexpected complication type $dataType")
            }
            // If no data is sent, we still need to inform the ComplicationManager, so
            // the update job can finish and the wake lock isn't held any longer.
            complicationManager.noUpdateRequired(complicationId)
        }
    }
}

Java

@Override
public void onComplicationUpdate(
       int complicationId, int dataType, ComplicationManager complicationManager) {

   Log.d(TAG, "onComplicationUpdate() id: " + complicationId);

   // Used to create a unique key to use with SharedPreferences for this complication.
   ComponentName thisProvider = new ComponentName(this, getClass());

   // Retrieves your data, in this case, we grab an incrementing number from SharedPrefs.
   SharedPreferences preferences =
     getSharedPreferences( ComplicationTapBroadcastReceiver.COMPLICATION_PROVIDER_PREFERENCES_FILE_KEY, 0);

   int number =
           preferences.getInt(
                   ComplicationTapBroadcastReceiver.getPreferenceKey(
                           thisProvider, complicationId),
                   0);
   String numberText = String.format(Locale.getDefault(), "%d!", number);

   ComplicationData complicationData = null;

   switch (dataType) {
       case ComplicationData.TYPE_SHORT_TEXT:
           complicationData =
                   new ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT)
                           .setShortText(ComplicationText.plainText(numberText))
                           .build();
           break;
       default:
           if (Log.isLoggable(TAG, Log.WARN)) {
               Log.w(TAG, "Unexpected complication type " + dataType);
           }
   }

   if (complicationData != null) {
       complicationManager.updateComplicationData(complicationId, complicationData);

   } else {
       // If no data is sent, we still need to inform the ComplicationManager, so
       // the update job can finish and the wake lock isn't held any longer.
       complicationManager.noUpdateRequired(complicationId);
   }
}

Manifest 声明和权限

数据提供程序应用必须在其应用 manifest 中包含特定的声明,才能被 Android 系统视为数据提供程序。本部分介绍了数据提供程序应用必需的设置。在您的应用 manifest 中,声明相应 service 并添加更新请求操作 intent 过滤器。manifest 还必须通过添加 BIND_COMPLICATION_PROVIDER 权限来保护该 service,以确保只有 Wear OS 系统可以绑定到提供程序 service。

另外,您必须在 service 元素中添加一个 android:icon 属性。提供的图标应是一个单色白图标。建议为图标使用矢量图。图标应表示提供程序并将显示在提供程序选择器中。

下面是一个示例:

        <service
            android:name=".provider.IncrementingNumberComplicationProviderService"
            android:icon="@drawable/icn_complications"
            android:label="@string/complications_provider_incrementing_number"
            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>
         </service>

指定元数据元素

在您的 manifest 文件中,添加元数据来指定支持的类型、更新期间和配置操作(如果需要);如需了解详情,请参阅 Wear API 参考中为 ComplicationProviderService 类列出的密钥。

当您的复杂功能数据提供程序处于活动状态时,UPDATE_PERIOD_SECONDS 会指定您希望系统检查数据更新的频率。这应该设置为尽可能长的时间,或设置为 0(如果不需要排定更新),因为更新频率过于频繁可能会影响电池续航时间。请注意,不能保证按照此频率发送更新请求。系统应用的最短更新周期为 300 秒,具体来说就是,当设备处于微光模式或未佩戴时,更新请求的频率可能会低一些。

您也可以使用“推送样式”发送更新,而不是以固定频率请求更新。根据需要使用 ProviderUpdateRequester 来触发对 onComplicationUpdate 的调用。例如:

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

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

添加配置 Activity

如果需要,提供程序可以包含一个在用户选择数据提供程序时会向其显示的配置 Activity。要包含配置 Activity,请在 manifest 的提供程序 service 声明中添加一个元数据条目,该条目带有以下键:

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

值可以是您选择的操作。

然后,为该操作创建一个带有 intent 过滤器的配置 Activity。配置 Activity 与提供程序必须位于相同的软件包中。配置 Activity 必须返回 RESULT_OKRESULT_CANCELED 以告知系统是否应设置提供程序。

提供程序指定的安全表盘

提供程序可以将特定表盘指定为“安全的”以接收其数据。只有表盘尝试将提供程序用作默认值(见下文),并且提供程序信任表盘应用时,才应使用这种方式。

为了将表盘声明为安全的,提供程序会添加一个带有 android.support.wearable.complications.SAFE_WATCH_FACES 键的元数据。元数据值应为逗号分隔的列表(忽略空格)。列表中的条目可以是 WatchFaceServices 的组件名称(假设已调用 ComponentName.flattenToString()),也可以是应用的软件包名称(指定应用中的每一个表盘都被视为安全的)。例如:

<meta-data
       android:name="android.support.wearable.complications.SAFE_WATCH_FACES"
       android:value="
          com.app.watchface/com.app.watchface.MyWatchFaceService,
          com.anotherapp.anotherwatchface/com.something.WatchFaceService,
          com.something.text"/>

提供防烙印图像

在容易出现烙印的屏幕上,应避免在微光模式下使用实心颜色块。如果您的图标或图像包含实心颜色块,您还应提供防烙印安全版本。

使用 ComplicationData.Builder#setIcon 提供图标时,请使用 ComplicationData.Builder#setBurnInProtectionIcon 包含防烙印安全版本。

使用 ComplicationData.Builder#setSmallImage 提供图像时,请使用 ComplicationData.Builder#setBurnInProtectionSmallImage 包含防烙印安全版本。

提供具有时效性的值

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

请不要为了保持这些值最新而每秒或每分钟更新一次复杂功能;一项复杂功能绝不需要更新得这么频繁。请使用具有时效性的文本指定相对于当前日期或时间的值。您可以使用 ComplicationText 类中的构建器来创建此类具有时效性的值。