Mudanças de comportamento: todos os apps

A plataforma Android 12 inclui mudanças de comportamento que podem afetar seu app. As mudanças de comportamento a seguir se aplicam a todos os apps quando executados no Android 12, independentemente da targetSdkVersion. Teste seu app e modifique-o conforme necessário para ficar compatível com essas mudanças, quando aplicável.

Consulte também a lista de mudanças de comportamento que afetam apenas os apps destinados ao Android 12.

Experiência do usuário

Efeito de rolagem

O comportamento dos eventos de rolagem mudou no Android 12. Consulte Efeito de rolagem para mais informações.

Atraso na UX das notificações de serviços em primeiro plano

Para oferecer uma experiência simplificada para serviços em primeiro plano de curta duração no Android 12, o sistema pode atrasar a exibição de notificações de alguns serviços em primeiro plano por 10 segundos. Essa mudança possibilita que as tarefas de curta duração sejam concluídas antes que as notificações sejam exibidas.

Se um serviço em primeiro plano tiver pelo menos uma das características a seguir, o sistema mostrará a notificação associada imediatamente após o início do serviço:

  • O serviço está associado a uma notificação que inclui botões de ação.
  • O serviço tem um foregroundServiceType de mediaPlayback, mediaProjection ou phoneCall.
  • O serviço tem um caso de uso relacionado a chamadas telefônicas, navegação ou reprodução de mídia, conforme definido no atributo de categoria da notificação.
  • O serviço desativou a mudança de comportamento transmitindo FOREGROUND_SERVICE_IMMEDIATE para o método setForegroundServiceBehavior() ao configurar a notificação.

Melhorias no modo imersivo para navegação por gestos

O Android 12 simplifica o modo imersivo a fim de tornar a navegação por gestos mais fácil e consistente com outras experiências de atividades, como assistir um vídeo e ler um livro. Para saber mais, consulte a entrada correspondente na página de recursos.

Resolução de intents da Web

Para oferecer uma experiência mais simplificada quando os usuários selecionam links da Web, o Android 12 abre uma determinada intent da Web no navegador padrão do usuário no caso dela conter um domínio não aprovado. O app pode ser aprovado para o domínio usando uma das abordagens a seguir:

  • Verifique o domínio usando Links do app Android.
  • Solicite que o usuário associe o app a um domínio.

Se o app invocar intents da Web, considere adicionar um prompt ou uma caixa de diálogo que pede ao usuário para confirmar a ação.

Saiba mais sobre as mudanças na resolução de intents da Web.

Bucket restritivo do App em espera

Os buckets do App em espera ajudam o sistema a priorizar as solicitações de recursos de um app com base na frequência e no uso recente dele.

Cada bucket representa uma prioridade. Uma prioridade baixa significa que o sistema impõe mais restrições à execução do app.

A partir do Android 12, há um novo bucket chamado de restrito. O bucket restrito tem a prioridade mais baixa, e as restrições mais altas, de todos os buckets. Os buckets em ordem de prioridade da mais alta para a mais baixa são:

  1. Ativo: o app está sendo usado ou foi usado recentemente.
  2. Grupo de trabalho: o app está em uso regular.
  3. Frequente: o app costuma ser usado, mas não todos os dias.
  4. Raro: o app não é usado com frequência.
  5. Restrito

O sistema considera o comportamento do app, além dos padrões de uso, para decidir se ele será colocado no bucket restrito. Seu app terá menos probabilidade de ser colocado no bucket restrito se usar os recursos do sistema com mais responsabilidade.

O sistema colocará o app em um bucket menos restritivo se o usuário interagir diretamente com ele.

Restrições do gerenciamento de energia

Se o sistema colocar o app no bucket restrito, as restrições a seguir serão aplicadas:

  • É possível executar jobs uma vez por dia, em uma sessão em lote de 10 minutos. Durante essa sessão, o sistema agrupa os jobs do app com os de outros apps.
  • Seu app pode executar menos jobs acelerados em comparação a quando o sistema coloca o app em um bucket menos restritivo.
  • Os alarmes imprecisos do app são enviados uma vez por dia. Um alarme impreciso é criado ao chamar os métodos set(), setInexactRepeating(), setAndAllowWhileIdle() ou setWindow().
  • O app pode receber cinco mensagens de alta prioridade do Firebase Cloud Messaging (FCM) por dia. Todas as mensagens subsequentes do FCM serão enviadas com prioridade normal. Dessa forma, as mensagens podem atrasar se o dispositivo estiver no modo de economia de energia.

