表盘复杂功能可显示数据提供程序提供的数据。数据提供程序会向表盘提供包含文本、字符串、图片和数字的原始字段。
数据提供程序服务扩展了 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_OK
或 RESULT_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
类中的构建器来创建此类具有时效性的值。