Adicionar suporte para o Android Automotive OS ao seu app estacionado

Ao distribuir seu app para dispositivos Android Automotive OS, há algumas considerações exclusivas do formato que você precisa conhecer. Este guia explica essas considerações.

Testar o app em um emulador do Android Automotive OS

Para começar a criar apps para Android Automotive OS, primeiro teste seu app em um emulador do Android Automotive OS. Siga as etapas em Testar usando o emulador do Android Automotive OS e configure o emulador. Em seguida, execute o app seguindo as instruções em Executar o app no emulador.

Ao executar o app, tenha cuidado com problemas de compatibilidade, como estes:

  • As telas de infoentretenimento têm orientações fixas. Para atender às diretrizes de qualidade de apps para carros, os apps precisam oferecer suporte às orientações de retrato e paisagem.
  • As APIs disponíveis em outros dispositivos podem não estar presentes no Android Automotive OS. Por exemplo, algumas APIs do Google Play Services não estão disponíveis no Android Automotive OS. Consulte a seção Desativar recursos para conferir mais detalhes sobre como lidar com esses problemas.

Configurar o arquivo de manifesto do app

Para ser direcionado a dispositivos Android Automotive OS, o app precisa ter determinadas entradas de manifesto. Depois de ativar a distribuição para dispositivos com o Android Automotive OS, os apps compatíveis passam por um processo de análise manual para garantir que sejam seguros para uso em carros. Consulte Distribuir para carros para mais detalhes.

Recursos necessários do Android Automotive OS

Todos os apps criados para o Android Automotive OS precisam atender a determinados requisitos para serem distribuídos pelo Google Play. Consulte Atender aos requisitos de recursos do Google Play para mais informações.

Entradas de manifesto específicas para a categoria

Além dos requisitos anteriores, que se aplicam a todos os apps estacionados, as categorias de vídeo e jogos têm requisitos adicionais:

Atender aos requisitos de distração do motorista

Evitar distrações do motorista é fundamental ao levar seu app para carros. Para apps estacionados, isso é feito principalmente impedindo que o app seja usado ou reproduza áudio enquanto as restrições de experiência do usuário (UX) estão ativas, conforme capturado pelas diretrizes de qualidade DD-2 e DD-3.

Impedir o uso enquanto as restrições de experiência do usuário estiverem ativas

Por padrão, as atividades não podem ser usadas ou iniciadas enquanto as restrições de UX estão ativas. Para garantir que esse comportamento se aplique ao app, ele não pode incluir o seguinte elemento <meta-data> em nenhum elemento <activity> do manifesto:

<!-- NOT ALLOWED -->
<meta-data
  android:name="distractionOptimized"
  android:value="true"/>

Se uma atividade no app for retomada quando as restrições de UX forem ativadas, ela será obscurecida por uma atividade pertencente ao SO.

No mínimo, a atividade do app precisa fazer a transição para o estado do ciclo de vida Pausad. Isso acontece como um callback do ciclo de vida onPause(), em que você precisa pausar a reprodução de vídeo e áudio do app.

Em dispositivos que incluem o modo de compatibilidade do Android Automotive OS, o bloqueio do sistema faz com que as atividades do app passem do estado Paused para o estado Stopped.

Parar a reprodução e impedir a retomada

Para alguns apps, pausar a reprodução durante onPause() e rastrear o estado para impedir a retomada da reprodução até onResume() é suficiente para atender aos requisitos de distração do motorista.

Se reagir aos callbacks de ciclo de vida não for suficiente para seu app, você poderá detectar o estado de restrição de UX diretamente, conforme descrito na próxima seção. Por exemplo, apps que oferecem suporte a picture-in-picture podem preferir detectar diretamente em vez de ter verificações condicionais em callbacks de ciclo de vida.

Ouvir as restrições da experiência do usuário

Para ouvir restrições de UX, primeiro adicione uma dependência à biblioteca android.car no arquivo build.gradle do módulo do app. Essa é uma extensão do SDK do Android que fornece APIs específicas para o Android Automotive OS.

android {
    ...
    useLibrary("android.car")
}

Use CarUxRestrictionsManager para ler o estado da restrição de UX. Não tente determinar o estado da restrição de UX de outro estado do hardware, como marcha ou velocidade, porque as restrições de UX podem variar de acordo com a tela em um veículo.

