Apps sempre ativados e modo ambiente do sistema

O Wear OS processa automaticamente a transição para o modo de baixo consumo de energia em apps ativos quando o usuário não está mais usando o relógio. Isso é chamado de modo ambiente do sistema. O app é retomado depois que o usuário interage com o relógio se alguma das seguintes condições for atendida:

  • A interação do usuário ocorre em um determinado período (antes do tempo limite).
  • O app declara e inicia uma atividade em andamento.

Para casos de uso específicos, por exemplo, quando o usuário quer conferir a frequência cardíaca e o ritmo durante uma corrida, também é possível controlar quais informações são exibidas no modo ambiente do sistema. Os apps para Wear OS que são executados nos modos ambiente e interativo são chamados de apps sempre ativados.

Tornar um app constantemente visível afeta a duração da bateria. Por isso, considere esse impacto ao adicionar esse recurso ao app.

Configurar seu projeto

Para oferecer suporte ao modo ambiente, siga estas etapas:

  1. Crie ou atualize seu projeto com base nas configurações da página Criar e executar um app para wearables.
  2. (Somente necessário no Wear OS 4 ou versões anteriores) Adicione a permissão WAKE_LOCK ao arquivo de manifesto do Android:
<uses-permission android:name="android.permission.WAKE_LOCK" android:maxSdkVersion="33"/>

Ativar o modo sempre ativado

A partir do Wear OS 6, os apps com targetSdkVersion definido como 36 ou mais estão sempre ativos por padrão. Esses apps permanecem visíveis durante o modo ambiente do sistema por um período limitado sem nenhuma configuração. Se o targetSdkVersion do app for menor que 36 ou se ele precisar ser executado no Wear OS 5 ou anterior, use a classe AmbientLifecycleObserver para deixar o app sempre ativado.

Reagir a eventos do modo ambiente usando a classe AmbientLifecycleObserver

Os apps também podem usar a classe AmbientLifecycleObserver para reagir diretamente aos eventos do modo ambiente:

  1. Implemente a interface AmbientLifecycleObserver.AmbientLifecycleCallback, como no exemplo abaixo. Nesta fase, os métodos estão vazios, mas mais adiante no guia vamos apresentar detalhes sobre quais mudanças você precisa fazer na visualização para entrar e sair do modo ambiente.

    Kotlin

    val ambientCallback = object : AmbientLifecycleObserver.AmbientLifecycleCallback {
        override fun onEnterAmbient(ambientDetails: AmbientLifecycleObserver.AmbientDetails) {
        // ... Called when moving from interactive mode into ambient mode.
        }
    
        override fun onExitAmbient() {
        // ... Called when leaving ambient mode, back into interactive mode.
        }
    
        override fun onUpdateAmbient() {
        // ... Called by the system in order to allow the app to periodically
        // update the display while in ambient mode. Typically the system will
        // call this every 60 seconds.
        }
    }
  2. Crie um AmbientLifecycleObserver e registre o observador. Normalmente, isso é usado no onCreate() ou no combinável de nível superior, se você estiver usando o Compose para Wear OS, para permitir que o comportamento sempre ativado seja ativado durante todo o ciclo de vida da atividade.

    Kotlin

    private val ambientObserver = AmbientLifecycleObserver(activity, callback)
    
    override fun onCreate(savedInstanceState: Bundle) {
      super.onCreate(savedInstanceState)
      lifecycle.addObserver(observer)
    
      // ...
    }
  3. Remova o observador chamando removeObserver() quando o comportamento sempre ativado não for mais necessário. Por exemplo, ele pode ser chamado no método onDestroy() da sua atividade.

Atualizar o texto de hora usando o widget TimeText

A partir do Wear OS 6, o widget TimeText é compatível com o modo ambiente. Se o app só precisar atualizar um texto de hora a cada minuto durante o modo ambiente, basta usar o widget TimeText sem usar o AmbientLifecycleObserver.

