Mudanças de comportamento: todos os aplicativos

O Android 9 (API de nível 28) introduz diversas mudanças ao sistema Android. As mudanças de comportamento a seguir se aplicam a todos os aplicativos quando são executados na plataforma Android 9, independentemente do nível de API ao qual eles estejam direcionados. Todos os desenvolvedores devem analisar essas mudanças e adaptar seus aplicativos a elas sempre que aplicável.

Consulte as mudanças que afetam somente aplicativos direcionados ao nível de API 28 ou superior em Mudanças de comportamento: aplicativos direcionados a níveis de API acima do 28.

Gerenciamento de energia

O Android 9 introduz novos recursos para melhorar o gerenciamento de energia dos dispositivos. Essas mudanças, além dos recursos apresentados antes do Android 9, ajudam a garantir que os recursos do sistema estejam disponíveis aos aplicativos que mais precisam.

Para ver detalhes, leia Gerenciamento de energia.

Mudanças de privacidade

Para proteger ainda mais a privacidade do usuário, o Android 9 lança diversas mudanças de comportamento, como a limitação do acesso a sensores do dispositivo por parte dos aplicativos em segundo plano, a restrição de informações obtidas de verificações de Wi-Fi e novas regras e grupos de permissão relacionadas a chamadas telefônicas, ao estado do telefone e a verificações de Wi-Fi.

Essas mudanças afetam todos os aplicativos que operam no Android 9, independentemente da versão-alvo do SDK.

Acesso limitado a sensores quando em segundo plano

O Android 9 limita o acesso à interação do usuário e a dados dos sensores para aplicativos em segundo plano. Se seu aplicativo estiver sendo executado em segundo plano em um dispositivo com Android 9, o sistema aplicará as seguintes restrições a ele:

  • O aplicativo não poderá acessar o microfone nem a câmera.
  • Sensores que usam o modo de relatório continuous , como acelerômetros e giroscópios, não receberão eventos.
  • Sensores que usam os modos de relatório on-change ou one-shot não receberão eventos.

Se seu aplicativo precisar detectar eventos de sensor em dispositivos com o Android 9, use um serviço de primeiro plano.

Acesso restrito a registros de chamada

O Android 9 apresenta o grupo de permissões CALL_LOG e transfere as permissões READ_CALL_LOG, WRITE_CALL_LOG e PROCESS_OUTGOING_CALLS para esse grupo. Nas versões anteriores do Android, essas permissões ficavam no grupo de permissões PHONE.

O grupo de permissões CALL_LOG dá aos usuários maior controle e visibilidade dos aplicativos que precisam de acesso a informações confidenciais sobre chamadas telefônicas, como a leitura do registro de chamadas e a identificação de números de telefone.

Se o aplicativo precisa acessar o registro de chamadas ou processar chamadas feitas, você deve solicitar essas permissões explicitamente pelo grupo de permissões CALL_LOG. Caso contrário, uma SecurityException vai ser gerada.

Observação: como essas permissões mudaram os grupos e são concedidas em tempo de execução, é possível que o usuário negue o acesso às informações do registro de chamadas telefônicas ao seu aplicativo. Nesse caso, o aplicativo deve ser capaz de lidar com a falta de acesso às informações sem problemas.

Se seu aplicativo já segue as práticas recomendadas para permissões em tempo de execução, ele consegue lidar com a mudança no grupo de permissões.

Acesso restrito a números de telefone

Os aplicativos que operam no Android 9 não podem ler números de telefone ou o estado do telefone sem antes adquirir a permissão READ_CALL_LOG, além de outras permissões que dependem do caso de uso do aplicativo.

Números de telefone associados a chamadas feitas e recebidas são visíveis na transmissão do estado do telefone, assim como para as chamadas feitas e recebidas, e podem ser acessados com a classe PhoneStateListener. Porém, sem a permissão READ_CALL_LOG, o campo do número de telefone fornecido nas transmissões PHONE_STATE_CHANGED e pelo PhoneStateListener fica vazio.

Para ler números de telefone pelo estado do telefone, atualize seu aplicativo e faça-o solicitar as permissões necessárias de acordo com o caso de uso:

