小工具資料來源可為錶面小工具提供文字、圖片和數字,供錶面顯示。
這項資料來源服務擴充了
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 系統才會將其視為資料來源。本節說明資料來源的必要設定。
在應用程式的資訊清單中,宣告這項服務並新增更新要求動作的意圖篩選器。此外,資訊清單也必須透過新增 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, for example: "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, specify a configuration activity, where the user can configure your complication. --> <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 分鐘) 的值,也就是系統強制執行的最低更新期限,來延長裝置的電池續航力。此外,請留意,裝置處於微光模式或沒有佩戴時,更新要求的頻率可能會降低。
新增設定活動
如有需要,資料來源可納入設定活動,當使用者從小工具挑選器選擇該資料來源時,該活動就會向使用者顯示。舉例來說,世界時鐘資料來源可能會有設定活動,讓使用者選擇要顯示的城市或時區。
範例資訊清單包含具有 PROVIDER_CONFIG_ACTION
鍵的 meta-data
元素。這個元素的值是啟動設定活動時使用的動作。
建立設定活動,並在資訊清單檔案中新增與該活動動作相符的意圖篩選器。
<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>
活動可以從活動的 onCreate()
方法中的意圖取得所設定複雜功能插槽的詳細資料:
// 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)
設定活動必須與供應商位於同一套件中。設定活動必須傳回 RESULT_OK
或 RESULT_CANCELED
,讓系統知道是否應設定資料來源:
setResult(RESULT_OK) // Or RESULT_CANCELED to cancel configuration finish()
使用推送更新
除了在應用程式資訊清單中指定更新間隔之外,也可以使用
ComplicationDataSourceUpdateRequester
的執行個體以動態方式啟動更新。如要要求更新,請呼叫 requestUpdate()
。
注意:為延長裝置電池續航力,透過 ComplicationDataSourceUpdateRequester
例項呼叫 requestUpdate()
的頻率不要超過平均每 5 分鐘一次。
提供時間相依值
部分小工具需要顯示與目前時間相關的值。例如目前日期、距離下一場會議還有多少時間或其他時區的時間。
請勿為了讓資料保持最新狀態,設定每秒或每分鐘更新小工具。請改用時間相依文字,指定與目前日期或時間相關的值。您可以使用下列類別建立這些時間相依值:
-
TimeFormatComplicationText
:設定日期或時間值的格式。 -
TimeDifferenceComplicationText
- 向上或向下計數至指定時間。
時間軸資料
如要使用在預先定義時間提供一系列值的複雜功能資料來源,請使用 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
程式庫而定。
在某些情況下,平台無法評估動態值:
- 有時無法取得動態值: 例如裝置脫離手腕時,在這種情況下,平台會在
NoDataComplicationData
的預留位置欄位中,改用 動態值失效備用欄位的值。 - 動態值一律無法使用: 如果裝置搭載舊版 Wear OS 4,就會發生這種情況。在這種情況下,平台會使用備用欄位,例如
getFallbackValue()
。