Os apps sempre ativados podem ser movidos para o segundo plano

A partir do Wear OS 5, o sistema move os apps sempre ativados para o segundo plano depois que eles ficam visíveis no modo ambiente por um determinado período. Os usuários podem configurar o tempo limite nas configurações do sistema.

Se o app sempre ativado mostrar informações sobre uma tarefa em andamento do usuário, como reprodução de música ou uma sessão de treino, mantenha a atividade em andamento visível até que a tarefa termine. Para isso, use a API Ongoing Activity para postar uma notificação em andamento vinculada à sua atividade sempre ativa.

Para que o sistema reconheça a atividade em andamento, a intent de toque da notificação em andamento precisa apontar para a atividade sempre ativa, conforme mostrado no snippet de código abaixo:

// Create a pending intent that point to your always-on activity
val touchIntent =
    PendingIntent.getActivity(
        context,
        0,
        Intent(context, MyAlwaysOnActivity::class.java),
        PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
    )

val notificationBuilder =
    NotificationCompat.Builder(this, CHANNEL_ID)
    // ...
    .setOngoing(true)

val ongoingActivity =
    OngoingActivity.Builder(
        applicationContext, NOTIFICATION_ID, notificationBuilder
    )
    // ...
    .setTouchIntent(touchIntent)
    .build()

ongoingActivity.apply(applicationContext)

notificationManager.notify(
    NOTIFICATION_ID,
    notificationBuilder.build()
)

Modificar a experiência do usuário no modo ambiente

Por padrão, ao implementar a opção "sempre ativado", a tela não muda de aparência quando o relógio entra no modo ambiente. Você pode modificar esse comportamento substituindo os métodos no AmbientLifecycleCallback.

Para ajudar a economizar bateria, faça o seguinte:

  • Ilumine menos pixels. Considere mostrar apenas informações importantes no modo ambiente e forneça mais detalhes quando o usuário entrar no modo interativo.
  • Mantenha pelo menos 85% da tela preta, remova preenchimentos e use contornos para botões e ícones grandes.
  • Evite mostrar informações irrelevantes, como branding não funcional e imagens de plano de fundo.
  • Mantenha os elementos na mesma posição nos modos ativo e sempre ativado e mostre sempre a hora.
  • Ajuste todo o conteúdo para atualizações menos frequentes. Por exemplo, mostre os timers até o minuto mais próximo em vez do segundo mais próximo.
  • Remova ou mostre a interface de marcador de posição para conteúdo alfanumérico que é atualizado com frequência, como distância ou hora.
  • Remova indicadores de progresso que são atualizados com frequência, como para contagem regressiva e sessões de mídia.
  • Ao entrar no modo "Sempre ativado", se o usuário já estava em uma tela de configuração ou de configurações no app, mostre uma tela mais relevante.
  • No objeto AmbientDetails transmitido para onEnterAmbient():
    • Se deviceHasLowBitAmbient estiver definido, desative a suavização sempre que possível.
    • Se burnInProtectionRequired estiver definido, mude a visualização periodicamente e evite áreas brancas sólidas.
  • Evite executar animações contínuas durante o modo ambiente. A partir do Wear OS 5.1, os animadores podem parar de ser executados durante o modo ambiente.

Lista de verificação para exibição ininterrupta

Pode haver situações em que você quer o máximo de controle sobre a tela à medida que o dispositivo passa por diferentes estados. Por exemplo, quando um app de treino quer evitar que o mostrador do relógio apareça na tela durante um treino. Nesses casos, faça o seguinte:

  1. Implemente a interface AmbientLifecycleObserver.AmbientLifecycleCallback.
  2. Crie um novo layout de baixo consumo para uso quando o dispositivo estiver no modo ambiente do sistema.
  3. Durante o treino, implemente uma atividade em andamento.

Para conferir um exemplo de como isso pode ser feito, confira o exemplo de exercício baseado no Compose no GitHub, que usa o combinável AmbientAware da biblioteca Horologist.