Mudanças de comportamento: todos os apps

O Android 10 inclui mudanças de comportamento que podem afetar seu app. As mudanças listadas nesta página se aplicam ao app quando executado no Android 10, independentemente da targetSdkVersion. Teste seu app e modifique-o conforme necessário para oferecer suporte a essas mudanças.

Se a targetSdkVersion do seu app for 29 ou mais recente, você também precisará oferecer compatibilidade com outras alterações. Leia as mudanças de comportamento para apps destinados ao 29 para ver mais detalhes.

Observação : além das mudanças listadas nesta página, o Android 10 introduz um grande número de mudanças e restrições com base na privacidade, incluindo o seguinte:

  • Acesso em segundo plano à localização do dispositivo
  • Início da atividade em segundo plano
  • Informações de afinidade de contatos
  • Randomização de endereço MAC
  • Metadados da câmera
  • Modelo de permissões

Essas mudanças afetam todos os apps e melhoram a privacidade do usuário. Para saber mais sobre como oferecer suporte a essas mudanças, consulte a página Mudanças de privacidade.

Restrições da interface não SDK

Para ajudar a garantir a estabilidade e a compatibilidade do app, a plataforma começou a restringir quais interfaces não SDK seu app pode usar no Android 9 (nível 28 da API). O Android 10 inclui listas atualizadas de interfaces não SDK restritas com base na colaboração com desenvolvedores Android e nos testes internos mais recentes. Nosso objetivo é garantir que alternativas públicas estejam disponíveis antes de restringirmos interfaces não SDK.

Se você não pretende segmentar o Android 10 (nível 29 da API), é 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 tem certeza se seu app usa interfaces não SDK, teste-o para descobrir. Se ele depende de interfaces não SDK, comece a planejar 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 externa ao SDK em um recurso no app, solicite uma nova API pública.

Para saber mais, consulte Atualizações para restrições de interface não SDK no Android 10 e Restrições para interfaces não SDK.

Navegação por gestos

A partir do Android 10, os usuários podem ativar a navegação por gestos no dispositivo. Se um usuário ativar a navegação por gestos, isso afetará todos os apps no dispositivo, independentemente de o app ser ou não destinado ao nível 29 da API. Por exemplo, se o usuário deslizar da borda da tela para dentro, o sistema interpretará esse gesto como uma navegação para voltar, a menos que um app modifique especificamente esse gesto para partes da tela.

Para tornar seu app compatível com a navegação por gestos, estenda o conteúdo do app de ponta a ponta e processe adequadamente os gestos conflitantes. Para mais informações, consulte a documentação Navegação por gestos.

NDK

O Android 10 inclui as alterações do NDK descritas a seguir.

Objetos compartilhados não podem conter realocações de texto

O Android 6.0 (nível 23 da API) não permitia o uso de realocações de texto em objetos compartilhados. O código precisa ser carregado como está e não pode ser modificado. Essa alteração melhora o tempo de carregamento e a segurança dos apps.

O SELinux aplica essa restrição em apps destinados ao Android 10 ou versões mais recentes. Esses apps correm alto risco de serem corrompidos caso continuem usando objetos compartilhados que contenham realocações de texto.

Alterações nos caminhos das bibliotecas Bionic e do vinculador dinâmico

A partir do Android 10, vários caminhos são links simbólicos em vez de arquivos normais. Os apps que dependem dos caminhos serem arquivos comuns podem ser corrompidos:

  • /system/lib/libc.so -> /apex/com.android.runtime/lib/bionic/libc.so
  • /system/lib/libm.so -> /apex/com.android.runtime/lib/bionic/libm.so
  • /system/lib/libdl.so -> /apex/com.android.runtime/lib/bionic/libdl.so
  • /system/bin/linker -> /apex/com.android.runtime/bin/linker

Essas mudanças também se aplicam às variantes de 64 bits do arquivo, com lib/ substituído por lib64/.

Para compatibilidade, os links simbólicos são fornecidos nos caminhos antigos. Por exemplo, /system/lib/libc.so é um link simbólico para /apex/com.android.runtime/lib/bionic/libc.so. Portanto, o dlopen(“/system/lib/libc.so”) continua funcionando, mas os apps vão descobrir a diferença quando tentarem examinar as bibliotecas carregadas lendo /proc/self/maps ou semelhante, o que não é normal, mas descobrimos que alguns apps fazem isso como parte do processo anti-hacking. Nesse caso, os caminhos /apex/… precisam ser adicionados como caminhos válidos para os arquivos Bionic.

Binários/bibliotecas do sistema mapeados para memória somente de execução

