Google 致力于为黑人社区推动种族平等。查看具体举措

向复杂功能提供数据

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

数据提供程序服务扩展了 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);
       }
    }
    

清单声明和权限

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

此外,您必须在服务元素中添加一个 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>
    

指定元数据元素

在您的清单文件中,添加元数据来指定支持的类型、更新周期和配置操作(如果需要);如需了解详情,请参阅 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 会在用户选择数据提供程序时显示给用户。要包含配置 Activity,请在清单中的提供程序服务声明中添加一个具有以下键的元数据项:

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

其中的“value”可以是您选择的操作。

然后,创建包含该操作的 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 类中的构建器来创建此类具有时效性的值。