Mudanças de comportamento: todos os apps

A plataforma Android 17 inclui mudanças de comportamento que podem afetar seu app. As mudanças a seguir se aplicam a todos os apps executados no Android 17, independente da targetSdkVersion. Teste o app e modifique-o conforme necessário para que ele ofereça suporte a essas mudanças.

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

Principal recurso

O Android 17 (nível 37 da API) inclui as mudanças abaixo, que modificam ou ampliam vários recursos principais do sistema Android.

Limites de memória para apps

O Android 17 traz limites de memória para os apps com base na RAM total do dispositivo para criar um ambiente mais estável e determinista para seus apps e usuários do Android. Esses limites se concentram em vazamentos de memória e outros valores atípicos antes que eles causem instabilidade em todo o sistema, resultando em instabilidade na interface, maior consumo de bateria e encerramento de apps. Embora o impacto seja mínimo na grande maioria das sessões de apps, recomendamos as práticas recomendadas de memória a seguir, incluindo o estabelecimento de um valor de referência para a memória.

Para determinar se a sessão do app foi afetada, chame getDescription em ApplicationExitInfo. Se o app tiver sido afetado, o motivo da saída será REASON_OTHER e a descrição vai conter a string "MemoryLimiter:AnonSwap" com outras informações. Também é possível usar a criação de perfil baseada em gatilhos com TRIGGER_TYPE_ANOMALY para receber heap dumps coletados quando o limite de memória é atingido.

A documentação Gerenciar a memória do seu app fornece informações para ajudar a diagnosticar problemas de memória do app e otimizar o consumo de recursos.

Testar o comportamento do app com as restrições de memória

Use o Android Debug Bridge (adb) para ajustar ou desativar os limites de memória em qualquer dispositivo que os imponha. O comando shell am fornece três subcomandos para ajustar os limites de memória. Esses comandos não têm efeito em um dispositivo que não impõe limites de memória.

  • am memory-limiter ignore <uid>|none|all
  • am memory-limiter manual <pid> <limit>|max|none
  • am memory-limiter status
ignore

Instrui o limitador de memória a ignorar alguns ou todos os processos. Transmitir um UID (ID do usuário do Android) instrui o limitador de memória a ignorar a aplicação em todos os processos associados a esse UID. Também é possível transmitir all (ignorar todos os apps) ou none (não ignorar nenhum app). Transmitir none substitui todas as chamadas anteriores para am memory-limiter ignore.

Se você instruir o limitador de memória a ignorar um UID, ainda será possível aplicar um limite de memória manual a um processo no app chamando am memory-limiter manual.

manual

Instrui o sistema a impor uma restrição de memória ao processo com o PID (ID de processo) especificado. A restrição de memória é especificada como um número inteiro de MB. Por exemplo, transmitir 30 especifica que o processo está limitado a 30 MB de memória. Transmitir max remove todos os limites de memória desse processo. Transmitir none remove todos os limites manuais definidos no processo, restaurando o limite padrão do sistema (se houver).

status

Informa o status atual do limitador de memória. O status inclui os limites de memória impostos a processos visíveis e não visíveis.

Privacidade

O Android 17 inclui as mudanças abaixo para melhorar a privacidade do usuário.

Proteção de OTP por SMS

A partir do Android 17, o Android está expandindo a proteção para mensagens SMS que contêm senhas únicas (OTP).

Nas versões anteriores do Android, essa proteção se concentrava principalmente no formato do SMS Retriever. A entrega de mensagens com um hash de recuperação de SMS foi atrasada em três horas para a maioria dos apps. No entanto, alguns apps (como o gerenciador de SMS padrão) estavam isentos do atraso, assim como o app que era proprietário do hash.

A partir do Android 17, a proteção também é aplicada a mensagens no formato WebOTP. Se um app tiver permissão para ler mensagens SMS, mas não for o destinatário de uma mensagem WebOTP (conforme determinado pela verificação de domínio), a mensagem não poderá ser acessada pelo app até três horas após o recebimento. Essa mudança tem como objetivo melhorar a segurança do usuário, garantindo que apenas os apps associados ao domínio mencionado na mensagem possam ler o código de verificação de forma programática.

Durante esse atraso de três horas, a transmissão SMS_RECEIVED_ACTION é retida, e as consultas ao banco de dados do provedor de SMS são filtradas. A mensagem SMS fica disponível para esses apps após o atraso. Essa mudança se aplica a todos os apps, seja qual for o nível desejado da API.