No Android 10 e versões mais recentes, segmentos executáveis de binários e bibliotecas do sistema são mapeados para memória somente de execução (não legível) como uma técnica de proteção contra ataques de reutilização de código. Se o app realizar operações de leitura em segmentos de memória marcados como somente execução, seja por bug, vulnerabilidade ou inspeção intencional da memória, o sistema vai enviar um sinal SIGSEGV ao app.

É possível identificar se esse comportamento causou uma falha examinando o arquivo tombstone relacionado em /data/tombstones/. Uma falha relacionada somente à execução contém a seguinte mensagem de cancelamento:

Cause: execute-only (no-read) memory access error; likely due to data in .text.

Para contornar esse problema e realizar operações como inspeção de memória, é possível marcar segmentos somente de execução como leitura + execução chamando mprotect(). No entanto, é altamente recomendável defini-la novamente para somente execução em seguida, já que essa configuração de permissão de acesso oferece melhor proteção para seu app e usuários.

Segurança

O Android 10 inclui as seguintes alterações de segurança.

TLS 1.3 ativado por padrão

No Android 10 e versões mais recentes, o TLS 1.3 é ativado por padrão para todas as conexões TLS. Confira alguns detalhes importantes sobre nossa implementação do TLS 1.3:

  • Os conjuntos de criptografia do TLS 1.3 não podem ser personalizados. Os pacotes de criptografia do TLS 1.3 compatíveis são sempre ativados quando o TLS 1.3 está ativado. Qualquer tentativa de desativá-los chamando setEnabledCipherSuites() será ignorada.
  • Quando o TLS 1.3 é negociado, os objetos HandshakeCompletedListener são chamados antes da adição das sessões ao cache da sessão. No TLS 1.2 e em outras versões anteriores, esses objetos são chamados depois que as sessões são adicionadas ao cache da sessão.
  • Em algumas situações em que as instâncias de SSLEngine geram uma SSLHandshakeException em versões anteriores do Android, essas instâncias geram uma SSLProtocolException no Android 10 e versões mais recentes.
  • Não há suporte ao modo 0-RTT.

Se quiser, é possível conseguir um SSLContext que tenha o TLS 1.3 desativado chamando SSLContext.getInstance("TLSv1.2"). Também é possível ativar ou desativar versões de protocolo em cada conexão, chamando setEnabledProtocols() em um objeto apropriado.

Certificados assinados com SHA-1 não são confiáveis no TLS

No Android 10, os certificados que usam o algoritmo de hash SHA-1 não são confiáveis nas conexões TLS. As ACs raiz não emitem esse certificado desde 2016 e não são mais confiáveis no Chrome ou em outros principais navegadores.

Qualquer tentativa de conexão falhará se a conexão for com um site que apresente um certificado usando SHA-1.

Mudanças e melhorias no comportamento do KeyChain

Alguns navegadores, como o Google Chrome, permitem que os usuários escolham um certificado quando um servidor TLS envia uma mensagem de solicitação de certificado como parte de um handshake de TLS. A partir do Android 10, os objetos KeyChain respeitam os emissores e os parâmetros de especificação da chave ao chamar KeyChain.choosePrivateKeyAlias() para mostrar aos usuários uma solicitação de seleção de certificado. Em particular, esse prompt não contém opções que não atendem às especificações do servidor.

Se não houver certificados selecionáveis pelo usuário disponíveis, como acontece quando nenhum certificado corresponde à especificação do servidor ou um dispositivo não tem nenhum certificado instalado, o prompt de seleção de certificado não vai aparecer.

Além disso, não é necessário ter um bloqueio de tela do dispositivo para importar chaves ou certificados de AC para um objeto KeyChain no Android 10 ou versões mais recentes.

Outras mudanças de TLS e criptografia

Houve várias pequenas mudanças nas bibliotecas de TLS e criptografia que entraram em vigor no Android 10:

  • As criptografias AES/GCM/NoPadding e ChaCha20/Poly1305/NoPadding retornam tamanhos de buffer mais precisos do getOutputSize().
  • O pacote de criptografia TLS_FALLBACK_SCSV é omitido das tentativas de conexão com um protocolo máximo de TLS 1.2 ou mais recente. Devido a melhorias nas implementações do servidor TLS, não recomendamos a tentativa de substituto externo ao TLS. Em vez disso, recomendamos confiar na negociação da versão do TLS.
  • ChaCha20-Poly1305 é um alias para ChaCha20/Poly1305/NoPadding.
  • Nomes de host com pontos à direita não são considerados nomes de host SNI válidos.
  • A extensão supported_signature_algorithms em CertificateRequest é respeitada ao escolher uma chave de assinatura para respostas de certificado.
  • Chaves de assinatura opacas, como as do Android Keystore, podem ser usadas com assinaturas RSA-PSS no TLS.

