In diesem Leitfaden wird erläutert, wie Sie Ihre App so gestalten, dass sie immer aktiv ist, wie Sie auf Änderungen des Energiestatus reagieren und wie Sie das Verhalten der Anwendung so verwalten, dass sie Akkuleistung spart und gleichzeitig eine gute Nutzererfahrung bietet.
Wenn eine App ständig sichtbar ist, wirkt sich das erheblich auf die Akkulaufzeit aus. Berücksichtigen Sie daher die Auswirkungen auf den Akku, wenn Sie diese Funktion hinzufügen.
Schlüsselkonzepte
Wenn eine Wear OS-App im Vollbildmodus angezeigt wird, befindet sie sich in einem von zwei Energiezuständen:
- Interaktiv: Ein Zustand mit hohem Stromverbrauch, in dem der Bildschirm die volle Helligkeit hat und Nutzer uneingeschränkt interagieren können.
- Umgebungsmodus: Ein Energiesparmodus, in dem das Display gedimmt wird, um Strom zu sparen. In diesem Zustand belegt die Benutzeroberfläche Ihrer App weiterhin den gesamten Bildschirm, das System kann jedoch ihr Erscheinungsbild ändern, indem es sie unkenntlich macht oder Inhalte wie die Uhrzeit einblendet. Dies wird auch als Inaktivmodus bezeichnet.
Das Betriebssystem steuert den Übergang zwischen diesen Status.
Eine Always-On-App ist eine Anwendung, die Inhalte sowohl im interaktiven als auch im Inaktivitätsmodus anzeigt.
Wenn eine Always-on-App weiterhin ihre eigene Benutzeroberfläche anzeigt, während sich das Gerät im Energiesparmodus Ambient befindet, wird sie als ambiactive mode bezeichnet.
Systemübergänge und Standardverhalten
Wenn sich eine App im Vordergrund befindet, verwaltet das System Übergänge des Energiezustands basierend auf zwei Zeitüberschreitungen, die durch Inaktivität des Nutzers ausgelöst werden.
- Zeitüberschreitung 1: Interaktiv zu Inaktivmodus:Nach einer gewissen Zeit der Inaktivität des Nutzers wechselt das Gerät in den Status Inaktivmodus.
- Zeitüberschreitung 2: Zum Zifferblatt zurückkehren:Nach einem weiteren Zeitraum der Inaktivität kann das System die aktuelle App ausblenden und das Zifferblatt anzeigen.
Unmittelbar nach dem ersten Übergang des Systems in den Status Ambient hängt das Standardverhalten von der Wear OS-Version und der Konfiguration Ihrer App ab:
- Auf Wear OS 5 und niedriger zeigt das System einen verschwommenen Screenshot der pausierten App mit der darüber gelegten Uhrzeit an.
- Unter Wear OS 6 und höher gilt eine App, die auf SDK 36 oder höher ausgerichtet ist, als Always-on-App. Das Display wird gedimmt, die Anwendung wird aber weiterhin ausgeführt und bleibt sichtbar. Aktualisierungen können bis zu einmal pro Minute erfolgen.
Verhalten für den Inaktivmodus anpassen
Unabhängig vom Standardverhalten des Systems können Sie auf allen Wear OS-Versionen das Erscheinungsbild oder Verhalten Ihrer App im Ambient-Zustand anpassen, indem Sie AmbientLifecycleObserver
verwenden, um auf Callbacks bei Zustandsübergängen zu warten.
AmbientLifecycleObserver verwenden
Verwende die Klasse AmbientLifecycleObserver
, um auf Ereignisse im Ambient-Modus zu reagieren:
Implementieren Sie die
AmbientLifecycleObserver.AmbientLifecycleCallback
-Schnittstelle. Verwenden Sie die MethodeonEnterAmbient()
, um die Benutzeroberfläche für den Energiesparmodus anzupassen, undonExitAmbient()
, um sie wieder auf die vollständige interaktive Anzeige zurückzusetzen.val ambientCallback = object : AmbientLifecycleObserver.AmbientLifecycleCallback { override fun onEnterAmbient(ambientDetails: AmbientLifecycleObserver.AmbientDetails) { // ... Called when moving from interactive mode into ambient mode. // Adjust UI for low-power state: dim colors, hide non-essential elements. } override fun onExitAmbient() { // ... Called when leaving ambient mode, back into interactive mode. // Restore full UI. } override fun onUpdateAmbient() { // ... Called by the system periodically (typically once per minute) // to allow the app to update its display while in ambient mode. } }
Erstellen Sie ein
AmbientLifecycleObserver
und registrieren Sie es im Lebenszyklus Ihrer Aktivität oder Ihres Composables.private val ambientObserver = AmbientLifecycleObserver(activity, ambientCallback) override fun onCreate(savedInstanceState: Bundle) { super.onCreate(savedInstanceState) lifecycle.addObserver(ambientObserver) // ... }
Rufen Sie
removeObserver()
auf, um den Observer inonDestroy()
zu entfernen.
Für Entwickler, die Jetpack Compose verwenden, bietet die Horologist-Bibliothek mit dem zusammensetzbaren AmbientAware
-Element ein hilfreiches Tool, das die Implementierung dieses Musters vereinfacht.
Umgebungsabhängiger TimeText
Als Ausnahme von der Anforderung eines benutzerdefinierten Beobachters ist das TimeText
-Widget unter Wear OS 6 umgebungsbewusst. Sie wird automatisch einmal pro Minute aktualisiert, wenn sich das Gerät im Ambient-Modus befindet. Dazu ist kein zusätzlicher Code erforderlich.
Dauer der Displayaktivierung festlegen
In den folgenden Abschnitten wird beschrieben, wie Sie festlegen, wie lange Ihre App auf dem Bildschirm angezeigt wird.
Rückkehr zum Zifferblatt bei laufender Aktivität verhindern
Nach einer bestimmten Zeit im Ambient-Status (Timeout 2) kehrt das System in der Regel zum Zifferblatt zurück. Der Nutzer kann die Zeitüberschreitungsdauer in den Systemeinstellungen konfigurieren. In bestimmten Anwendungsfällen, z. B. wenn ein Nutzer ein Training aufzeichnet, muss eine App möglicherweise länger sichtbar bleiben.
Bei Wear OS 5 und höher können Sie dies verhindern, indem Sie eine laufende Aktivität implementieren. Wenn in Ihrer App Informationen zu einer laufenden Nutzeraufgabe wie einem Training angezeigt werden, können Sie mit der Ongoing Activity API dafür sorgen, dass Ihre App bis zum Ende der Aufgabe sichtbar bleibt. Wenn ein Nutzer manuell zum Zifferblatt zurückkehrt, kann er über die Anzeige für laufende Aktivitäten mit nur einem Tippen zu Ihrer App zurückkehren.
Dazu muss der Touch-Intent der laufenden Benachrichtigung auf Ihre Always-On-Aktivität verweisen, wie im folgenden Code-Snippet gezeigt:
private fun createNotification(): Notification { 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) return notificationBuilder.build() }
Display aktiviert lassen und Inaktivmodus verhindern
In seltenen Fällen müssen Sie möglicherweise vollständig verhindern, dass das Gerät in den Inaktivmodus wechselt. So vermeiden Sie das erste Zeitlimit. Verwenden Sie dazu das Fenster-Flag FLAG_KEEP_SCREEN_ON
. Dies funktioniert wie eine Aktivierungssperre, die das Gerät im Status Interaktiv hält. Verwenden Sie diese Funktion mit äußerster Vorsicht, da sie die Akkulaufzeit erheblich beeinträchtigt.
Empfehlungen für den Inaktivmodus
Damit die Nutzerfreundlichkeit optimiert und der Akku im Ambient-Modus geschont wird, solltest du diese Designrichtlinien beachten.
- Minimalistisches Display mit geringem Stromverbrauch verwenden
- Mindestens 85% des Bildschirms müssen schwarz sein.
- Verwenden Sie für große Symbole oder Schaltflächen Umrisslinien anstelle von Volltonfarben.
- Zeigen Sie nur die wichtigsten Informationen an und verschieben Sie sekundäre Details auf das interaktive Display.
- Vermeiden Sie große Blöcke mit einfarbigen Hintergründen und nicht funktionalem Branding oder Hintergrundbildern.
- Inhalte angemessen aktualisieren
- Bei sich häufig ändernden Daten wie einer Stoppuhr, einer Trainingsdistanz oder der Uhrzeit sollten Sie Platzhalterinhalte wie
--
anzeigen, um nicht den Eindruck zu erwecken, dass die Inhalte aktuell sind. - Entfernen Sie Fortschrittsanzeigen, die kontinuierlich aktualisiert werden, z. B. Countdown-Ringe und Mediensitzungen.
- Der
onUpdateAmbient()
-Callback sollte nur für wichtige Updates verwendet werden, in der Regel einmal pro Minute.
- Bei sich häufig ändernden Daten wie einer Stoppuhr, einer Trainingsdistanz oder der Uhrzeit sollten Sie Platzhalterinhalte wie
- Einheitliches Layout beibehalten
- Achten Sie darauf, dass Elemente im Interaktiven Modus und im Ambient-Modus an derselben Position sind, um einen reibungslosen Übergang zu ermöglichen.
- Die Uhrzeit immer anzeigen.
- Kontext berücksichtigen
- Wenn sich der Nutzer auf einem Einstellungs- oder Konfigurationsbildschirm befand, als das Gerät in den Inaktivmodus wechselte, sollten Sie in Ihrer App einen relevanteren Bildschirm anstelle der Einstellungen anzeigen.
- Gerätespezifische Anforderungen berücksichtigen
- Im
AmbientDetails
-Objekt, das anonEnterAmbient()
übergeben wurde:- Wenn
deviceHasLowBitAmbient
true
ist, deaktivieren Sie das Antialiasing, sofern möglich. - Wenn
burnInProtectionRequired
gleichtrue
ist, verschieben Sie die UI-Elemente regelmäßig leicht und vermeiden Sie rein weiße Bereiche, um ein Einbrennen des Displays zu verhindern.
- Wenn
- Im
Debugging und Tests
Diese adb
-Befehle können beim Entwickeln oder Testen des Verhaltens Ihrer App im Inaktivmodus hilfreich sein:
# 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
Beispiel: Trainings-App
Stellen Sie sich eine Trainings-App vor, die dem Nutzer während des gesamten Trainings Messwerte anzeigen muss. Die App muss während der Übergänge in den Ambient-Status sichtbar bleiben und darf nicht durch das Zifferblatt ersetzt werden.
Dazu sollte der Entwickler Folgendes tun:
- Implementiere eine
AmbientLifecycleObserver
, um UI-Änderungen zwischen den Status Interaktiv und Ambient zu verarbeiten, z. B. das Dimmen des Displays und das Entfernen nicht benötigter Daten. - Erstelle ein neues Layout mit geringem Stromverbrauch für den Ambient-Modus, das den Best Practices entspricht.
- Verwende die Ongoing Activity API während des Trainings, um zu verhindern, dass das System zum Zifferblatt zurückkehrt.
Eine vollständige Implementierung finden Sie im Compose-basierten Übungsbeispiel auf GitHub. In diesem Beispiel wird auch die Verwendung des zusammensetzbaren AmbientAware
aus der Horologist-Bibliothek veranschaulicht, um die Verarbeitung des Inaktivmodus in Compose zu vereinfachen.