Źródła danych widżetów udostępniają informacje widżetom na tarczy zegarka, dostarczając tekst, obrazy i liczby, które tarcza zegarka może renderować.
Usługa źródła danych rozszerza
SuspendingComplicationDataSourceService
, aby dostarczać przydatne informacje bezpośrednio na tarczę zegarka.
Pierwsze kroki
Dodaj do modułu aplikacji tę zależność:
dependencies { implementiation("androidx.wear.watchface:watchface-complications-data-source-ktx:1.2.1") }
Utwórz usługę źródła danych
Gdy dane komplikacji są potrzebne, system Wear OS wysyła do źródła danych żądania aktualizacji.
Aby odpowiadać na żądania aktualizacji, źródło danych musi implementować metodę
onComplicationRequest()
klasy SuspendingComplicationDataSourceService
.
System Wear OS wywołuje metodę onComplicationRequest()
, gdy potrzebuje danych ze źródła, np. gdy komplikacja korzystająca ze źródła danych staje się aktywna lub gdy upłynie określony czas.
Uwaga: gdy źródło danych dostarcza dane, tarcza zegarka otrzymuje surowe wartości. Tarcza zegarka odpowiada za formatowanie danych do wyświetlania.
Poniższy fragment kodu przedstawia przykładową implementację:
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() // ... }
Deklaracje i uprawnienia w pliku manifestu
Aby źródła danych były traktowane przez system Android jako źródła danych, muszą zawierać w pliku manifestu aplikacji określone deklaracje. W tej sekcji opisujemy wymagane ustawienia źródeł danych.
W pliku manifestu aplikacji zadeklaruj usługę i dodaj filtr intencji działania żądania aktualizacji.
Plik manifestu musi też chronić usługę, dodając uprawnienie BIND_COMPLICATION_PROVIDER
, aby mieć pewność, że tylko system Wear OS może powiązać się z usługami dostawcy.
W elemencie service
umieść też atrybut android:icon
, który zawiera jednokolorową białą ikonę. W przypadku ikon zalecamy używanie obrazów wektorowych.
Ikona reprezentuje źródło danych i jest widoczna w selektorze komplikacji.
Oto przykład:
<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>
Elementy metadanych
W pliku manifestu zwróć uwagę na te elementy metadanych:
-
android:name="android.support.wearable.complications.SUPPORTED_TYPES"
: określa typy danych powikłań, które obsługuje źródło danych. -
android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
: Określa, jak często system ma sprawdzać dostępność aktualizacji danych.
Gdy źródło danych komplikacji jest aktywne, parametrUPDATE_PERIOD_SECONDS
określa, jak często system ma sprawdzać aktualizacje danych. Jeśli informacje wyświetlane w komplikacji nie muszą być aktualizowane regularnie, np. gdy używasz aktualizacji push, ustaw tę wartość na 0
.
Jeśli nie ustawisz wartości UPDATE_PERIOD_SECONDS
na 0
, musisz użyć wartości co najmniej 300
(5 minut), która jest minimalnym okresem aktualizacji wymaganym przez system, aby oszczędzać baterię urządzenia. Pamiętaj też, że prośby o aktualizację są wysyłane rzadziej, gdy urządzenie jest w trybie otoczenia lub nie jest noszone.
Dodawanie aktywności związanej z konfiguracją
W razie potrzeby źródło danych może zawierać aktywność konfiguracyjną, która jest wyświetlana użytkownikowi, gdy wybierze on to źródło danych w selektorze komplikacji. Na przykład źródło danych zegara światowego może mieć aktywność konfiguracji, która pozwala użytkownikowi wybrać miasto lub strefę czasową do wyświetlenia.
Przykładowy plik manifestu zawiera element meta-data
z kluczem PROVIDER_CONFIG_ACTION
. Wartość tego elementu to działanie, które jest używane do uruchamiania aktywności konfiguracyjnej.
Utwórz aktywność konfiguracji i dodaj do niej filtr intencji, który pasuje do działania w pliku manifestu.
<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>
Działanie może uzyskać szczegóły gniazda widżetu, które konfiguruje, z intencji w metodzie onCreate()
działania:
// 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)
Działanie konfiguracyjne musi znajdować się w tym samym pakiecie co dostawca. Działanie konfiguracji musi zwracać wartość RESULT_OK
lub RESULT_CANCELED
, aby poinformować system, czy należy ustawić źródło danych:
setResult(RESULT_OK) // Or RESULT_CANCELED to cancel configuration finish()
Korzystanie z aktualizacji push
Zamiast określać interwał aktualizacji w pliku manifestu aplikacji, możesz użyć instancji
ComplicationDataSourceUpdateRequester
, aby dynamicznie inicjować aktualizacje.
Aby poprosić o aktualizację, zadzwoń pod numer requestUpdate()
.
Ostrzeżenie: aby oszczędzać baterię urządzenia, nie wywołuj funkcji requestUpdate()
z instancji ComplicationDataSourceUpdateRequester
częściej niż co 5 minut.
Podawanie wartości zależnych od czasu
Niektóre komplikacje muszą wyświetlać wartość związaną z bieżącym czasem. Może to być na przykład bieżąca data, czas do następnego spotkania lub godzina w innej strefie czasowej.
Nie aktualizuj komplikacji co sekundę lub minutę, aby te wartości były aktualne. Zamiast tego określ wartości względem bieżącej daty lub godziny, używając tekstu zależnego od czasu. Te klasy umożliwiają tworzenie wartości zależnych od czasu:
-
TimeFormatComplicationText
– formatuje wartość daty lub godziny. -
TimeDifferenceComplicationText
– odlicza w górę lub w dół do określonego czasu.
Dane osi czasu
W przypadku źródeł danych widżetów, które dostarczają sekwencję wartości w zdefiniowanych wcześniej momentach, użyj SuspendingTimelineComplicationDataSourceService
.
Przykładem może być źródło danych „następne wydarzenie” z aplikacji kalendarza: zamiast regularnie odpytywać źródło danych o następne wydarzenie, system może raz pobrać oś czasu wydarzeń, a potem źródło danych może inicjować aktualizacje, jeśli kalendarz ulegnie zmianie. Minimalizuje to obciążenie systemu i umożliwia wyświetlanie prawidłowego wydarzenia w odpowiednim czasie:
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() // ... }
Działanie symbolu SuspendingTimelineComplicationDataSourceService
jest następujące:
- Gdy bieżący czas mieści się w przedziale czasu rozpoczęcia i zakończenia wpisu na osi czasu, tarcza zegarka używa tej wartości.
- Jeśli bieżąca godzina nie mieści się w żadnym wpisie na osi czasu, używana jest wartość domyślna. Na przykład w aplikacji Kalendarz może to być „Brak wydarzenia”.
- Jeśli bieżący czas mieści się w kilku wydarzeniach, używane jest najkrótsze z nich.
Podawanie wartości dynamicznych
Od Wear OS 4 niektóre widżety mogą wyświetlać wartości, które odświeżają się częściej na podstawie wartości dostępnych bezpośrednio na platformie. Aby udostępnić tę funkcję w komplikacjach, użyj pól
ComplicationData
, które akceptują wartości dynamiczne. Platforma często ocenia i aktualizuje te wartości bez konieczności uruchamiania dostawcy komplikacji.
Przykładowe pola to
GoalProgressComplicationData
pole wartości dynamicznej i
DynamicComplicationText
, które można stosować w dowolnym polu
ComplicationText
. Te wartości dynamiczne są oparte na bibliotece
androidx.wear.protolayout.expression
.
W niektórych sytuacjach platforma nie może ocenić wartości dynamicznych:
- Wartość dynamiczna jest czasami niedostępna: dzieje się tak np. wtedy, gdy urządzenie nie jest na nadgarstku. W takich sytuacjach platforma używa wartości
pola zastępczego unieważnienia wartości dynamicznej zamiast
NoDataComplicationData
pola zastępczego. - Wartość dynamiczna jest niedostępna: dzieje się tak na urządzeniu z Wear OS 4 w starszej wersji. W takiej sytuacji platforma używa dodatkowego pola rezerwowego, np.
getFallbackValue()
.