Aplikacje dostawców danych ujawniają informacje widżetom tarczy zegarka, udostępniając pola zawierające tekst, ciągi znaków, obrazy i liczby.
Dostawca danych wykracza poza
ComplicationProviderService
, aby dostarczać przydatne informacje bezpośrednio na tarczę zegarka.
Tworzenie projektu dostawcy danych
Aby utworzyć w Android Studio projekt dla aplikacji dostawcy danych, wykonaj te czynności:
- Kliknij File (Plik) > New (Nowy) > New project (Nowy projekt).
- W oknie Szablon projektu kliknij kartę Wear OS, wybierz Brak aktywności i kliknij Dalej.
- W oknie Skonfiguruj projekt wpisz nazwę projektu, wpisz standardowe informacje o projekcie i kliknij Zakończ.
- Android Studio utworzy projekt z modułem aplikacji dla Twojego dostawcy danych. Więcej informacji o projektach w Android Studio znajdziesz w artykule o tworzeniu projektu.
- Zacznij aplikację dostawcy danych od utworzenia nowej klasy o rozszerzeniu
BroadcastReceiver
. Ta klasa służy do wychwytywania żądań aktualizacji widżetów z systemu Wear OS. Dodatkowo utwórz nową klasę, która rozszerzy zakresComplicationProviderService
, aby udostępniać dane wymagane przez odpowiednie widżety. Więcej informacji:- Wdrażanie metody obsługi żądań aktualizacji
- Klasy
ComplicationTapBroadcastReceiver
iCustomComplicationProviderService
w ramach tych ćwiczeń z programowania: Udostępnianie danych na potrzeby widżetów tarczy zegarka w Wear OS ComplicationToggleReceiver
,LongTextProviderService
i inne klasy w przykładzie pakietu testowego
Uwaga: dodanie aktywności dla Twojego dostawcy danych jest opcjonalne. Możesz na przykład chcieć, aby działanie było uruchamiane tylko wtedy, gdy użytkownik kliknie widżet.
Wdrażanie metody obsługi żądań aktualizacji
Gdy potrzebne są dane widżetów, system Wear OS wysyła żądania aktualizacji do dostawcy danych. Żądania są przesyłane przez
BroadcastReceiver
. Aby odpowiadać na żądania aktualizacji, Twój dostawca danych musi wdrożyć metodę
onComplicationUpdate()
klasy ComplicationProviderService
.
System Wear OS wywołuje onComplicationUpdate()
, gdy potrzebuje danych od dostawcy, np. gdy aktywny widżet korzystający z usług dostawcy lub gdy minie ustalony czas.
Przekazuje do onComplicationUpdate
obiekt
ComplicationManager
jako parametr, który służy do wysyłania danych z powrotem do systemu.
Uwaga: gdy aplikacja dostawcy danych dostarcza dane, tarcza zegarka otrzymuje nieprzetworzone wartości, które przesyłasz, aby mogła je pobrać.
Ten fragment kodu zawiera przykładową implementację metody 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, grabs an incrementing number from SharedPrefs. val preferences = getSharedPreferences(ComplicationTapBroadcastReceiver.COMPLICATION_PROVIDER_PREFERENCES_FILE_KEY, 0) val number = preferences.getInt( ComplicationTapBroadcastReceiver.getPreferenceKey( thisProvider, complicationId), 0) val numberText = String.format(Locale.getDefault(), "%d!", number) var complicationData: ComplicationData? = null when (dataType) { ComplicationData.TYPE_SHORT_TEXT -> complicationData = ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT) .setShortText(ComplicationText.plainText(numberText)) .build() else -> 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) } }
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, grabs 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); } }
Deklaracje i uprawnienia w pliku manifestu
Aplikacje dostawców danych muszą zawierać określone deklaracje w pliku manifestu, aby system Android był traktowany jako dostawca danych. W tej sekcji opisano wymagane ustawienia dla aplikacji dostawców 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 tworzyć powiązania z usługami dostawców.
Dodaj też atrybut android:icon
w elemencie service
, który tworzy jednokolorową białą ikonę. Zalecamy korzystanie z elementów rysowalnych w formie wektorowej.
Ikona ta reprezentuje dostawcę i jest widoczna w selektorze dostawcy.
Oto przykład:
<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>
Określ elementy metadanych
W pliku manifestu uwzględnij metadane, aby określić obsługiwane typy, okres aktualizacji i działanie konfiguracji, jak pokazano w tym przykładzie:
<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="300" />
Gdy dostawca danych widżetu jest aktywny, UPDATE_PERIOD_SECONDS
określa, jak często system ma sprawdzać dostępność aktualizacji danych. Jeśli informacje widoczne w widżecie nie muszą być aktualizowane zgodnie ze stałym harmonogramem, np. gdy używasz aktualizacji push, ustaw tę wartość na 0
.
Jeśli nie ustawisz UPDATE_PERIOD_SECONDS
na 0
, musisz użyć wartości co najmniej 300
(5 minut), co jest minimalnym okresem aktualizacji wymuszanym przez system, aby oszczędzać baterię urządzenia. Dodatkowo pamiętaj, że żądania aktualizacji przychodzą rzadziej, gdy urządzenie działa w trybie nieaktywnym lub nie jest używane.
Więcej informacji o wysyłaniu aktualizacji znajdziesz w opisie kluczy dla klasy
ComplicationProviderService
w dokumentacji interfejsu Wear OS API.
Dodaj działanie konfiguracji
W razie potrzeby dostawca może dołączyć aktywność związaną z konfiguracją, która jest wyświetlana użytkownikowi, gdy użytkownik wybiera dostawcę danych. Aby uwzględnić działanie konfiguracji, w deklaracji usługi dostawcy w pliku manifestu umieść element metadanych z tym kluczem:
<meta-data android:name="android.support.wearable.complications.PROVIDER_CONFIG_ACTION" android:value="PROVIDER_CONFIG_ACTION"/>
Wartością może być dowolne działanie.
Następnie utwórz działanie konfiguracji z filtrem intencji dla tego działania. Działanie konfiguracji musi znajdować się w tym samym pakiecie co dostawca. Działanie konfiguracji musi zwracać wartość RESULT_OK
lub RESULT_CANCELED
, która informuje system, czy należy ustawić dostawcę.
Bezpieczne tarcze zegarka określone przez dostawcę
Dostawcy mogą określić niektóre tarcze zegarka jako „bezpieczne” i mogą odbierać dane. Jest używane tylko wtedy, gdy tarcza zegarka próbuje ustawić dostawcę jako dostawcę domyślnego i traktuje ją jako zaufaną aplikację.
Aby zadeklarować tarcze zegarka jako bezpieczne, dostawca dodaje metadane z kluczem android.support.wearable.complications.SAFE_WATCH_FACES
. Wartość metadanych to rozdzielana przecinkami lista nazw komponentów
WatchFaceService
(jakby wywoływana była funkcja ComponentName.flattenToString()
) lub nazwy pakietów aplikacji, w których przypadku każda tarcza zegarka w określonej aplikacji jest uznawana za bezpieczną. Odstępy na liście wartości są ignorowane. Na przykład:
<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"/>
Dodawanie obrazów bezpiecznych do wykrywania wypalania
W trybie nieaktywnym na ekranach narażonych na wypalenie należy unikać stosowania jednolitych bloków kolorów. Jeśli ikony lub obrazy zawierają jednolite bloki koloru, zapewnij też bezpieczną wersję do wypalenia.
Dodając ikonę, korzystając z
ComplicationData.Builder#setIcon
, dodaj bezpieczną wersję wypaloną za pomocą
ComplicationData.Builder#setBurnInProtectionIcon
.
Przy dostarczaniu obrazu za pomocą
ComplicationData.Builder#setSmallImage
dodaj bezpieczną wersję wypalania za pomocą
ComplicationData.Builder#setBurnInProtectionSmallImage
.
Korzystanie z aktualizacji push
Zamiast określać stały, niezerowy interwał aktualizacji dla widżetu w pliku manifestu aplikacji możesz użyć wystąpienia
ComplicationDataSourceUpdateRequester
, aby dynamicznie żądać aktualizacji.
Aby poprosić o aktualizację treści widocznej dla użytkowników widżetu, wywołaj requestUpdate()
.
Uwaga: aby oszczędzać baterię urządzenia, nie wywołuj funkcji requestUpdate()
z instancji ComplicationDataSourceUpdateRequester
częściej niż średnio co 5 minut.
Podaj wartości dynamiczne
Począwszy od Wear OS 4 niektóre widżety mogą wyświetlać wartości, które są odświeżane częściej na podstawie wartości dostępnych bezpośrednio na platformie. Aby udostępnić tę funkcję w swoich widżetach, użyj pól
ComplicationData
, które akceptują wartości dynamiczne. Platforma często ocenia i aktualizuje te wartości, nie wymagając działania dostawcy widżetu.
Przykładowe pola to
dynamiczne pole wartości parametru GoalProgressComplicationData
i
DynamicComplicationText
, których można użyć w dowolnym polu
ComplicationText
. Te wartości dynamiczne opierają się na bibliotece
androidx.wear.protolayout.expression
.
W niektórych sytuacjach platforma nie może ocenić wartości dynamicznych:
- Wartość dynamiczna jest czasami niedostępna: tak się dzieje np. wtedy, gdy urządzenie jest poza nadgarstkiem. W takich sytuacjach platforma korzysta z wartości
pola kreacji zastępczej w przypadku unieważnienia wartości dynamicznej w
polu zmiennej
NoDataComplicationData
. - Wartość dynamiczna nigdy nie jest dostępna: dzieje się tak na urządzeniu ze starszą wersją Wear OS 4. W takiej sytuacji platforma używa pola kreacji zastępczej, np.
getFallbackValue()
.
Podaj wartości zależne od czasu
Niektóre widżety muszą wyświetlać wartość związaną z bieżącą godziną. Może to być na przykład bieżąca data, godzina do następnego spotkania lub godzina w innej strefie czasowej.
Nie aktualizuj widżetów co sekundę ani minutę, aby te wartości były aktualne. Zamiast tego podaj wartości w odniesieniu do bieżącej daty lub godziny, korzystając z tekstu zależnego od czasu.
Aby utworzyć te wartości zależne od czasu, możesz użyć monterów w klasie
ComplicationText
.
Częstotliwość aktualizacji widżetów
Możesz szybko aktualizować widżety. Może to jednak wpłynąć na żywotność baterii urządzenia. Możesz korzystać z uprzywilejowanego interfejsu API żądania widżetu, który umożliwia częstsze aktualizowanie określonych widżetów. Korzystanie z tego interfejsu API musi jednak być dopuszczone przez producenta zegarka. Każdy producent zegarka decyduje, które widżety mogą aktualizować się szybciej niż jest to dozwolone.