Acesso restrito às informações de localização e conexão do Wi-Fi

No Android 9, as necessidades de permissão que um aplicativo tem para realizar verificações de Wi-Fi são mais restritas do que nas versões anteriores. Para saber mais, acesse Restrições de verificação de Wi-Fi.

Restrições semelhantes também se aplicam ao método getConnectionInfo(), que retorna um objeto WifiInfo que descreve a conexão com Wi-Fi atual. Você só pode usar os métodos desse objeto para obter os valores de SSID e BSSID se o aplicativo solicitante tiver as seguintes permissões:

  • ACCESS_FINE_LOCATION ou ACCESS_COARSE_LOCATION
  • ACCESS_WIFI_STATE

Para obter o SSID ou o BSSID, os serviços de localização do dispositivo devem estar habilitados (em Configurar > Localização).

Informações removidas dos métodos de serviço Wi-Fi

No Android 9, os eventos e transmissões a seguir não recebem informações sobre a localização nem sobre dados pessoais do usuário:

A transmissão NETWORK_STATE_CHANGED_ACTION do sistema pelo Wi-Fi não contém mais o SSID (antes chamado de EXTRA_SSID), o BSSID (antes chamado de EXTRA_BSSID) nem informações da conexão (antes chamadas de EXTRA_NETWORK_INFO). Se o aplicativo precisar dessas informações, chame getConnectionInfo().

Agora as informações de telefonia dependem da configuração de localização do dispositivo

Se o usuário desativou a localização do dispositivo em um dispositivo com Android 9, os métodos abaixo não produzem resultado:

Restrições para o uso de interfaces que não fazem parte do SDK

Para ajudar a garantir a estabilidade e a compatibilidade do aplicativo, a plataforma restringe o uso de de alguns métodos e campos não pertencentes ao SDK. Essas restrições se aplicam mesmo que você tente acessar os métodos e campos diretamente, via reflexão ou usando JNI. No Android 9, seu aplicativo pode continuar acessando essas interfaces restritas — a plataforma usa toasts e entradas de registro para chamar sua atenção. Se seu aplicativo mostrar esse toast, é importante adotar uma estratégia de implementação diferente da interface restrita. Se você acredita que estratégias alternativas não são viáveis, registre um bug para solicitar uma reavaliação da restrição.

O Restrições em interfaces externas ao SDK contém mais informações importantes. Você deve ler esse artigo para ter certeza de que o seu aplicativo continue funcionando corretamente.

Mudanças de comportamento de segurança

Mudanças na segurança do dispositivo

O Android 9 traz diversos recursos que aumentam a segurança do aplicativo, seja qual for a versão de plataforma dele.

Mudanças na implementação do TLS

A implementação do TLS do sistema sofreu diversas alterações no Android 9:

  • Se uma instância de SSLSocket não se conectar enquanto estiver sendo criada, o sistema gerará uma IOException, e não mais uma NullPointerException.
  • A classe SSLEngine passa a gerenciar de forma simples todos os alertas de close_notify que ocorrerem.

Para saber mais sobre como criar solicitações web seguras em um aplicativo Android, leia Um exemplo de HTTPS.

Filtro de SECCOMP mais rígido

O Android 9 restringe ainda mais as chamadas de sistema disponíveis aos aplicativos. Esse comportamento é uma extensão do filtro de SECCOMP incluso no Android 8.0 (API de nível 26).

Observação: essa mudança só afeta aplicativos que usam chamadas de sistema privilegiadas.

Mudanças na criptografia

O Android 9 introduz várias mudanças na implementação e no processamento de algoritmos criptográficos.

Implementações Conscrypt de parâmetros e algoritmos

O Android 9 oferece mais implementações de parâmetros de algoritmo no Conscrypt. Esses parâmetros incluem: AES, DESEDE, OAEP e EC. As versões do Bouncy Castle desses parâmetros e muitos algoritmos foram removidos a partir do Android 9.

Observação: A implementação do Conscrypt do parâmetro EC só oferece suporte a curvas nomeadas.