Permissão de serviços em primeiro plano

Se o sistema colocar seu app no bucket restrito, ele ainda poderá executar serviços em primeiro plano. No entanto, se o app for direcionado ao Android 12, ele ainda será afetado pelas restrições de inicialização de serviços em primeiro plano.

Conferir se o app está no bucket restrito

Para conferir se o sistema colocou o app no bucket restrito, chame getAppStandbyBucket(). Se o valor de retorno desse método for STANDBY_BUCKET_RESTRICTED, significa que o app está no bucket restrito.

Testar o comportamento do bucket restrito

Para testar como o app se comporta quando o sistema o coloca no bucket restrito, mova o app manualmente para esse bucket. Para fazer isso, execute os comandos a seguir em uma janela de terminal:

adb shell am set-standby-bucket PACKAGE_NAME restricted

Display#getRealSize e getRealMetrics: descontinuação e sandbox

Os dispositivos Android estão disponíveis em vários formatos, como telas grandes, tablets e dobráveis. Para renderizar conteúdo corretamente para cada dispositivo, o app precisa determinar o tamanho da tela ou da exibição. Com o tempo, o Android forneceu APIs diferentes para extrair essas informações. No Android 11, introduzimos a API WindowMetrics e descontinuamos estes métodos:

No Android 12, continuamos a recomendar o uso da WindowMetrics e descontinuamos estes métodos:

Para mitigar o comportamento de aplicativos usando as APIs Display para extrair os limites do aplicativo, o Android 12 oferece um novo mecanismo de sandbox para corrigir as informações retornadas por essas APIs. Isso pode afetar os apps que usam essas informações com MediaProjection.

Os apps precisam usar as APIs WindowMetrics para consultar os limites da janela e Configuration.densityDpi para consultar a densidade atual.

Para oferecer compatibilidade com versões mais antigas do Android, use a biblioteca WindowManager do Jetpack, que inclui uma classe WindowMetrics compatível com o Android 4.0 (nível 14 da API) e versões mais recentes.

Exemplos de como usar a WindowMetrics

Primeiro, confira se as atividades do seu app são totalmente redimensionáveis.

Uma atividade depende da WindowMetrics de um contexto de atividade para qualquer trabalho relacionado à IU, especialmente WindowManager.getCurrentWindowMetrics().

Se o app criar uma MediaProjection, os limites precisam ser dimensionados corretamente, já que a projeção captura a tela. Se o app for totalmente redimensionável, o contexto da atividade retornará os limites corretos, como em:

WindowMetrics projectionMetrics = activityContext
        .getSystemService(WindowManager.class).getMaximumWindowMetrics();

Se o app não for totalmente redimensionável, ele precisará consultar os limites de uma instância WindowContext e extrair as WindowMetrics da área máxima de exibição disponível para o app usando WindowManager.getMaximumWindowMetrics().

Context windowContext = mContext.createWindowContext(mContext.getDisplay(),
        TYPE_APPLICATION, null /* options */);
WindowMetrics projectionMetrics = windowContext.getWindowManager()
        .getMaximumWindowMetrics();

Gráficos e imagens

Melhorias na alternância da taxa de atualização

No Android 12, mudanças na taxa de atualização usando setFrameRate() podem acontecer se a tela for compatível com uma transição uniforme para a nova taxa de atualização. Uma transição uniforme é aquela que não apresenta interrupções visuais, como uma tela preta por um ou dois segundos. Anteriormente, se a tela não fosse compatível com uma transição uniforme, ela continuaria usando a mesma taxa de atualização após chamar setFrameRate(). É possível determinar com antecedência se a transição para a nova atualização será contínua chamando o método getAlternativeRefreshRates(). Geralmente, o callback onDisplayChanged() é chamado após a taxa de atualização mudar, mas para algumas telas conectadas externamente, ele é chamado durante uma transição uniforme.

Veja um exemplo de como implementar isso:

Kotlin

// Determine whether the transition will be seamless.
// Non-seamless transitions may cause a 1-2 second black screen.
val refreshRates = this.display?.mode?.alternativeRefreshRates
        val willbeSeamless = Arrays.asList<FloatArray>(refreshRates).contains(newRefreshRate)

// Set the frame rate even if the transition will not be seamless.
surface.setFrameRate(newRefreshRate, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ALWAYS)

Java