Alguns apps, como o app assistivo de SMS padrão, apps complementares de dispositivos conectados etc., estão isentos desse atraso. Todos os apps que dependem da leitura de mensagens SMS para extração de OTP precisam usar as APIs SMS Retriever ou SMS User Consent para garantir a funcionalidade contínua.

Segurança

O Android 17 inclui as seguintes melhorias na segurança de dispositivos e apps.

Plano de descontinuação de usesClearTraffic

Em uma versão futura, planejamos descontinuar o elemento usesCleartextTraffic. Os apps que precisam fazer conexões não criptografadas (HTTP) precisam migrar para um arquivo de configuração de segurança de rede, que permite especificar os domínios com que o app precisa fazer conexões de texto não criptografado.

Os arquivos de configuração de segurança de rede só são compatíveis com os níveis de API 24 e mais recentes. Se o app tiver um nível mínimo de API inferior a 24, faça o seguinte:

  • Defina o atributo usesCleartextTraffic como true.
  • Usar um arquivo de configuração de rede

Se o nível da API mínimo do app for 24 ou mais recente, você poderá usar um arquivo de configuração de rede e não precisará definir usesCleartextTraffic.

Restrição das concessões implícitas de URI

Atualmente, se um app inicia uma intent com um URI que tem a ação ACTION_SEND, ACTION_SEND_MULTIPLE ou ACTION_IMAGE_CAPTURE, o sistema concede automaticamente as permissões de leitura e gravação de URI ao app de destino. No Android 18, o sistema não vai mais conceder essas permissões automaticamente. Por isso, recomendamos que os apps concedam explicitamente as permissões de URI relevantes em vez de depender do sistema para isso.

Para detectar o uso dessas intents no app, use StrictMode com detectImplicitUriPermissionGrant() para acionar uma violação:

Kotlin

val policy = StrictMode.VmPolicy.Builder()
    .detectImplicitUriPermissionGrant()
    .penaltyLog()
    .build()
StrictMode.setVmPolicy(policy)

Java

StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder()
    .detectImplicitUriPermissionGrant()
    .penaltyLog()
    .build();
StrictMode.setVmPolicy(policy);

Como alternativa, é possível monitorar exceções registradas que contenham a mensagem Please set the grant explicitly in the app, que aparece quando o sistema define implicitamente a concessão. É possível monitorar esses registros usando o seguinte comando adb:

adb logcat | grep "Please set the grant explicitly in the app"

Para conceder explicitamente as permissões necessárias, adicione a flag FLAG_GRANT_READ_URI_PERMISSION às intents ACTION_SEND e ACTION_SEND_MULTIPLE:

Kotlin

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)

Java

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

Inclua as sinalizações FLAG_GRANT_READ_URI_PERMISSION e FLAG_GRANT_WRITE_URI_PERMISSION para intents ACTION_IMAGE_CAPTURE:

Kotlin

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)

Java

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

Limites de keystore por app

Os apps precisam evitar a criação de um número excessivo de chaves no Android Keystore, porque ele é um recurso compartilhado para todos os apps no dispositivo. A partir do Android 17, o sistema impõe um limite ao número de chaves que um app pode ter. O limite é de 50.000 chaves para apps que não são do sistema destinados ao Android 17 (nível 37 da API) ou versões mais recentes e de 200.000 chaves para todos os outros apps. Os apps do sistema têm um limite de 200.000 chaves, independentemente do nível da API que usam.

Se um app tentar criar chaves além do limite, a criação vai falhar com um KeyStoreException. A string de mensagem da exceção contém informações sobre o limite de chaves. Se o app chamar getNumericErrorCode() na exceção, o valor de retorno vai depender do nível da API de destino do app:

  • Apps destinados ao Android 17 (nível 37 da API) ou versões mais recentes: getNumericErrorCode() retorna o novo valor de ERROR_TOO_MANY_KEYS.
  • Todos os outros apps: getNumericErrorCode() retorna ERROR_INCORRECT_USAGE.

Bloquear o tráfego de loopback entre perfis unificados

A partir do Android 17, o tráfego de loopback entre perfis não é mais permitido por padrão. O tráfego de loopback no mesmo perfil não é afetado. Essa mudança se aplica a todos os apps executados no Android 17 ou versões mais recentes, seja qual for o nível da API de destino.

Experiência do usuário e interface do sistema

O Android 17 inclui as mudanças a seguir, que têm como objetivo criar uma experiência do usuário mais consistente e intuitiva.

Restauração da visibilidade padrão do IME após a rotação

A partir do Android 17, quando a configuração do dispositivo muda (por exemplo, devido à rotação) e isso não é processado pelo próprio app, a visibilidade anterior do IME não é restaurada.