Se seu aplicativo for destinado ao Android 8.1 (nível de API 27) ou a uma versão anterior, você receberá um aviso quando solicitar uma implementação Bouncy Castle de um desses algoritmos obsoletos. Porém, se seu aplicativo é voltado ao Android 9, cada uma dessas solicitações gerará um NoSuchAlgorithmException.

Outras mudanças

O Android 9 apresenta diversas outras alterações relacionadas a criptografia:

  • Ao usar chaves PBE, se o Bouncy Castle estiver esperando um vetor de inicialização (IV) e seu aplicativo não fornecer um, você receberá um aviso.
  • A implementação Conscrypt da cifra ARC4 permite que você especifique ARC4/ECB/NoPadding ou ARC4/NONE/NoPadding.
  • O provedor Crypto Java Cryptography Architecture (JCA) foi removido. Por esse motivo, se seu aplicativo chamar SecureRandom.getInstance("SHA1PRNG", "Crypto"), uma NoSuchProviderException ocorrerá.
  • Se seu aplicativo analisar chaves RSA em buffers maiores do que a estrutura da chave, não ocorrerá mais uma exceção.

Para saber mais sobre como usar os recursos criptográficos do Android, leia Criptografia.

Arquivos criptografados protegidos pelo Android não têm mais suporte

O Android 9 remove totalmente o suporte a arquivos criptografados protegidos Android (ASECs).

No Android 2.2 (API de nível 8), os ASECs foram lançados para que houvesse compatibilidade com o recurso "aplicativos em cartão SD". No Android 6.0 (API de nível 23), a plataforma lançou uma tecnologia de dispositivo de armazenamento adotável, que os desenvolvedores podem usar no lugar do ASECs.

Atualizações nas bibliotecas de ICU

O Android 9 usa a versão 60 da biblioteca ICU. O Android 8.0 (API de nível 26) e o Android 8.1 (API de nível 27) usam a ICU 58.

A ICU é usada para fornecer APIs públicas dentro de android.icu package e é usada internamente na plataforma Android para suporte à internacionalização. Por exemplo, ela é usada para implementar classes Android em java.util, java.text e android.text.format.

A atualização para a ICU 60 contém muitas alterações pequenas, mas úteis, como o suporte a dados do Emoji 5.0 e melhorias nos formatos de data/hora, conforme documentado nas notas da versão 59 e 60 da ICU.

Estas são algumas mudanças de destaque dessa atualização:

  • A forma como a plataforma lida com fusos horários mudou.
    • A plataforma lida melhor com GMT e UTC (UTC não é mais sinônimo de GMT).

      A ICU agora fornece nomes de fusos traduzidos para GMT e UTC. Essa mudança afeta o comportamento de formatação e análise de android.icu para fusos como "GMT", "Etc/GMT", "UTC", "Etc/UTC” e "Zulu".

    • java.text.SimpleDateFormat agora usa a ICU para fornecer nomes de exibição para UTC/GMT, o que significa que:
      • A formatação zzzz gera uma string longa localizada para muitas localidades. Antes, ela produzia "UTC" para UTC e strings como "GMT+00H00" para GMT.
      • A análise de zzzz reconhece strings como "Universal Coordinated Time” e "Greenwich Mean Time".
      • Os aplicativos podem experimentar problemas de compatibilidade se presumirem que "UTC" ou "GMT+00:00" são saídas de zzzz em todos os idiomas.
    • O comportamento de java.text.DateFormatSymbols.getZoneStrings() mudou:
      • Assim como com SimpleDateFormat, UTC e GMT agora têm nomes longos. Variantes DST de nomes de fusos horários para UTC, como as "UTC", "Etc/UTC” e "Zulu", se tornaram GMT+00:00, que é a alternativa padrão quando não há nomes disponíveis, em vez da string codificada UTC.
      • Alguns IDs de fusos são corretamente reconhecidos como sinônimos de outros fusos, portanto, o Android encontra strings para IDs de fusos arcaicos, como Eire, que antes não podiam ser resolvidos.
    • Ásia/Hanoi não é mais um fuso reconhecido. Por esse motivo, java.util.TimeZones.getAvailableIds() não retorna esse valor e java.util.TimeZone.getTimeZone() não o reconhece. Esse comportamento é consistente com o comportamento android.icu existente.
  • O método android.icu.text.NumberFormat.getInstance(ULocale, PLURALCURRENCYSTYLE).parse(String) pode gerar uma ParseException, mesmo ao analisar texto de moeda legítimo. Para evitar esse problema, use NumberFormat.parseCurrency, disponível desde o Android 7.0 (API de nível 24), para texto de moeda com estilo PLURALCURRENCYSTYLE.