// Determine whether the transition will be seamless.
// Non-seamless transitions may cause a 1-2 second black screen.
Display display = context.getDisplay(); // API 30+
Display.Mode mode = display.getMode();
float[] refreshRates = mode.getAlternativeRefreshRates();
boolean willbeSeamless = Arrays.asList(refreshRates).contains(newRefreshRate);

// Set the frame rate even if the transition will not be seamless.
surface.setFrameRate(newRefreshRate, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ALWAYS);

Segurança e privacidade

Desativação do microfone e da câmera

Os blocos das Configurações rápidas são rotulados como &quot;Acesso à câmera&quot; e
         &quot;Acesso ao Microfone&quot;
Figura 1. Desativação do microfone e da câmera nas Configurações rápidas.

No Android 12, os dispositivos compatíveis possibilitam que os usuários ativem e desativem o acesso à câmera e ao microfone para todos os apps no dispositivo, pressionando uma única opção que pode ser alternada. Os usuários podem acessar as opções de alternância nas Configurações rápidas, como mostrado na Figura 1, ou na Tela de privacidade nas configurações do sistema.

Alternar a câmera e o microfone afeta todos os apps do dispositivo:

  • Quando o usuário desativar o acesso à câmera, os apps receberão um feed de câmera em branco.
  • Quando o usuário desativar o acesso ao microfone, os apps receberão áudio mudo. Além disso, os sensores de movimento terão limitação de taxa, independente de você declarar a permissão HIGH_SAMPLING_RATE_SENSORS ou não.

Quando o usuário desativar o acesso à câmera ou ao microfone e iniciar um app que precisa de acesso às informações da câmera ou do microfone, o sistema lembrará o usuário de que o botão desses recursos do dispositivo está desativado.

Conferir se um dispositivo específico é compatível com a desativação do microfone e da câmera

Para conferir se um dispositivo é compatível com a desativação do microfone e da câmera, adicione a lógica mostrada no snippet de código a seguir:

Kotlin

val sensorPrivacyManager = applicationContext
        .getSystemService(SensorPrivacyManager::class.java)
        as SensorPrivacyManager
val supportsMicrophoneToggle = sensorPrivacyManager
        .supportsSensorToggle(Sensors.MICROPHONE)
val supportsCameraToggle = sensorPrivacyManager
        .supportsSensorToggle(Sensors.CAMERA)

Java

SensorPrivacyManager sensorPrivacyManager = getApplicationContext()
        .getSystemService(SensorPrivacyManager.class);
boolean supportsMicrophoneToggle = sensorPrivacyManager
        .supportsSensorToggle(Sensors.MICROPHONE);
boolean supportsCameraToggle = sensorPrivacyManager
        .supportsSensorToggle(Sensors.CAMERA);

Conferir o comportamento do app em resposta a desativação da câmera e do microfone

A desativação do microfone e da câmera não pode afetar a forma como o app lida com as permissões CAMERA e RECORD_AUDIO, contanto que você siga as práticas recomendadas para as permissões do Android.

Confira, especialmente, se o app faz o seguinte:

  • Aguarda até que o usuário conceda a permissão CAMERA ao app para acessar a câmera do dispositivo.
  • Aguarda até que o usuário conceda a permissão RECORD_AUDIO ao app para acessar o microfone do dispositivo.

Indicadores de microfone e câmera

Um retângulo arredondado no canto superior direito,
         que inclui um ícone da câmera e um ícone do microfone
Figura 2. Indicadores de microfone e câmera, que mostram o acesso recente aos dados.

Em dispositivos com o Android 12, quando um app acessa o microfone ou a câmera, um ícone é exibido na barra de status. Se o app estiver no modo imersivo, o ícone será exibido no canto superior direito da tela. Os usuários podem abrir as Configurações rápidas e selecionar o ícone para ver quais apps estão usando o microfone ou a câmera. A Figura 2 mostra um exemplo de captura de tela que contém os ícones.

Para oferecer uma melhor experiência do usuário, não acesse o microfone ou a câmera até que o usuário conceda explicitamente a permissão ao app.

Apps não podem fechar caixas de diálogo do sistema

