Este guia explica como deixar seu app sempre ativo, como reagir a transições de estado de energia e como gerenciar o comportamento do aplicativo para oferecer uma boa experiência do usuário enquanto economiza bateria.
Tornar um app constantemente visível afeta significativamente a duração da bateria. Por isso, considere o impacto no consumo de energia ao adicionar esse recurso.
Conceitos principais
Quando um app do Wear OS é mostrado em tela cheia, ele está em um de dois estados de energia:
- Interativo: um estado de alta potência em que a tela está com brilho máximo, permitindo interação total do usuário.
- Ambiente: um estado de baixo consumo de energia em que a tela escurece para economizar energia. Nesse estado, a interface do app ainda ocupa a tela inteira, mas o sistema pode alterar a aparência dela desfocando ou sobrepondo conteúdo, como a hora. Isso também é chamado de Modo ambiente.
O sistema operacional controla a transição entre esses estados.
Um app sempre ativo é um aplicativo que mostra conteúdo nos estados Interativo e Ambiente.
Quando um app sempre ativado continua mostrando a própria interface enquanto o dispositivo está no estado de baixo consumo de energia ambiente, ele é descrito como estando no modo ambiactivo.
Transições do sistema e comportamento padrão
Quando um app está em primeiro plano, o sistema gerencia as transições de estado de energia com base em dois tempos limite acionados pela inatividade do usuário.
- Tempo limite 1: estado interativo para ambiente:após um período de inatividade do usuário, o dispositivo entra no estado Ambiente.
- Tempo limite nº 2: voltar ao mostrador do relógio:após um período adicional de inatividade, o sistema pode ocultar o app atual e mostrar o mostrador do relógio.
Logo após o sistema passar pela primeira transição para o estado Ambient, o comportamento padrão depende da versão do Wear OS e da configuração do app:
- No Wear OS 5 e versões anteriores, o sistema mostra uma captura de tela desfocada do aplicativo pausado, com o tempo sobreposto na parte de cima.
- No Wear OS 6 e versões mais recentes, se um app segmentar o SDK 36 ou mais recente, ele será considerado sempre ativo. A tela fica esmaecida, mas o aplicativo continua em execução e visível. As atualizações podem ser tão raras quanto uma vez por minuto.
Personalizar o comportamento do estado Ambiente
Independente do comportamento padrão do sistema, em todas as versões do Wear OS, é possível
personalizar a aparência ou o comportamento do app no estado Ambiental usando
AmbientLifecycleObserver
para detectar callbacks em transições
de estado.
Usar AmbientLifecycleObserver
Para reagir a eventos do modo ambiente, use a classe AmbientLifecycleObserver
:
Implemente a interface
AmbientLifecycleObserver.AmbientLifecycleCallback
. Use o métodoonEnterAmbient()
para ajustar a interface ao estado de baixo consumo de energia eonExitAmbient()
para restaurar a tela interativa completa.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. } }
Crie um
AmbientLifecycleObserver
e registre-o com o ciclo de vida da atividade ou elemento combinável.private val ambientObserver = AmbientLifecycleObserver(activity, ambientCallback) override fun onCreate(savedInstanceState: Bundle) { super.onCreate(savedInstanceState) lifecycle.addObserver(ambientObserver) // ... }
Chame
removeObserver()
para remover o observador emonDestroy()
.
Para desenvolvedores que usam o Jetpack Compose, a biblioteca Horologist oferece uma utilidade útil, o elemento combinável AmbientAware
, que simplifica a implementação desse padrão.
TimeText com reconhecimento de ambiente
Como exceção à necessidade de um observador personalizado, no Wear OS 6, o widget TimeText
é compatível com o modo ambiente. Ele é atualizado automaticamente uma vez por minuto quando o
dispositivo está no estado Ambiente sem nenhum código adicional.
Controlar a duração da tela ativada
As seções a seguir descrevem como gerenciar o tempo que seu app fica na tela.
Evitar voltar ao mostrador do relógio com uma atividade em andamento
Após um período no estado Ambiente (tempo limite nº 2), o sistema normalmente volta ao mostrador do relógio. O usuário pode configurar a duração do tempo limite nas configurações do sistema. Em alguns casos de uso, como um usuário monitorando um treino, um app pode precisar ficar visível por mais tempo.
No Wear OS 5 e em versões mais recentes, é possível evitar isso implementando uma Atividade em andamento. Se o app estiver mostrando informações sobre uma tarefa em andamento do usuário, como uma sessão de treino, use a API Ongoing Activity para manter o app visível até o fim da tarefa. Se um usuário voltar manualmente ao mostrador do relógio, o indicador de atividade em andamento vai oferecer uma maneira de retornar ao seu app com um toque.
Para implementar isso, a intent de toque da notificação em andamento precisa apontar para sua atividade sempre ativa, conforme mostrado no snippet de código a seguir:
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() }
Manter a tela ativada e evitar o estado ambiente
Em casos raros, talvez seja necessário impedir completamente que o dispositivo entre no estado
Ambiente. Ou seja, para evitar o tempo limite 1. Para fazer isso, use a
flag de janela FLAG_KEEP_SCREEN_ON
. Isso funciona como um bloqueio de despertar, mantendo
o dispositivo no estado Interativo. Use com muito cuidado, porque isso
afeta muito a duração da bateria.
Recomendações para o Modo ambiente
Para oferecer a melhor experiência do usuário e economizar energia no modo Ambiente, siga estas diretrizes de design. Essas recomendações priorizam uma experiência do usuário clara, evitando informações enganosas e reduzindo a poluição visual, ao mesmo tempo em que otimizam o poder de exibição.
- Reduza a poluição visual e a potência da tela. Uma interface limpa e minimalista indica ao usuário que o app está em um estado de baixo consumo de energia e economiza bateria significativamente ao limitar pixels brilhantes.
- Mantenha pelo menos 85% da tela preta.
- Mostre apenas as informações mais importantes, movendo os detalhes secundários para a tela interativa.
- Use contornos em vez de preenchimentos sólidos para ícones ou botões grandes.
- Evite grandes blocos de cores sólidas e imagens de marca ou de fundo não funcionais.
- Processar dados dinâmicos desatualizados
- O callback
onUpdateAmbient()
é invocado apenas periodicamente, geralmente uma vez por minuto, para economizar energia. Devido a essa limitação, qualquer dado que mude com frequência, como um cronômetro, frequência cardíaca ou distância do treino, fica desatualizado entre as atualizações. Para evitar mostrar informações enganosas e incorretas, ouça o callbackonEnterAmbient
e substitua esses valores dinâmicos por conteúdo de marcador estático, como--
.
- O callback
- Mantenha um layout consistente
- Mantenha os elementos na mesma posição nos modos Interativo e Ambiente para criar uma transição suave.
- Sempre mostrar a hora.
- Esteja ciente do contexto
- Se o usuário estiver em uma tela de configurações ou configuração quando o dispositivo entrar no modo ambiente, considere mostrar uma tela mais relevante do seu app em vez da visualização de configurações.
- Processar requisitos específicos do dispositivo
- No objeto
AmbientDetails
transmitido paraonEnterAmbient()
:- Se
deviceHasLowBitAmbient
fortrue
, desative a suavização sempre que possível. - Se
burnInProtectionRequired
fortrue
, mova os elementos da interface ligeiramente de forma periódica e evite áreas brancas sólidas para evitar a queima da tela.
- Se
- No objeto
Depuração e testes
Estes comandos adb
podem ser úteis ao desenvolver ou testar o comportamento do app
quando o dispositivo está no modo ambiente:
# 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
Exemplo: app de treino
Considere um app de treino que precisa mostrar métricas ao usuário durante toda a sessão de exercícios. O app precisa permanecer visível durante as transições de estado Ambient e não pode ser substituído pelo mostrador do relógio.
Para isso, o desenvolvedor precisa fazer o seguinte:
- Implemente um
AmbientLifecycleObserver
para processar mudanças na interface entre os estados Interativo e Ambiente, como escurecer a tela e remover dados não essenciais. - Crie um novo layout de baixo consumo de energia para o estado Ambiente que siga as práticas recomendadas.
- Use a API Ongoing Activity durante todo o treino para evitar que o sistema volte ao mostrador do relógio.
Para uma implementação completa, consulte o Exemplo de exercício (link em inglês) baseado no Compose no
GitHub. Este exemplo também demonstra o uso do elemento combinável AmbientAware
da biblioteca Horologist para simplificar o processamento do modo ambiente
no Compose.