Mudanças no Android Test

O Android 9 introduziu diversas mudanças à biblioteca e à estrutura de classes da estrutura do Android Test. Essas mudanças ajudam os desenvolvedores a usar APIs públicas compatíveis com a biblioteca, mas também dão maior flexibilidade de desenvolvimento e execução de testes usando bibliotecas de terceiros ou lógica personalizada.

Bibliotecas removidas da estrutura

O Android 9 reorganiza as classes baseadas em JUnit em três bibliotecas: android.test.base, android.test.runner e android.test.mock. Com essa mudança, você pode executar testes na versão do JUnit que funciona melhor com as dependências do seu projeto. Essa versão do JUnit pode ser diferente da que android.jar oferece.

Se quiser saber mais sobre como as classes baseadas em JUnit são organizadas nessas três bibliotecas e aprender a preparar o projeto do seu aplicativo para o desenvolvimento e execução de testes, leia Configurar o projeto para o Android Test.

Mudanças na compilação do conjunto de teste

O método addRequirements() na classe TestSuiteBuilder foi removido e a classe TestSuiteBuilder em si ficou obsoleta. O método addRequirements() exigia que os desenvolvedores fornecessem argumentos cujos tipos são APIs ocultas, o que tornava a API inválida.

Decodificador de UTF Java

UTF-8 é o conjunto de caracteres padrão no Android. Uma sequência de bytes UTF-8 pode ser decodificada por um construtor String, como String(byte[] bytes).

O decodificador de UTF-8 do Android 9 segue os padrões Unicode com mais firmeza do que as versões anteriores. As mudanças são:

  • A forma não mais curta de UTF-8, como <C0, AF>, é tratada como se tivesse sido formada incorretamente.
  • A forma substituta de UTF-8, como U+D800..U+DFFF, é tratada como se tivesse sido formada incorretamente.
  • A subparte máxima é substituída por um só U+FFFD. Por exemplo, na sequência de bytes "41 C0 AF 41 F4 80 80 41," as subpartes máximas são "C0," "AF" e "F4 80 80“. "F4 80 80" pode ser a subsequência inicial de "F4 80 80 80", mas "C0" não pode ser a subsequência inicial de qualquer sequência de unidades de código formada corretamente. Portanto, a saída deve ser "A\ufffd\ufffdA\ufffdA."
  • Para decodificar uma sequência UTF-8/CESU-8 modificada no Android 9, use o método DataInputStream.readUTF() ou o método JNI NewStringUTF().

Verificação de nome do host usando um certificado

RFC 2818 descreve dois métodos para fazer a correspondência de um nome de domínio com um certificado — usando os nomes disponíveis na extensão subjectAltName (SAN) ou na falta de uma extensão SAN, executando fallback para commonName (CN).

No entanto, o fallback para o CN foi tornado obsoleto na RFC 2818. Por esse motivo, o Android deixou de fazer o fallback para o CN. Para verificar um nome do host, o servidor deve apresentar um certificado com um SAN correspondente. Certificados que não contêm um SAN correspondente ao nome do host não são mais confiáveis.

Buscas de endereço de rede podem causar violações de rede

Buscas de endereços de rede que exigem resolução de nome podem envolver E/S de rede e, portanto, são consideradas operações de bloqueio. Operações de bloqueio no thread principal podem causar pausas ou travamentos.

A classe StrictMode é uma ferramenta de desenvolvimento que ajuda desenvolvedores a detectar problemas no código.

No Android 9 e em versões mais recentes, StrictMode detecta violações de rede causadas por buscas de endereço de rede que exigem resolução de nome.