Para melhorar o controle do usuário ao interagir com apps e com o sistema, a ação da intent ACTION_CLOSE_SYSTEM_DIALOGS foi suspensa a partir do Android 12. Com a exceção de alguns casos específicos, quando seu app tenta invocar uma intent que contém essa ação, o sistema realiza uma das seguintes ações, com base na versão do SDK de destino do app:

  • Se o app for destinado ao Android 12, ocorrerá uma SecurityException.
  • Se o app for destinado ao Android 11 (API de nível 30) ou versões anteriores, a intent não será executada e a seguinte mensagem aparecerá no Logcat:

    E ActivityTaskManager Permission Denial: \
    android.intent.action.CLOSE_SYSTEM_DIALOGS broadcast from \
    com.package.name requires android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS, \
    dropping broadcast.
    

Exceções

O app ainda pode fechar caixas de diálogo do sistema no Android 12 nos seguintes casos:

  • O app está executando um teste de instrumentação.
  • O app é destinado ao Android 11 ou versões anteriores e está exibindo uma janela que sobrepõe a gaveta de notificações.

  • O app é destinado ao Android 11 ou versões anteriores. Além disso, o usuário interagiu com uma notificação, possivelmente usando os botões de ação da notificação, e o app está processando um serviço ou broadcast receiver em resposta à ação do usuário.

  • O app é destinado ao Android 11 ou versões anteriores e tem um serviço de acessibilidade ativo. Se o app for direcionado ao Android 12 e quiser fechar a barra de notificações, use a ação de acessibilidade GLOBAL_ACTION_DISMISS_NOTIFICATION_SHADE.

Eventos de toque não confiáveis estão bloqueados

Para preservar a segurança do sistema e uma boa experiência do usuário, o Android 12 impede que os apps consumam eventos de toque em que uma sobreposição oculte o app de forma não segura. Em outras palavras, o sistema bloqueia toques que são transmitidos por determinadas janelas, com algumas exceções.

Apps afetados

Essa mudança afeta os apps que optam por permitir que toques sejam transmitidos pelas janelas, por exemplo, usando a sinalização FLAG_NOT_TOUCHABLE. Alguns exemplos incluem os seguintes:

Exceções

Os toques de transmissão são permitidos nos seguintes casos:

  • Interações dentro do app. O app exibe a sobreposição, que aparece somente quando o usuário está interagindo com o próprio app.
  • Janelas confiáveis. Essas janelas incluem, entre outras:

  • Janelas invisíveis. A visualização raiz da janela é GONE ou INVISIBLE.

  • Janelas totalmente transparentes. A propriedade alpha da janela é 0.0.

  • Janelas de alerta do sistema translúcidas o suficiente. O sistema considera que um conjunto de janelas de alerta do sistema é translúcido o suficiente quando a opacidade combinada é menor ou igual à opacidade máxima de ofuscação do sistema para toques. No Android 12 Beta, essa opacidade máxima é de 0,8. Esse valor pode mudar em uma versão Beta futura.

Detectar quando um toque não confiável está bloqueado

Se uma ação de toque for bloqueada pelo sistema, o Logcat registrará a seguinte mensagem:

Untrusted touch due to occlusion by PACKAGE_NAME

Testar a mudança

Os toques não confiáveis são bloqueados por padrão em dispositivos com a Visualização do desenvolvedor 3 do Android 12. Para permitir toques não confiáveis, execute o comando ADB a seguir em uma janela de terminal:

# A specific app
adb shell am compat disable BLOCK_UNTRUSTED_TOUCHES com.example.app

# All apps
# If you'd still like to see a Logcat message warning when a touch would be
# blocked, use 1 instead of 0.
adb shell settings put global block_untrusted_touches 0

Para reverter o comportamento para o padrão (toques não confiáveis bloqueados), execute o comando a seguir:

# A specific app
adb shell am compat reset BLOCK_UNTRUSTED_TOUCHES com.example.app

# All apps
adb shell settings put global block_untrusted_touches 2

Visibilidade do pacote de permissões

Em dispositivos com o Android 12, os apps direcionados ao Android 11 (nível 30 da API) ou mais recentes e que chamam um dos métodos a seguir recebem um conjunto filtrado de resultados, com base na visibilidade do pacote do app para outros:

Remoção das implementações do Bouncy Castle

O Android 12 removeu muitas implementações do BouncyCastle (link em inglês) de algoritmos criptográficos que foram descontinuados, incluindo todos os algoritmos AES. Em vez disso, o sistema usa as implementações Conscrypt (link em inglês) desses algoritmos.