Se o app passar por uma mudança de configuração que não processa e precisar que o teclado fique visível após a mudança, você precisará solicitar isso explicitamente. É possível fazer essa solicitação de uma das seguintes maneiras:

  • Defina o atributo android:windowSoftInputMode como stateAlwaysVisible.
  • Solicite o teclado de software de forma programática no método onCreate() da atividade ou adicione o método onConfigurationChanged().

Contribuição humana

O Android 17 inclui as mudanças abaixo que afetam como os apps interagem com dispositivos de entrada humana, como teclados e touchpads.

Os touchpads fornecem eventos relativos por padrão durante a captura de ponteiro

A partir do Android 17, se um app solicitar a captura de ponteiro usando View.requestPointerCapture() e o usuário usar um touchpad, o sistema vai reconhecer o movimento do ponteiro e os gestos de rolagem dos toques do usuário e vai informar ao app da mesma forma que os movimentos do ponteiro e da roda de rolagem de um mouse capturado. Na maioria dos casos, isso elimina a necessidade de os apps que oferecem suporte a mouses capturados adicionarem uma lógica de processamento especial para touchpads. Para mais detalhes, consulte a documentação de View.POINTER_CAPTURE_MODE_RELATIVE.

Anteriormente, o sistema não tentava reconhecer gestos do touchpad e, em vez disso, fornecia os locais brutos e absolutos dos dedos ao app em um formato semelhante aos toques na tela touch. Se um app ainda precisar desses dados absolutos, ele precisará chamar o novo método View.requestPointerCapture(int) com View.POINTER_CAPTURE_MODE_ABSOLUTE.

Mídia

O Android 17 inclui as seguintes mudanças no comportamento de mídia.

Proteção de áudio em segundo plano

A partir do Android 17, o framework de áudio aplica restrições a interações de áudio em segundo plano, incluindo reprodução de áudio, solicitações de foco de áudio e APIs de mudança de volume para garantir que essas mudanças sejam iniciadas intencionalmente pelo usuário.

Se o app tentar chamar APIs de áudio enquanto não estiver em um ciclo de vida válido, as APIs de reprodução de áudio e mudança de volume vão falhar silenciosamente sem gerar uma exceção ou fornecer uma mensagem de falha. A API de foco de áudio falha com o código de resultado AUDIOFOCUS_REQUEST_FAILED.

Para mais informações, incluindo estratégias de mitigação, consulte Proteção de áudio em segundo plano.

Conectividade

O Android 17 inclui as mudanças abaixo para melhorar a conectividade do dispositivo.

Repareamento autônomo para perdas de conexão Bluetooth

O Android 17 apresenta o novo pareamento autônomo, uma melhoria no sistema projetada para resolver automaticamente a perda de conexão Bluetooth.

Antes, se uma conexão fosse perdida, os usuários precisavam acessar manualmente as Configurações para desparear e parear novamente o periférico. Esse recurso se baseia na melhoria de segurança do Android 16, permitindo que o sistema restabeleça vínculos em segundo plano sem que os usuários precisem acessar manualmente as Configurações para desparear e parear novamente os periféricos.

Embora a maioria dos apps não exija mudanças no código, os desenvolvedores precisam estar cientes das seguintes mudanças de comportamento na pilha do Bluetooth:

  • Novo contexto de pareamento:o ACTION_PAIRING_REQUEST agora inclui o extra EXTRA_PAIRING_CONTEXT, que permite que os apps diferenciem uma solicitação de pareamento padrão de uma tentativa de repareamento iniciada pelo sistema autônomo.
  • Atualizações de chave condicionais:as chaves de segurança atuais só serão substituídas se o novo pareamento for bem-sucedido e a nova conexão atender ou exceder o nível de segurança da conexão anterior.
  • Momento da intent modificado:a intent ACTION_KEY_MISSING agora é transmitida apenas se a tentativa de novo pareamento autônomo falhar. Isso reduz o tratamento de erros desnecessário no app se o sistema recuperar a vinculação em segundo plano.
  • Notificação do usuário:o sistema gerencia o novo pareamento usando novas notificações e caixas de diálogo da interface. Os usuários vão precisar confirmar a tentativa de pareamento para garantir que estão cientes da reconexão.

Os fabricantes de dispositivos periféricos e os desenvolvedores de apps complementares precisam verificar se o hardware e o app lidam corretamente com as transições de vínculo. Para testar esse comportamento, simule uma perda de vínculo remoto usando um dos seguintes métodos:

  • Remover manualmente as informações de vínculo do dispositivo periférico
  • Despareie o dispositivo manualmente em: Configurações > Dispositivos conectados.