Você não deve configurar seus aplicativos com StrictMode ativado. Caso contrário, os aplicativos podem apresentar novas exceções, como NetworkOnMainThreadException, ao usar os métodos detectNetwork() ou detectAll(), para ter uma política que detecte violações de rede.

A resolução de um endereço IP numérico não é considerada uma operação de bloqueio. Esse tipo de resolução funciona melhor como nas versões anteriores ao Android 9.

Tagging de soquete

Nas versões da plataforma anteriores ao Android 9, se um soquete é marcado usando o método setThreadStatsTag(), é desmarcado ao ser enviado a outro processo usando o associador IPC com um contêiner ParcelFileDescriptor.

A partir do Android 9, a tag do soquete é mantida quando ele é enviado a outro processo usando um associador IPC. Essa mudança pode afetar as estatísticas de tráfego de rede, por exemplo, quando se usa o método queryDetailsForUidTag().

Se quiser manter o comportamento das versões anteriores, em que o soquete é desmarcado quando é enviado a outro processo, chame untagSocket() antes de enviá-lo.

Quantidade informada de bytes disponíveis no soquete

O método available() retorna 0 quando é chamado após invocar o método shutdownInput().

Relatórios de recursos de rede mais detalhados para VPNs

No Android 8.1 (API de nível 28) e em versões mais antigas, a classe NetworkCapabilities só comunicava um conjunto limitado de informações de VPNs, como TRANSPORT_VPN, mas omitindo NET_CAPABILITY_NOT_VPN. Essa limitação dificultava o processo de determinar se usar uma VPN geraria cobranças ao usuário do aplicativo. Por exemplo, verificar NET_CAPABILITY_NOT_METERED não determinaria se as redes envolvidas são tarifadas ou não.

A partir do Android 9, quando uma VPN chama o método setUnderlyingNetworks(), o sistema Android mescla os transportes e os recursos de todas as redes envolvidas e retorna os recursos de rede reais da rede VPN como o resultado.

No Android 9 e em versões mais recentes, os aplicativos que já verificam NET_CAPABILITY_NOT_METERED recebem os recursos de rede da VPN e das redes envolvidas.

Arquivos na pasta xt_qtaguid não estão mais disponíveis para aplicativos

Do Android 9 em diante, os aplicativos não poderão ter acesso de leitura direto aos arquivos da pasta /proc/net/xt_qtaguid. O motivo disso é garantir a consistência com alguns dispositivos que não têm esses arquivos.

As APIs públicas que dependem desses arquivos, TrafficStats e NetworkStatsManager, continuam funcionando da forma planejada. Entretanto, as funções cutils que não contam com suporte, como a qtaguid_tagSocket(), podem não funcionar da forma esperada— ou simplesmente não funcionar — em dispositivos diferentes.

O requisito FLAG_ACTIVITY_NEW_TASK agora é aplicado

Com o Android 9, não é possível iniciar uma atividade a partir de um contexto de não atividade, a não ser que você passe o sinalizador de intent FLAG_ACTIVITY_NEW_TASK. Se você tentar iniciar uma atividade sem passar esse sinalizador, ela não será iniciada e o sistema adicionará uma mensagem no registro.

Observação: a exigência do sinalizador sempre foi o comportamento desejado e foi aplicada em versões anteriores ao Android 7.0 (API de nível 24). Um bug no Android 7.0 impedia a aplicação dessa exigência de sinalizador.

Mudanças na rotação da tela

Começando pelo Android 9, há mudanças importantes ao modo de rotação retrato. No Android 8.0 (API de nível 26), os usuários podiam alternar entre os modos de rotação rotação automática e retrato usando um bloco Quicksettings ou as configurações da tela. O modo retrato foi renomeado como rotação bloqueada e fica ativo quando a rotação automática está desativada. Não há mudanças no modo de rotação automática.

Quando o dispositivo estiver no modo de rotação bloqueada, os usuários poderão fixar a tela em qualquer rotação permitida pela Activity principal visível. Uma Activity não deve presumir que sempre será renderizada no modo retrato. Se a Activity principal puder ser renderizada em várias rotações no modo de rotação automática, as mesmas opções deverão estar disponíveis no modo de rotação bloqueada, com algumas exceções de acordo com a configuração screenOrientation da Activity (veja a tabela abaixo).