val car = Car.createCar(context)
val carUxRestrictionsManager =
    car.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE) as CarUxRestrictionsManager

// You can either read the state directly ...
val currentUxRestrictions = carUxRestrictionsManager.currentUxRestrictions

// or listen to state changes
carUxRestrictionsManager.registerListener { carUxRestrictions: CarUxRestrictions -> ...}

// Don't forget to teardown and release resources when they're no longer needed
carUxRestrictionsManager.unregisterListener()
car.disconnect()

O único valor fornecido por CarUxRestrictions que o app precisa referenciar é o valor de retorno de isRequiresDistractionOptimization(). Outros valores são relevantes apenas para atividades marcadas como otimizadas para distração.

Testar a implementação

Valide se o app atende aos requisitos de distração do motorista usando o seguinte procedimento:

  1. Instale seu app em uma imagem do sistema sem a Google Play Store ou o modo de compatibilidade.
  2. Com a grade de apps do Acesso rápido aberto, simule a direção e verifique se o app não pode ser aberto.
  3. Pare de simular a direção, abra o app em uma tela de reprodução e inicie a reprodução.
  4. Simule dirigir novamente e verifique se a reprodução é pausada.
    1. Se o app oferece suporte a integrações com MediaSession, use adb shell cmd media_session dispatch play e verifique se a reprodução não é retomada.

Otimizar o app para o Android Automotive OS

Para oferecer aos usuários a melhor experiência possível em carros, não se esqueça do seguinte ao criar seu app para o Android Automotive OS:

Trabalhar com encartes de janela e cortes da tela

Assim como em outros formatos, o Android Automotive OS inclui elementos da interface do sistema, como barras de status e navegação, e suporte a telas não retangulares.

Por padrão, os apps renderizam em uma área que não se sobrepõe às barras de sistema ou aos cortes da tela. No entanto, o app pode ocultar as barras de sistema, renderizar o conteúdo atrás delas ou mostrar o conteúdo em um corte da tela, conforme descrito em Posicionar o app dentro de encartes de janelas. Se o app realizar qualquer uma dessas ações, consulte as subseções abaixo para detalhes sobre como permitir que o app funcione bem em todo o ecossistema de dispositivos Android Automotive OS.

Barras de sistema, modo imersivo e renderização de ponta a ponta

As barras de sistema em carros podem ser dimensionadas e posicionadas de maneira diferente de outros formatos. Por exemplo, as barras de navegação podem ser posicionadas à esquerda, à direita ou na parte de baixo da tela. Mesmo que haja uma barra de status na parte de cima e uma barra de navegação na parte de baixo, como é o caso da maioria dos smartphones e tablets, o tamanho desses elementos provavelmente será muito maior em carros.

Além disso, o Android Automotive OS permite que os OEMs controlem se os apps podem ou não mostrar ou ocultar as barras de sistema para entrar e sair do modo imersivo. Por exemplo, ao impedir que apps ocultem as barras de sistema, os OEMs podem garantir que os controles do veículo, como os de clima, fiquem sempre acessíveis na tela. Se um OEM impedir os apps de controlar as barras de sistema, nada acontecerá quando um app chamar as APIs WindowInsetsController (ou WindowInsetsControllerCompat) para mostrar ou ocultar barras de sistema. Consulte a documentação de show e hide para saber mais sobre como detectar se o app conseguiu modificar os encartes.

Da mesma forma, os OEMs também podem controlar se os apps podem ou não definir a cor e a translucência das barras de sistema para garantir que elas e os elementos contidos nelas fiquem claramente visíveis o tempo todo. Se o app renderizar de ponta a ponta, confira se apenas conteúdo não essencial é mostrado por trás das barras de sistema. Esse conteúdo pode não ser visível se o OEM do dispositivo impedir a configuração da cor ou da translucência das barras.

<!-- Depending on OEM configuration, these style declarations
     (and the corresponding runtime calls) may be ignored -->
<style name="...">
  <item name="android:statusBarColor">...</item>
  <item name="android:navigationBarColor">...</item>
  <item name="android:windowTranslucentStatus">...</item>
  <item name="android:windowTranslucentNavigation">...</status>
</style>