Essa mudança afetará o app se alguma das condições a seguir for verdadeira:

  • O app usa tamanhos de chave de 512 bits. O Conscrypt não é compatível com esse tamanho de chave. Se necessário, atualize a lógica de criptografia do app para usar tamanhos de chave diferentes.
  • O app usa tamanhos de chave inválidos com o KeyGenerator. A implementação do Conscrypt do KeyGenerator executa outras validações em parâmetros de chave, em comparação com o BouncyCastle. Por exemplo, o Conscrypt não permite que o app gere uma chave AES de 64 bits porque o AES é compatível apenas com chaves de 128, 192 e 256 bits.

    O BouncyCastle possiblita gerar chaves de tamanhos inválidos, mas isso falhará mais tarde se elas forem usadas com uma Cipher. O Conscrypt falha antes.

  • As criptografias dos modos Galois/Counter (GCM, na sigla em inglês) são inicializadas usando um tamanho diferente de 12 bytes. A implementação da GcmParameterSpec do Conscrypt exige uma inicialização de 12 bytes, de acordo com o recomendado pela NIST.

Notificações de acesso à área de transferência

No Android 12, quando um app chamar getPrimaryClip() para acessar os ClipData de um app diferente pela primeira vez, uma mensagem avisará o usuário sobre este acesso à área de transferência.

O texto da mensagem de aviso contém o formato a seguir: APP pasted from your clipboard.

A mensagem não é exibida ao acessar a descrição do clipe

O app pode chamar getPrimaryClipDescription() para receber informações sobre os dados atuais que estão na área de transferência. Quando o app chamar esse método, o sistema não mostrará uma mensagem de aviso.

O Android 12 melhora esse método para detectar os detalhes a seguir:

Conectividade

Atualizações do Passpoint

As APIs a seguir foram adicionadas ao Android 12:

  • isPasspointTermsAndConditionsSupported(): os Termos e Condições são um recurso do Passpoint que possibilita que as implantações de rede substituam o portal cativo não seguro, que usa redes abertas, por uma rede do Passpoint segura. O usuário recebe uma notificação quando ele for solicitado a aceitar os Termos e Condições. Os apps que sugerem redes de Passpoint controladas por Termos e Condições, precisam chamar essa API primeiro para ter certeza de que o dispositivo é compatível com a funcionalidade. Se o dispositivo não for compatível com o recurso, ele não poderá se conectar a essa rede, e será necessário sugerir uma rede alternativa ou legada.
  • isDecoratedIdentitySupported(): ao autenticar em redes com uma decoração prefixada, o prefixo de identidade decorado possibilita que os operadores de rede atualizem o identificador de acesso à rede (NAI, na sigla em inglês) para executar o roteamento explícito usando vários proxies dentro de uma rede AAA. Consulte RFC 7542 (link em inglês) para saber mais sobre isso.

    O Android 12 implementa esse recurso para estar em conformidade com as especificações da WBA para extensões PPS-MO (link em inglês). Os apps que sugerem redes do Passpoint que exigem uma identidade decorada, precisam chamar essa API primeiro para garantir que dispositivo é compatível com a funcionalidade. Se o dispositivo não for compatível com o recurso, a identidade não será decorada e a autenticação na rede pode falhar.

Para criar uma sugestão de Passpoint, os apps precisam usar as classes PasspointConfiguration, Credential e HomeSp. Essas classes descrevem o perfil do Passpoint, definido na especificação do Passpoint do Wi-Fi Alliance (em inglês).

Atualização das restrições da interface não SDK

O Android 12 inclui listas atualizadas de interfaces não SDK restritas com base na colaboração de desenvolvedores do Android e nos testes internos mais recentes. Antes de restringirmos interfaces não SDK, sempre que possível, garantimos que haja alternativas públicas disponíveis.

Caso seu app não seja destinado ao Android 12, é possível que algumas dessas mudanças não afetem você imediatamente. No entanto, embora atualmente seja possível usar algumas interfaces não SDK (dependendo do nível da API de destino do app), o uso de qualquer método ou campo não SDK sempre apresenta um alto risco de corromper o app.

Se você não sabe se o app usa interfaces não SDK, é possível testá-lo para descobrir. Se ele depende de interfaces não SDK, planeje uma migração para alternativas SDK. No entanto, entendemos que alguns apps têm casos de uso válidos para interfaces não SDK. Caso você não encontre uma alternativa para deixar de usar uma interface não SDK em um recurso no app, solicite uma nova API pública.

Para saber mais sobre as mudanças dessa versão do Android, consulte Atualizações para restrições de interfaces não SDK no Android 12. Para saber mais sobre interfaces não SDK em geral, consulte Restrições para interfaces não SDK.