Atividades que solicitam uma orientação específica (por exemplo, screenOrientation=landscape) ignoram a preferência de bloqueio do usuário e comportam-se da mesma forma que no Android 8.0.

A preferência de orientação da tela pode ser definida no nível da Activity no Manifesto do Android ou programaticamente com setRequestedOrientation().

O modo de bloqueio de rotação passa a funcionar ao se definir a preferência de rotação do usuário que o WindowManager usa para lidar com a rotação da Activity. A preferência de rotação do usuário pode ser alterada nos casos abaixo. Note que há uma tendência a retornar à rotação natural do dispositivo, que normalmente é no formato retrato para dispositivos com dimensões de um celular:

  • Quando o usuário aceita uma sugestão de rotação, a preferência de rotação passa a ser essa sugestão.
  • Quando o usuário troca para um aplicativo que força o modo retrato (incluindo a tela de bloqueio ou o inicializador), a preferência de rotação é alterada para retrato.

A tabela a seguir resume o comportamento de rotação das orientações de tela mais comuns:

Orientação da tela Comportamento
unspecified, user Na rotação automática e no bloqueio de rotação, a Activity pode ser renderizada no modo retrato ou paisagem (e o inverso). Espere oferecer suporte para layouts no modo retrato e no modo paisagem.
userLandscape Na rotação automática e no bloqueio de rotação, a Activity pode ser renderizada no modo paisagem ou paisagem inversa. Espere oferecer suporte apenas para layouts no modo paisagem.
userPortrait Na rotação automática e no bloqueio de rotação, a Activity pode ser renderizada no modo retrato ou retrato inverso. Espere oferecer suporte apenas para layouts no modo retrato.
fullUser Na rotação automática e no bloqueio de rotação, a Activity pode ser renderizada no modo retrato ou paisagem (e o inverso). Espere oferecer suporte para layouts no modo retrato e no modo paisagem.

Os usuários do bloqueio de rotação terão a opção de bloquear no modo retrato inverso, frequentemente em 180º.
sensor, fullSensor, sensorPortrait, sensorLandscape A preferência do modo de bloqueio de rotação é ignorada e é tratada como se a rotação automática estivesse ativada. Use isso somente em circunstâncias excepcionais considerando a experiência do usuário com muito cuidado.

A suspensão de uso do cliente Apache HTTP afeta aplicativos com ClassLoader não padrão

Com o Android 6.0, removemos o suporte ao cliente Apache HTTP. Essa mudança não tem efeito na grande maioria dos aplicativos que não são voltados ao Android 9 ou a uma versão mais recente. No entanto, ela pode afetar determinados aplicativos que usam uma estrutura ClassLoader não padrão, mesmo que os aplicativos não sejam voltados ao Android 9 ou a uma versão mais recente.

O aplicativo pode ser afetado se usar um ClassLoader não padrão que delega ao ClassLoader do sistema explicitamente. Em vez disso, esses aplicativos devem delegar ao ClassLoader do aplicativo ao buscar classes em org.apache.http.*. Se delegarem ao ClassLoader do sistema, os aplicativos apresentarão um erro NoClassDefFoundError no Android 9 ou em uma versão mais recente, já que o ClassLoader do sistema não reconhece mais essas classes. Para evitar problemas semelhantes no futuro, em geral, os aplicativos devem carregar classes por meio do ClassLoader do aplicativo, e não acessar o ClassLoader do sistema diretamente.

Enumerar câmeras

Os aplicativos que operam em dispositivos Android 9 podem descobrir todas as câmeras disponíveis chamando getCameraIdList(). O aplicativo não deve presumir que o dispositivo só tenha uma câmera traseira ou uma frontal.

Por exemplo, se o aplicativo tem um botão para alternar entre as câmeras frontal e traseira, pode haver mais de uma câmera frontal ou traseira para escolher. Você deve acessar a lista de câmeras, analisar as características de cada uma e decidir que câmeras vai apresentar ao usuário.