Se o app cobre a tela inteira de ponta a ponta, não presuma o tamanho, o número, o tipo ou a localização das barras de sistema. Em vez disso, use as APIs de encarte de janela para mostrar o conteúdo do app em relação às barras de sistema. Consulte Mostrar conteúdo de ponta a ponta no app para saber mais sobre como usar essas APIs. Valores de padding codificados nunca são recomendados para nenhum formato, mas em carros, eles provavelmente não vão funcionar para manter o conteúdo na área segura.

Adaptar para telas de formato irregular

Além das telas retangulares, alguns veículos podem ter telas de formato irregular, como mostrado na Figura 1:

Diagrama de um dispositivo Android Automotive OS com uma tela
      curvada no lado direito.
Figura 1: um dispositivo Android Automotive OS com tela curvada no lado direito. A área verde é o retângulo seguro que não se sobrepõe à caixa delimitadora do corte da tela da curva.

Se o app não renderizar de ponta a ponta, não será necessário fazer algo para que ele seja renderizado dentro da área segura.

Se o app renderizar de ponta a ponta, você poderá escolher como gostaria que ele se comportasse em relação aos cortes da tela. Para fazer isso, use recursos configurando o atributo android:windowLayoutInDisplayCutoutMode para o tema do app ou durante a execução modificando o atributo da janela layoutInDisplayCutoutMode.

Como os tipos de corte da tela presentes nos dispositivos Android Automotive OS são diferentes daqueles usados em dispositivos móveis, não use LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT nem LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES, que têm comportamento otimizado para os cortes encontrados em dispositivos móveis. Em vez disso, use LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER ou LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS para sempre evitar ou sempre usar o corte. Ao escolher a segunda opção, consulte Suporte a cortes de tela para saber mais sobre as APIs relacionadas.

Se o app for renderizado na área de corte da tela, e você quiser um comportamento diferente entre o Android Automotive OS e o dispositivo móvel, consulte Desativar recursos para orientações se o app definir esse comportamento durante a execução. Consulte Usar recursos alternativos caso seu app defina esse comportamento usando arquivos de recursos.

Desativar recursos

Se você estiver disponibilizando um app para dispositivos móveis no Android Automotive OS, alguns recursos e funcionalidades podem não ser relevantes ou não estar disponíveis. Por exemplo, os carros geralmente não oferecem acesso a câmeras. Além disso, apenas um subconjunto do Google Play Services está disponível no Android Automotive OS. Consulte mais detalhes em Google Play Services para carros.

Você pode usar a API PackageManager.hasSystemFeature para detectar se o app está sendo executado no Android Automotive OS. Para isso, confira se o recurso FEATURE_AUTOMOTIVE está presente, conforme mostrado no exemplo a seguir:

Kotlin

val packageManager: PackageManager = ... // Get a PackageManager from a Context
val isCar = packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
if (isCar) {
  // Enable or disable a given feature
}

Java

PackageManager packageManager = ... // Get a PackageManager from a Context
boolean isCar = packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
if (isCar) {
  // Enable or disable a given feature
}

Como alternativa, se o app também tiver um componente do Android Auto, você poderá usar a API CarConnection da biblioteca Android for Cars App para detectar se o app está sendo executado no Android Automotive OS ou no Android Auto ou se não está conectado a um carro.

No modo picture-in-picture (PiP), siga as práticas recomendadas estabelecidas para conferir se o recurso está disponível e reagir de forma adequada.

Lidar com cenários off-line

Embora os carros estejam cada vez mais conectados à Internet, é recomendado que os apps possam ser executados sem uma conexão de Internet, como nos seguintes casos:

  • Os usuários podem desativar os dados móveis oferecidos como parte de um pacote de assinatura do fabricante de automóveis.
  • O acesso a dados móveis pode ser limitado em algumas áreas.
  • Carros com rádios Wi-Fi podem estar fora do alcance do recurso ou um OEM pode desativar o Wi-Fi em favor de uma rede móvel.

Prepare-se para lidar com esses cenários no seu app fazendo uma degradação suave das funcionalidades que dependem do acesso à Internet, como a oferta de conteúdo off-line. Se quiser mais informações, consulte as práticas recomendadas para otimizar redes.

Usar recursos alternativos

Para adaptar seu app para carros, use o qualificador de recurso car, que fornece recursos alternativos durante a execução de um app em um veículo com o Android Automotive OS. Por exemplo, se você utilizar recursos de dimensão para armazenar valores de padding, poderá usar um valor maior para o conjunto de recursos car para aumentar as áreas de toque.