Z tego przewodnika dowiesz się, jak sprawić, aby aplikacja była zawsze włączona, jak reagować na zmiany stanu zasilania i jak zarządzać działaniem aplikacji, aby zapewnić użytkownikom komfort korzystania z niej przy jednoczesnym oszczędzaniu baterii.
Ciągłe wyświetlanie aplikacji ma znaczący wpływ na czas pracy baterii, więc podczas dodawania tej funkcji należy wziąć pod uwagę zużycie energii.
Kluczowe pojęcia
Gdy aplikacja na Wear OS jest wyświetlana na pełnym ekranie, może być w jednym z 2 stanów zasilania:
- Interaktywny: stan wysokiego poboru mocy, w którym ekran ma pełną jasność i umożliwia pełną interakcję z użytkownikiem.
- Wygaszacz: stan niskiego zużycia energii, w którym wyświetlacz przyciemnia się, aby oszczędzać energię. W tym stanie interfejs aplikacji nadal zajmuje cały ekran, ale system może zmienić jego wygląd, rozmywając go lub wyświetlając nakładkę, np. z godziną. Jest to też nazywane oświetleniem kinowym.
System operacyjny kontroluje przejście między tymi stanami.
Aplikacja zawsze włączona to aplikacja, która wyświetla treści w trybach interaktywnym i otoczenia.
Gdy zawsze aktywna aplikacja nadal wyświetla swój interfejs, gdy urządzenie jest w stanie niskiego zużycia energii Ambient, mówimy, że jest w trybie ambiactive.
Przejścia systemowe i domyślne zachowanie
Gdy aplikacja działa na pierwszym planie, system zarządza przejściami między stanami zasilania na podstawie 2 limitów czasu aktywowanych przez nieaktywność użytkownika.
- Limit czasu 1: stan interaktywny do stanu otoczenia: po okresie nieaktywności użytkownika urządzenie przechodzi w stan otoczenia.
- Limit czasu 2: powrót do tarczy zegarka:po kolejnym okresie braku aktywności system może ukryć bieżącą aplikację i wyświetlić tarczę zegarka.
Natychmiast po przejściu systemu w stan Ambient domyślne działanie zależy od wersji Wear OS i konfiguracji aplikacji:
- Na Wear OS 5 i starszych wersjach system wyświetla rozmyty zrzut ekranu wstrzymanej aplikacji z nałożonym na niego czasem. Ten stan jest reprezentowany przez węzeł „AOD Lite” na tym schemacie blokowym.
- Na Wear OS 6 i nowszych wersjach, jeśli aplikacja jest kierowana na pakiet SDK 36 lub nowszy, jest uznawana za zawsze włączoną. Wyświetlacz jest przyciemniony, ale aplikacja nadal działa i jest widoczna. (Aktualizacje mogą być rzadsze niż raz na minutę). Ten stan jest reprezentowany przez węzeł „Global AOD” na tym schemacie blokowym.
Dostosowywanie działania w stanie Ambient
Niezależnie od domyślnego działania systemu we wszystkich wersjach Wear OS możesz dostosować wygląd lub działanie aplikacji w stanie Ambient, używając LocalAmbientModeManager do obserwowania przejść stanu w Jetpack Compose na Wear OS. Ten stan jest reprezentowany przez węzeł „Tryb Ambiactive” na tym schemacie blokowym.
Obserwowanie stanu otoczenia
Aby reagować na zdarzenia w trybie nieaktywnym w Jetpack Compose na Wear OS:
Użyj
LocalAmbientModeManager, aby obserwować zmiany stanu trybu otoczenia systemu i odpowiednio dostosowywać elementy kompozycyjne. Skonfiguruj komponent tak, aby przełączał się w tryb niskiego zużycia energii w stanieAmbientMode.Ambienti wracał do pełnego interaktywnego wyświetlania w stanieAmbientMode.Interactive.// In a production application, the AmbientModeManager should be instantiated and provided at // the highest level of the Compose hierarchy (typically in the host Activity's setContent // block) using a CompositionLocalProvider. This ensures proper lifecycle management and // broad accessibility. // For this self-contained demo, AmbientModeManager is created and provided locally: val activityAmbientModeManager = rememberAmbientModeManager() CompositionLocalProvider(LocalAmbientModeManager provides activityAmbientModeManager) { val ambientModeManager = LocalAmbientModeManager.current val ambientMode = ambientModeManager?.currentAmbientMode if (ambientModeManager != null) { ambientModeManager.AmbientTickEffect { // While device is in ambient mode, update properties every minute or so // ... } } // ... val ambientModeName = when (ambientMode) { is AmbientMode.Interactive -> "Interactive" is AmbientMode.Ambient -> "Ambient" else -> "Unknown" } Text(text = "$ambientModeName Mode") // ... }
Schemat blokowy działania w trybie otoczenia
Poniższy schemat blokowy pokazuje, jak system określa zachowanie w trybie otoczenia na podstawie wersji Wear OS na urządzeniu, wartości targetSdkVersion w aplikacji i tego, czy aplikacja obserwuje przejścia do trybu otoczenia (za pomocą LocalAmbientModeManager lub AmbientLifecycleCallback).
Kontrolowanie czasu włączenia ekranu
W sekcjach poniżej znajdziesz informacje o tym, jak zarządzać czasem wyświetlania aplikacji na ekranie.
Zapobieganie powrotowi do tarczy zegarka z aktywnością w toku lub aktualizacją na żywo
Po pewnym czasie w stanie Ambient (Timeout 2) system zwykle wraca do tarczy zegara. Użytkownik może skonfigurować czas trwania limitu czasu w ustawieniach systemu. W niektórych przypadkach, np. gdy użytkownik śledzi trening, aplikacja może potrzebować dłuższego czasu widoczności.
W przypadku Wear OS 5 i nowszych możesz temu zapobiec, wdrażając OngoingActivity. Jeśli aplikacja wyświetla informacje o trwającym zadaniu użytkownika, np. o sesji treningowej, możesz użyć interfejsu Ongoing Activity API, aby aplikacja była widoczna do czasu zakończenia zadania. Jeśli użytkownik ręcznie wróci do tarczy zegarka, wskaźnik trwającej aktywności umożliwi mu powrót do aplikacji jednym kliknięciem.
Na Wear OS 7 i nowszych możesz też użyć aktualizacji na żywo zamiast trwającej aktywności. Aby zachować zgodność wsteczną, nadal obsługuj trwającą aktywność na urządzeniach z Wear OS 6 lub starszym.
Aby to zrobić, intencja dotknięcia trwałego powiadomienia musi wskazywać aktywność zawsze włączoną, jak pokazano w tym fragmencie kodu:
val activityIntent = Intent(this, AlwaysOnActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_SINGLE_TOP } val pendingIntent = PendingIntent.getActivity( this, 0, activityIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, ) val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID) // ... // ... .setOngoing(true) // ... val ongoingActivity = OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder) // ... // ... .setTouchIntent(pendingIntent) .build() ongoingActivity.apply(applicationContext) val notification = notificationBuilder.build()
Pozostawianie włączonego ekranu i zapobieganie przejściu w stan nieaktywny
W rzadkich przypadkach może być konieczne całkowite uniemożliwienie przejścia urządzenia w stan nieaktywny. Chodzi o uniknięcie przekroczenia limitu czasu 1. Możesz do tego użyć modyfikatora keepScreenOn. Działa to jak blokada uśpienia, która utrzymuje urządzenie w stanie interaktywnym. Używaj tej opcji z dużą ostrożnością, ponieważ ma ona duży wpływ na czas pracy baterii.
Rekomendacje dotyczące trybu nieaktywnego
Aby zapewnić użytkownikom jak najlepsze wrażenia i oszczędzać energię w trybie Ambient, postępuj zgodnie z tymi wytycznymi dotyczącymi projektowania. Te rekomendacje stawiają na pierwszym miejscu wygodę użytkowników, zapobiegając wprowadzaniu ich w błąd i ograniczając nadmiar informacji wizualnych, a jednocześnie optymalizując moc wyświetlania.
- Ogranicz wizualny bałagan i zmniejsz zużycie energii przez wyświetlacz. Czysty, minimalistyczny interfejs sygnalizuje użytkownikowi, że aplikacja jest w stanie niskiego zużycia energii, i znacznie oszczędza baterię, ograniczając jasne piksele.
- Co najmniej 85% ekranu musi być czarne (stosunek włączonych pikseli do wszystkich pikseli musi wynosić 15% lub mniej).
- Wyświetlaj tylko najważniejsze informacje, a szczegóły dodatkowe przenieś na wyświetlacz interaktywny.
- W przypadku dużych ikon lub przycisków używaj konturów zamiast pełnych wypełnień. Dostosuj kontrast konturów, aby elementy były czytelne bez ryzyka migotania ekranu lub wypalenia.
- Unikaj dużych bloków jednolitego koloru oraz niedziałających elementów marki lub obrazów tła.
- Obsługa nieaktualnych danych dynamicznych i animacji
- Wywołanie zwrotne
AmbientTickEffectjest wywoływane tylko okresowo – zwykle raz na minutę – aby oszczędzać energię. Z tego powodu wszelkie dane, które często się zmieniają, np. stoper, tętno czy dystans treningu, stają się nieaktualne między aktualizacjami. Aby uniknąć wyświetlania wprowadzających w błąd i nieprawidłowych informacji, zastąp te wartości na żywo statyczną treścią zastępczą, np.--. - Usuń wskaźniki postępu, które wymagają częstych aktualizacji, aby były przydatne w bieżącym kontekście lub sytuacji użytkownika, np. pierścienie postępu w przypadku krótkich sesji multimedialnych. Możesz zachować wskaźniki postępu, w przypadku których aktualizacje raz na minutę nadal są przydatne, np. w przypadku długich minutników.
- Wstrzymaj lub usuń wszystkie animacje w trybie otoczenia, w tym animowane wskaźniki postępu i przewijany tekst.
- Wywołanie zwrotne
- Zachowaj spójny układ
- Zachowaj elementy w tej samej pozycji w trybach Interaktywnym i Ambient, aby zapewnić płynne przejście. Interaktywne elementy interfejsu, takie jak przyciski, mogą pozostać widoczne, ponieważ nowoczesne urządzenia z Wear OS obsługują dotyk podczas sesji w trybie otoczenia.
- Zawsze wyświetlaj bieżący czas. W Jetpack Compose na Wear OS
TimeText(domyślnie uwzględniony wScreenScaffold) jest dostosowany do trybu otoczenia i automatycznie aktualizuje się raz na minutę w tym trybie.
- Uwzględniaj kontekst
- Jeśli w momencie przejścia urządzenia w tryb otoczenia użytkownik był na ekranie ustawień lub konfiguracji, rozważ wyświetlenie bardziej odpowiedniego ekranu z Twojej aplikacji zamiast widoku ustawień.
- Obsługa wymagań dotyczących konkretnych urządzeń
- Gdy
currentAmbientModezwracaAmbientMode.Ambient:- Jeśli
isLowBitAmbientSupportedma wartośćtrue, wyświetlacz obsługuje mniej bitów na kolor w trybie otoczenia. Wyłącz wygładzanie (np. w niestandardowych operacjach rysowaniaCanvaslubPaint) i w miarę możliwości unikaj gradientów kolorów. - Jeśli
isBurnInProtectionRequiredma wartośćtrue, system okresowo przesuwa wyświetlane treści, aby zapobiec wypaleniu pikseli. Nie przesuwaj ręcznie elementów interfejsu w aplikacji. Zamiast tego unikaj jednolitych białych obszarów i umieszczaj kluczowe elementy interfejsu co najmniej 10 pikseli od krawędzi ekranu, aby nie zostały ucięte, gdy system przesunie wyświetlacz. (Standardowe układy Wear Compose, takie jakScreenScaffold, zapewniają już wystarczające dopełnienie krawędzi).
- Jeśli
- Gdy
Debugowanie i testowanie
Te polecenia adb mogą być przydatne podczas programowania lub testowania działania aplikacji, gdy urządzenie jest w trybie otoczenia:
# put device in ambient mode if the always on display is enabled in settings
# (and not disabled by other settings, such as theatre mode)
$ adb shell input keyevent KEYCODE_SLEEP
# put device in interactive mode
$ adb shell input keyevent KEYCODE_WAKEUP
Przykład: aplikacja do treningu
Weźmy pod uwagę aplikację do ćwiczeń, która musi wyświetlać użytkownikowi dane przez cały czas trwania sesji treningowej. Aplikacja musi być widoczna podczas przechodzenia w stan Ambient i nie może być zastępowana przez tarczę zegarka.
Aby to zrobić, deweloper powinien wykonać te czynności:
- Używaj
LocalAmbientModeManager, aby obsługiwać zmiany interfejsu między stanami interaktywnym i otoczenia, np. przyciemnianie ekranu i usuwanie nieistotnych danych. - Utwórz nowy układ o niskim poborze mocy dla stanu Ambient, który jest zgodny ze sprawdzonymi metodami.
- Używaj interfejsu Ongoing Activity API (lub Aktualizacji na żywo na Wear OS 7 i nowszych) przez cały czas trwania treningu, aby zapobiec powrotowi systemu do tarczy zegarka.
Pełną implementację znajdziesz w przykładowej aplikacji do ćwiczeń opartej na Compose w GitHubie. Ten przykład pokazuje też, jak używać funkcji kompozycyjnej
LocalAmbientModeManager, aby uprościć obsługę trybu otoczenia
w Compose.