Transmissões do Wi-Fi Direct

No Android 10, as seguintes transmissões relacionadas ao Wi-Fi Direct não são fixas:

Se o app dependia do recebimento dessas transmissões no momento de registro porque elas eram fixas, use o método get() apropriado na inicialização para receber as informações.

Funções do Wi-Fi Aware

O Android 10 adiciona compatibilidade para facilitar a criação de soquetes TCP/UDP usando caminhos de dados do Wi-Fi Aware. Para criar um soquete TCP/UDP conectando-se a um ServerSocket, o dispositivo cliente precisa saber o endereço IPv6 e a porta do servidor. Anteriormente, isso precisava ser comunicado fora de banda, por exemplo, usando mensagens de camada 2 por BT ou Wi-Fi Aware, ou descoberto dentro da banda usando outros protocolos, como mDNS. Com o Android 10, as informações podem ser comunicadas como parte da configuração da rede.

O servidor pode fazer uma destas ações:

  • Inicialize um ServerSocket e defina ou consiga a porta a ser usada.
  • Especificar as informações da porta como parte da solicitação de rede Wi-Fi Aware.

O exemplo de código abaixo mostra como especificar as informações da porta como parte da solicitação de rede:

Kotlin

val ss = ServerSocket()
val ns = WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle)
  .setPskPassphrase("some-password")
  .setPort(ss.localPort)
  .build()

val myNetworkRequest = NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
  .setNetworkSpecifier(ns)
  .build()

Java

ServerSocket ss = new ServerSocket();
WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier
  .Builder(discoverySession, peerHandle)
  .setPskPassphrase(“some-password”)
  .setPort(ss.getLocalPort())
  .build();

NetworkRequest myNetworkRequest = new NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
  .setNetworkSpecifier(ns)
  .build();

Em seguida, o cliente executa uma solicitação de rede Wi-Fi Aware para conseguir o IPv6 e a porta fornecida pelo servidor:

Kotlin


val callback = object : ConnectivityManager.NetworkCallback() {
  override fun onAvailable(network: Network) {
    ...
  }
  
  override fun onLinkPropertiesChanged(network: Network,
      linkProperties: LinkProperties) {
    ...
  }

  override fun onCapabilitiesChanged(network: Network,
      networkCapabilities: NetworkCapabilities) {
    ...
    val ti = networkCapabilities.transportInfo
    if (ti is WifiAwareNetworkInfo) {
       val peerAddress = ti.peerIpv6Addr
       val peerPort = ti.port
    }
  }
  override fun onLost(network: Network) {
    ...
  }
};

connMgr.requestNetwork(networkRequest, callback)

Java

callback = new ConnectivityManager.NetworkCallback() {
  @Override
  public void onAvailable(Network network) {
    ...
  }
  @Override
  public void onLinkPropertiesChanged(Network network,
      LinkProperties linkProperties) {
    ...
  }
  @Override
  public void onCapabilitiesChanged(Network network,
      NetworkCapabilities networkCapabilities) {
    ...
    TransportInfo ti = networkCapabilities.getTransportInfo();
    if (ti instanceof WifiAwareNetworkInfo) {
       WifiAwareNetworkInfo info = (WifiAwareNetworkInfo) ti;
       Inet6Address peerAddress = info.getPeerIpv6Addr();
       int peerPort = info.getPort();
    }
  }
  @Override
  public void onLost(Network network) {
    ...
  }
};

connMgr.requestNetwork(networkRequest, callback);

SYSTEM_ALERT_WINDOW em dispositivos Android Go

Apps executados em dispositivos Android 10 (versão Go) não podem receber a permissão SYSTEM_ALERT_WINDOW. Isso ocorre porque o desenho de janelas de sobreposição usa memória excessiva, o que é particularmente prejudicial ao desempenho de dispositivos Android com pouca memória.

Se um app executado em um dispositivo Go com o Android 9 ou versões anteriores receber a permissão SYSTEM_ALERT_WINDOW, ele vai manter a permissão mesmo que o dispositivo seja atualizado para o Android 10. No entanto, os apps que ainda não têm essa permissão não poderão recebê-la depois do upgrade do dispositivo.

Se um app em um dispositivo Go enviar uma intent com a ação ACTION_MANAGE_OVERLAY_PERMISSION, o sistema vai negar a solicitação automaticamente e direcionar o usuário para uma tela Configurações que informa que a permissão não é permitida porque o dispositivo fica lento. Se um app em um dispositivo Go chamar Settings.canDrawOverlays(), o método sempre retornará "false". Novamente, essas restrições não se aplicam a apps que receberam a permissão SYSTEM_ALERT_WINDOW antes do upgrade do dispositivo para o Android 10.

