Questa guida spiega come rendere la tua app sempre attiva, come reagire alle transizioni dello stato di alimentazione e come gestire il comportamento dell'applicazione per offrire una buona esperienza utente risparmiando batteria.
Rendere un'app costantemente visibile ha un impatto significativo sulla durata della batteria, quindi valuta l'impatto sul consumo energetico quando aggiungi questa funzionalità.
Concetti principali
Quando un'app per Wear OS viene visualizzata a schermo intero, si trova in uno dei due stati di alimentazione:
- Interattivo: uno stato di elevato consumo energetico in cui lo schermo è alla massima luminosità, consentendo la piena interazione dell'utente.
- Ambientale: uno stato di basso consumo energetico in cui la luminosità del display si riduce per risparmiare energia. In questo stato, la UI dell'app occupa ancora l'intero schermo, ma il sistema potrebbe modificarne l'aspetto sfocandolo o mostrando contenuti di overlay come l'ora. Questa modalità è nota anche come modalità Ambient.
Il sistema operativo controlla la transizione tra questi stati.
Un'app sempre attiva è un'applicazione che mostra contenuti sia nello stato interattivo che in quello ambient.
Quando un'app sempre attiva continua a visualizzare la propria UI mentre il dispositivo è in modalità Ambient a basso consumo energetico, viene descritta come in modalità ambiactive.
Transizioni di sistema e comportamento predefinito
Quando un'app è in primo piano, il sistema gestisce le transizioni dello stato di alimentazione in base a due timeout attivati dall'inattività dell'utente.
- Timeout n. 1: stato interattivo a stato Ambient:dopo un periodo di inattività dell'utente, il dispositivo entra nello stato Ambient.
- Timeout n. 2: ritorno al quadrante. Dopo un ulteriore periodo di inattività, il sistema potrebbe nascondere l'app corrente e mostrare il quadrante.
Subito dopo il primo passaggio del sistema allo stato Ambient, il comportamento predefinito dipende dalla versione di Wear OS e dalla configurazione dell'app:
- Su Wear OS 5 e versioni precedenti, il sistema mostra uno screenshot sfocato dell'applicazione in pausa, con l'ora sovrapposta. Questo stato è rappresentato dal nodo "AOD Lite" nel seguente diagramma di flusso.
- Su Wear OS 6 e versioni successive, se un'app ha come target SDK 36 o versioni successive, viene considerata sempre attiva. Il display è oscurato, ma l'applicazione continua a essere eseguita e rimane visibile. Gli aggiornamenti possono essere eseguiti anche una volta al minuto. Questo stato è rappresentato dal nodo "AOD globale" nel seguente diagramma di flusso.
Personalizzare il comportamento per lo stato Ambient
Indipendentemente dal comportamento predefinito del sistema, in tutte le versioni di Wear OS puoi
personalizzare l'aspetto o il comportamento della tua app nello stato Ambient utilizzando
LocalAmbientModeManager per osservare le transizioni di stato in
Jetpack Compose su Wear OS. Questo stato è rappresentato dal nodo "Modalità Ambiactive"
nel seguente diagramma di flusso.
Osserva lo stato ambientale
Per reagire agli eventi della modalità Ambient in Jetpack Compose su Wear OS:
Utilizza
LocalAmbientModeManagerper osservare le modifiche allo stato della modalità Ambient del sistema e regolare di conseguenza i composable. Configura il componente in modo che passi a una modalità a basso consumo nello statoAmbientMode.Ambiente ripristinalo in modo che visualizzi un display interattivo completo nello statoAmbientMode.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") // ... }
Per gli sviluppatori che utilizzano Jetpack Compose, utilizza LocalAmbientModeManager, che
semplifica l'implementazione di questo pattern.
Diagramma di flusso del comportamento ambientale
Il seguente diagramma di flusso illustra come il sistema determina il comportamento
ambientale in base alla versione di Wear OS del dispositivo, al targetSdkVersion della tua app
e se implementa AmbientLifecycleCallback.
Controllare la durata di accensione dello schermo
Le sezioni seguenti descrivono come gestire la durata di visualizzazione dell'app sullo schermo.
Impedire il ritorno al quadrante con un'attività in corso o un aggiornamento live
Dopo un periodo di tempo nello stato Ambientale (Timeout n. 2), il sistema tornerà in genere al quadrante orologio. L'utente può configurare la durata del timeout nelle impostazioni di sistema. Per alcuni casi d'uso, ad esempio quando un utente monitora un allenamento, un'app potrebbe dover rimanere visibile più a lungo.
Su Wear OS 5 e versioni successive, puoi impedirlo implementando un'attività in corso. Se la tua app mostra informazioni su un'attività utente in corso, come una sessione di allenamento, puoi utilizzare l'API Ongoing Activity per mantenere la tua app visibile fino al termine dell'attività. Se un utente torna manualmente al quadrante, l'indicatore dell'attività continua gli consente di tornare alla tua app con un solo tocco.
In alternativa, su Wear OS 7 e versioni successive, puoi utilizzare un aggiornamento live al posto di un'attività in corso. Per la compatibilità con le versioni precedenti, continua a supportare Attività in corso sui dispositivi con Wear OS 6 o versioni precedenti.
Per implementare questa funzionalità, l'intent di tocco della notifica continua deve puntare all'attività sempre attiva, come mostrato nello snippet di codice seguente:
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()
Mantenere lo schermo attivo ed evitare lo stato Ambient
In rari casi, potrebbe essere necessario impedire completamente al dispositivo di entrare nello stato
Ambient. ovvero per evitare il timeout n. 1. Per farlo, puoi utilizzare il modificatore
keepScreenOn. Questa funzione funge da wakelock, mantenendo
il dispositivo nello stato Interattivo. Utilizza questa opzione con estrema cautela, in quanto
influisce notevolmente sulla durata della batteria.
Suggerimenti per la modalità Ambient
Per offrire la migliore esperienza utente e risparmiare energia in modalità Ambient, segui queste linee guida di progettazione. Questi consigli danno la priorità a un'esperienza utente chiara, evitando informazioni fuorvianti e riducendo il disordine visivo, ottimizzando al contempo il consumo energetico del display.
- Ridurre il disordine visivo e la potenza del display. Un'interfaccia utente pulita e minimalista indica
all'utente che l'app è in stato di risparmio energetico e consente di risparmiare
molta batteria limitando i pixel luminosi.
- Mantieni almeno l'85% dello schermo nero.
- Mostra solo le informazioni più importanti, spostando i dettagli secondari sul display interattivo.
- Utilizza contorni per icone o pulsanti di grandi dimensioni anziché riempimenti pieni.
- Evita grandi blocchi di colore uniforme e immagini di branding o di sfondo non funzionali.
- Gestire i dati dinamici obsoleti
- Il callback
AmbientTickEffectviene richiamato solo periodicamente, in genere una volta al minuto, per risparmiare energia. A causa di questa limitazione, tutti i dati che cambiano di frequente, come un cronometro, la frequenza cardiaca o la distanza dell'allenamento, diventano obsoleti tra gli aggiornamenti. Per evitare di mostrare informazioni fuorvianti e errate, sostituisci questi valori live con contenuti segnaposto statici, ad esempio--.
- Il callback
- Mantenere un layout coerente
- Mantieni gli elementi nella stessa posizione nelle modalità Interattiva e Ambient per creare una transizione fluida.
- Mostra sempre l'ora.
- Essere sensibile al contesto
- Se l'utente si trovava in una schermata di impostazioni o configurazione quando il dispositivo entra in modalità Ambient, valuta la possibilità di mostrare una schermata più pertinente della tua app anziché la visualizzazione delle impostazioni.
- Gestire i requisiti specifici per i dispositivi
- Nell'oggetto
AmbientModerestituito dacurrentAmbientMode:- Se
isLowBitAmbientSupportedètrue, disattiva l'anti-aliasing, se possibile. - Se
isBurnInProtectionRequiredètrue, sposta periodicamente gli elementi dell'interfaccia utente leggermente ed evita le aree bianche piene per evitare il burn-in dello schermo.
- Se
- Nell'oggetto
Debug e test
Questi comandi adb possono essere utili durante lo sviluppo o il test del comportamento dell'app quando il dispositivo è in modalità Ambient:
# 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
Esempio: app di allenamento
Prendi in considerazione un'app di allenamento che deve mostrare le metriche all'utente per l'intera durata della sessione di allenamento. L'app deve rimanere visibile durante le transizioni di stato Ambient ed evitare di essere sostituita dal quadrante orologio.
Per farlo, lo sviluppatore deve:
- Utilizza
LocalAmbientModeManagerper gestire le modifiche dell'interfaccia utente tra gli stati Interattivo e Ambientale, ad esempio oscurando lo schermo e rimuovendo i dati non essenziali. - Crea un nuovo layout a basso consumo energetico per lo stato Ambient che segue le best practice.
- Utilizza l'API per le attività continue (o Aggiornamenti live su Wear OS 7 e versioni successive) per tutta la durata dell'allenamento per impedire al sistema di tornare al quadrante.
Per un'implementazione completa, consulta l'esempio di esercizio basato su Compose su
GitHub. Questo esempio mostra anche l'utilizzo del
LocalAmbientModeManager componibile per semplificare la gestione della modalità Ambient
in Compose.