Este guia explica como deixar o app sempre ativado, como reagir às transições de estado de energia e como gerenciar o comportamento do aplicativo para oferecer uma boa experiência ao usuário e economizar bateria.
Tornar um app constantemente visível afeta significativamente a duração da bateria. Portanto, considere o impacto de energia ao adicionar esse recurso.
Conceitos principais
Quando um app do Wear OS aparece em tela cheia, ele está em um dos dois estados de energia:
- Interativo: um estado de alta potência em que a tela está com brilho total, permitindo a interação total do usuário.
- Ambiente: um estado de baixo consumo de energia em que a tela fica escura para economizar energia. Nesse estado, a interface do app ainda ocupa a tela inteira, mas o sistema pode alterar a aparência desfocando ou sobrepondo o conteúdo, como o tempo. Isso também é chamado de modo ambiente.
O sistema operacional controla a transição entre esses estados.
Um app sempre ativado é 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 Ambient de baixo consumo de energia, ele é descrito como estando no modo ambiativo.
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 2: retorno ao mostrador do relógio:após um período de inatividade, o sistema pode ocultar o app atual e mostrar o mostrador do relógio.
Imediatamente 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 app pausado, com o tempo sobreposto na parte de cima.
- No Wear OS 6 e mais recentes, se um app for direcionado ao SDK 36 ou mais recente, ele será considerado sempre ativado. A tela fica escura, mas o aplicativo continua executando e permanece visível. As atualizações podem ser tão infrequentes quanto uma por minuto.
Personalizar o comportamento do estado do Modo ambiente
Independentemente 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 enquanto ele está no estado Ambient
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 pouca energia eonExitAmbient()
para restaurá-la à 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 do 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 um utilitário
útil, o elemento combinável AmbientAware
, que simplifica a implementação
desse padrão.
TimeText com detecção de ambiente
Como exceção à necessidade de um observador personalizado, no Wear OS 6, o widget
TimeText
é sensível ao ambiente. Ele é atualizado automaticamente uma vez por minuto quando o
dispositivo está no estado Ambient sem nenhum código extra.
Controlar a duração da tela ligada
As seções a seguir descrevem como gerenciar o tempo que o app permanece na tela.
Impedir o retorno ao mostrador do relógio com uma atividade em andamento
Após um período no estado Ambient (tempo limite 2), o sistema normalmente retorna 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 que está rastreando um treino, o app pode precisar permanecer 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 do usuário em andamento, 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 retornar manualmente ao mostrador do relógio, o indicador de atividade em andamento vai permitir que ele retorne ao app com um toque.
Para implementar isso, a intent de toque da notificação em andamento precisa apontar para a atividade sempre ativa, conforme mostrado no snippet de código abaixo:
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 ligada e impedir o estado de ambiente
Em casos raros, talvez seja necessário impedir completamente que o dispositivo entre no
estado Ambient. Ou seja, para evitar o Timeout 1. Para fazer isso, use a
flag de janela FLAG_KEEP_SCREEN_ON
. Isso funciona como um bloqueio de ativação, mantendo
o dispositivo no estado Interativo. Use com extrema cautela, porque isso
afeta significativamente 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 Ambient, siga estas diretrizes de design.
- Usar uma tela minimalista e de baixo consumo de energia
- Mantenha pelo menos 85% da tela preta.
- Use contornos para ícones ou botões grandes em vez de preenchimentos sólidos.
- Mostre apenas as informações mais importantes, movendo os detalhes secundários para a tela interativa.
- Evite grandes blocos de cores sólidas e branding não funcional ou imagens de plano de fundo.
- Atualizar o conteúdo de forma adequada
- Para dados que mudam com frequência, como um cronômetro, a distância do treino ou
o tempo, mostre conteúdo de marcador de posição, como
--
, para evitar a impressão de que o conteúdo é novo. - Remova os indicadores de progresso que são atualizados continuamente, como os toques de contagem regressiva e as sessões de mídia.
- O callback
onUpdateAmbient()
só deve ser usado para atualizações essenciais, normalmente uma vez por minuto.
- Para dados que mudam com frequência, como um cronômetro, a distância do treino ou
o tempo, mostre conteúdo de marcador de posição, como
- Manter um layout consistente
- Mantenha os elementos na mesma posição nos modos Interativo e Ambiente para criar uma transição suave.
- Mostre sempre a hora.
- Conhecer o contexto
- Se o usuário estava em uma tela de configurações ou de configuração quando o dispositivo entrou no modo ambiente, mostre uma tela mais relevante do 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
, mude os elementos da interface periodicamente 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 para o usuário durante toda a sessão de exercícios. O app precisa permanecer visível durante as transições de estado Ambient e evitar ser substituído pelo mostrador do relógio.
Para fazer isso, o desenvolvedor precisa:
- 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 para o estado Ambient que siga as práticas recomendadas.
- Use a API Ongoing Activity durante o treino para evitar que o sistema retorne ao mostrador do relógio.
Para uma implementação completa, consulte o exercício de exemplo (link em inglês) baseado no Compose no
GitHub. Esse exemplo também demonstra o uso do elemento combinável AmbientAware
da biblioteca Horologist para simplificar o processamento do modo ambiente
no Compose.