Avisos para apps voltados a versões anteriores do Android

Os dispositivos com o Android 10 ou versões mais recentes avisam os usuários na primeira vez que eles executam qualquer app direcionado ao Android 5.1 (nível 22 da API) ou versões anteriores. Se o app exigir que o usuário conceda permissões, ele também poderá ajustar as permissões do app antes que ele possa ser executado pela primeira vez.

Devido aos requisitos de API de destino do Google Play, o usuário recebe esses avisos somente quando executa um app que não foi atualizado recentemente. Para apps distribuídos por outras lojas, requisitos de API de destino semelhantes entraram em vigor em 2019. Para mais informações sobre esses requisitos, consulte Expansão dos requisitos de nível desejado da API em 2019.

Conjuntos de criptografia CBC SHA-2 removidos

Os seguintes conjuntos de criptografia CBC SHA-2 foram removidos da plataforma:

  • TLS_RSA_WITH_AES_128_CBC_SHA256
  • TLS_RSA_WITH_AES_256_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384

Esses conjuntos de criptografia são menos seguros do que os semelhantes que usam o GCM. A maioria dos servidores é compatível com as variantes GCM e CBC desses pacotes ou não oferece suporte a nenhum deles.

Uso de apps

O Android 10 traz as seguintes mudanças de comportamento relacionadas ao uso de apps:

  • Melhorias no uso do app Estatísticas de uso - 1 - o uso de apps do app com precisão - na imagem - Além disso, o Android 10 rastreia corretamente o uso de apps instantâneos.

  • Escala de cinza por app - uma base de cinza da exibição

  • Estado de distração por app - 1 sentido 1 quando os apps 1 selecionados não aparecem 1 como as notificações 1 1 quando os apps são selecionados

  • Suspensão e reprodução -

Mudanças na conexão HTTPS

Se um app que executa o Android 10 transmitir null para setSSLSocketFactory(), ocorre uma IllegalArgumentException. Nas versões anteriores, transmitir null para setSSLSocketFactory() tinha o mesmo efeito que a transmissão da fábrica padrão atual.

A biblioteca android.preference está obsoleta

A biblioteca android.preference foi descontinuada a partir do Android 10. Em vez disso, os desenvolvedores precisam usar a biblioteca de preferências do AndroidX, parte do Android Jetpack. Para conferir outros recursos que podem ajudar na migração e no desenvolvimento, confira o Guia de configurações atualizado, além do nosso app de exemplo público e da documentação de referência (links em inglês).

Mudanças na biblioteca de utilitários de arquivos ZIP

O Android 10 introduz as seguintes mudanças nas classes no pacote java.util.zip, que processa arquivos ZIP. Essas mudanças tornam o comportamento da biblioteca mais consistente entre o Android e outras plataformas que usam java.util.zip.

Inflater

Nas versões anteriores, alguns métodos na classe Inflater geravam uma IllegalStateException se fossem invocados após uma chamada para end(). No Android 10, esses métodos geram uma NullPointerException.

ZipFile

No Android 10 e versões mais recentes, o construtor para ZipFile que usa argumentos do tipo File, int e Charset não vai gerar uma ZipException se o arquivo ZIP fornecido não tiver nenhum arquivo.

ZipOutputStream

No Android 10 e versões mais recentes, o método finish() em ZipOutputStream não gera um ZipException se tentar gravar um stream de saída para um arquivo ZIP que não contenha nenhum arquivo.

Mudanças da câmera

Muitos apps que usam câmera presumem que, se o dispositivo estiver na configuração retrato, o dispositivo físico também estará na orientação retrato, conforme descrito em Orientação da câmera. No passado, essa era uma suposição segura, mas ela mudou com a expansão dos formatos disponíveis, como dispositivos dobráveis. Essa suposição nesses dispositivos pode levar a uma exibição girada ou dimensionada incorretamente (ou ambos) do visor da câmera.

Os aplicativos direcionados ao nível 24 da API ou mais recente precisam definir android:resizeableActivity explicitamente e fornecer a funcionalidade necessária para processar operações em várias janelas.

Acompanhamento de uso da bateria

No Android 10 e versões mais recentes, SystemHealthManager redefine as estatísticas de uso da bateria sempre que o dispositivo é desconectado após um grande evento de carregamento. Em termos gerais, um grande evento de carregamento é quando o dispositivo foi totalmente carregado ou o dispositivo passou de quase vazio para quase carregado.

Antes do Android 10, as estatísticas de uso da bateria eram redefinidas sempre que o dispositivo era desconectado, não importa quão pequena tivesse sido a mudança no nível da bateria.

Obsolescência do Android Beam

No Android 10, estamos oficialmente descontinuando o Android Beam, um recurso antigo para iniciar o compartilhamento de dados entre dispositivos por meio da comunicação a curta distância (NFC, na sigla em inglês). Também estamos descontinuando várias das APIs NFC relacionadas. O Android Beam permanece opcional para parceiros fabricantes de dispositivos que queiram usá-lo, mas não está mais em desenvolvimento ativo. No entanto, o Android vai continuar oferecendo suporte a outros recursos e APIs de NFC, e casos de uso como leitura de etiquetas e pagamentos vão continuar funcionando conforme o esperado.

Mudança de comportamento java.math.Bigdecimal.stripTrailingZeros()

BigDecimal.stripTrailingZeros() não preserva mais zeros à direita como um caso especial se o valor de entrada for zero.

Mudanças de comportamento de java.util.regex.Matcher e de padrão

O resultado de split() foi mudado para não começar mais com um String ("") vazio quando há uma correspondência de largura zero no início da entrada. Isso também afeta String.split(). Por exemplo, "x".split("") agora retorna {"x"}, enquanto costumava retornar {"", "x"} em versões mais antigas do Android. "aardvark".split("(?=a)" agora retorna {"a", "ardv", "ark"} em vez de {"", "a", "ardv", "ark"}.

O comportamento de exceção para argumentos inválidos também foi aprimorado:

  • appendReplacement(StringBuffer, String) agora gera uma IllegalArgumentException em vez de IndexOutOfBoundsException se o String substituto terminar com uma única barra invertida, o que é ilegal A mesma exceção será gerada se a String substituta terminar com uma $. Anteriormente, nenhuma exceção era gerada nesse cenário.
  • replaceFirst(null) não vai mais chamar reset() no Matcher se gerar uma NullPointerException. NullPointerException agora também é gerado quando não há correspondência. Antes, ele só era gerado quando havia uma correspondência.
  • start(int group), end(int group) e group(int group) agora geram uma IndexOutOfBoundsException mais geral se o índice do grupo estiver fora dos limites Anteriormente, esses métodos geravam ArrayIndexOutOfBoundsException.

O ângulo padrão do GradientDrawable agora é TOP_BOTTOM

No Android 10, se você definir um GradientDrawable em XML e não fornecer uma medida de ângulo, a orientação do gradiente será padronizada como TOP_BOTTOM. Essa é uma mudança em relação às versões anteriores do Android, em que o padrão era LEFT_RIGHT.

Como solução alternativa, se você atualizar para a versão mais recente do AAPT2, a ferramenta vai definir uma medida de ângulo de 0 para apps legados se nenhuma medida de ângulo for especificada.

Geração de registros para objetos serializados usando o SUID padrão

No Android 7.0 (nível 24 da API) e versões mais recentes, a plataforma fez uma correção no serialVersionUID padrão para objetos serializáveis. Essa correção não afetou os apps direcionados ao nível 23 da API ou versões anteriores.

A partir do Android 10, se um app for direcionado ao nível 23 da API ou anterior e depender do serialVersionUID padrão antigo, incorreto, o sistema registrará um aviso e sugerirá uma correção de código.

Especificamente, o sistema registrará um aviso se todas as condições a seguir forem verdadeiras:

  • O aplicativo é direcionado ao nível 23 da API ou inferior.
  • Uma classe é serializada.
  • A classe serializada usa o serialVersionUID padrão, em vez de definir explicitamente um serialVersionUID.
  • O serialVersionUID padrão é diferente do serialVersionUID se o app fosse direcionado ao nível 24 da API ou mais recente.

Esse aviso é registrado uma vez para cada classe afetada. A mensagem de aviso inclui uma correção sugerida, que é definir explicitamente o serialVersionUID como o valor padrão que seria calculado se o app fosse direcionado ao nível 24 da API ou mais recente. Ao usar essa correção, você garante que, se um objeto dessa classe for serializado em um app direcionado ao nível 23 da API ou anterior, ele será lido corretamente por apps destinados à versão 24 ou mais recente e vice-versa.

Mudanças em java.io.FileChannel.map()

A partir do Android 10, FileChannel.map() não oferece suporte a arquivos não padrão, como /dev/zero, cujo tamanho não pode ser alterado usando truncate(). As versões anteriores do Android processavam o errno retornado por truncate(), mas o Android 10 gerava uma IOException. Se você precisar do comportamento antigo, será necessário usar o código nativo.