Com novos recursos e funcionalidades, o Android 8.0 (nível 26 da API) inclui uma variedade de mudanças de comportamento do sistema e da API. Este documento destaca algumas das principais mudanças que você precisa entender e considerar nos seus apps.
A maioria dessas mudanças afeta todos os aplicativos, independentemente da versão do Android que eles segmentam. Porém, muitas alterações afetam somente a segmentação de aplicativos Android 8.0 Para maximizar a clareza, esse é dividida em duas seções: Mudanças para todos os apps e Alterações na segmentação de apps Android 8.0
Mudanças para todos os apps
Essas mudanças de comportamento se aplicam a
Background execution limits
Como uma das mudanças que o Android 8.0 (nível 26 da API) introduz nos melhorar a duração da bateria, quando seu aplicativo entrar no armazenado em cache de estado, sem estado componentes, o sistema libera todos os wake locks retidos pelo aplicativo.
Além disso, para melhorar o desempenho do dispositivo, o sistema limita determinadas por apps que não estão em execução em primeiro plano. Especificamente:
- Os aplicativos executados em segundo plano agora têm limites de liberdade possam acessar serviços em segundo plano.
- Os apps não podem usar os manifestos para se registrar na maioria das transmissões implícitas ou seja, transmissões que não são direcionadas especificamente para o app.
por padrão, essas restrições só se aplicam a aplicativos destinados ao Android O. No entanto, os usuários podem ativar essas restrições para qualquer app na tela Configurações, mesmo que o aplicativo não seja direcionado a O.
O Android 8.0 (API de nível 26) também inclui as seguintes mudanças em métodos específicos:
- O método
startService()
agora gera umaIllegalStateException
se um app direcionados ao Android 8.0 tentam usar esse método em uma situação em que não é permitido criar serviços de segundo plano. - O novo método
Context.startForegroundService()
inicia uma serviço em primeiro plano. O sistema permite que apps para chamarContext.startForegroundService()
mesmo quando o app estiver em segundo plano. No entanto, o app precisa chamar o métodostartForeground()
desse serviço em cinco segundos após a criação do serviço.
Para mais informações, consulte Limites de execução em segundo plano.
Limites da localização em segundo plano no Android
Para economizar bateria, a experiência do usuário e a integridade do sistema, aplicativos em segundo plano recebem atualizações de localização com menos frequência quando usados em um dispositivo com Android 8.0. Essa mudança de comportamento afeta todos os apps que recebem atualizações de localização, incluindo o Google Play Services.
Essas mudanças afetam as seguintes APIs:
- Fused Location Provider (FLP)
- Geofencing
- GNSS Measurements
- Location Manager
- Wi-Fi Manager
Para garantir que o aplicativo funcione como o esperado, faça o seguinte:
- Revise a lógica do app e verifique se você está usando a localização mais recente. APIs de terceiros.
- Testar se o app exibe o comportamento esperado para cada uso caso.
- Considere usar o Fusada Provedor de localização (FLP, na sigla em inglês) ou fronteira geográfica virtual para lidar com os casos de uso que dependem a localização atual do usuário.
Para mais informações sobre essas mudanças, consulte Localização em segundo plano Limites.
Atalhos de apps
O Android 8.0 (API de nível 26) inclui as seguintes mudanças nos atalhos de apps:
- O número de transmissão de
com.android.launcher.action.INSTALL_SHORTCUT
ainda mais afeta o aplicativo, porque agora ele é um ambiente privado, implícito transmissão. Em vez disso, crie um atalho usando orequestPinShortcut()
da classeShortcutManager
. - O
ACTION_CREATE_SHORTCUT
agora pode criar atalhos de apps que você gerencia usando oShortcutManager
. Essa intent também pode criar atalhos legados da tela de início que não interagem comShortcutManager
: Antes, essa intent só podia Criar apenas atalhos legados na tela de início. - Atalhos criados usando
requestPinShortcut()
e atalhos criados em uma atividade que manipula aACTION_CREATE_SHORTCUT
agora são atalhos de apps completos. Por isso, eles podem ser atualizados pelos apps usando os métodos emShortcutManager
. - Os atalhos legados mantêm a funcionalidade das versões anteriores do Android, mas precisam ser convertidas manualmente em atalhos de apps.
Para saber mais sobre as mudanças nos atalhos de apps, consulte a Fixar atalhos e Widgets.
Localidades e internacionalização
O Android 7.0 (API de nível 24) introduziu o conceito de poder
especificar uma localidade de categoria padrão, mas algumas APIs continuaram a usar o
genérico Locale.getDefault()
, sem argumentos, quando deveriam ter usado a localidade DISPLAY
de categoria padrão. No Android 8.0 (API de nível 26), a
os métodos a seguir agora usam Locale.getDefault(Category.DISPLAY)
.
em vez de Locale.getDefault()
:
Locale.getDisplayScript(Locale)
também
volta para Locale.getDefault()
quando o
Valor displayScript especificado para Locale
não está disponível.
Outras mudanças relacionadas a localidades e internacionalização são: da seguinte forma:
- Chamar
Currency.getDisplayName(null)
gera umaNullPointerException
, correspondendo ao comportamento documentado. - A análise do nome do fuso horário mudou. Antes,
Dispositivos Android usaram o valor do relógio do sistema amostrado na inicialização
tempo para armazenar em cache os nomes de fusos horários usados para analisar a data
vezes. Como resultado, a análise poderia ser afetada negativamente se o sistema
estava errado no momento da inicialização ou em casos mais raros.
Em casos comuns, a lógica de análise usa a ICU e a valor atual do relógio do sistema ao analisar nomes de fusos horários. Isso alteração fornece resultados mais corretos, que podem ser diferentes dos anteriores Versões do Android quando o app usa classes como
SimpleDateFormat
: - O Android 8.0 (nível 26 da API) atualiza a ICU para a versão 58.
Janelas de alerta
Se um app usa a SYSTEM_ALERT_WINDOW
permissão e usa um dos seguintes tipos de janela para tentar exibir
janelas de alerta sobre outros apps e janelas do sistema:
...essas janelas sempre aparecem abaixo das janelas que usam o
TYPE_APPLICATION_OVERLAY
janela
não é válido. Se um aplicativo for direcionado ao Android 8.0 (nível 26 da API), ele usará as
TYPE_APPLICATION_OVERLAY
para exibir janelas de alerta.
Para mais informações, consulte os Tipos de janela comuns para a seção de janelas de alerta nas alterações de comportamento de Aplicativos destinados ao Android 8.0.
Interação e navegação
Com o advento dos apps Android no ChromeOS e em outros formatos grandes, como tablets, estamos vendo um ressurgimento da navegação pelo teclado nos Apps Android. No Android 8.0 (API de nível 26), voltamos a lidar com o uso o teclado como um dispositivo de entrada de navegação, o que resulta em uma experiência previsível para navegação baseada em setas e guias.
Fizemos as seguintes alterações no foco do elemento comportamento:
-
Se você não definiu nenhuma cor do estado de foco para um Objeto
View
(em primeiro ou segundo plano) drawable), o framework define uma cor de destaque de foco padrão para oView
. O destaque de foco é um drawable de ondulação com base no tema da atividade.Se você não quiser que um objeto
View
use esse padrão destacar quando receber foco, defina oandroid:defaultFocusHighlightEnabled
parafalse
no arquivo XML de layout que contém oView
ou transmitafalse
parasetDefaultFocusHighlightEnabled()
na lógica da interface do seu app. - Para testar como a entrada do teclado afeta o foco no elemento da interface, ative o Desenho > Opção para desenvolvedores Mostrar limites de layout. No Android 8.0, essa opção exibe um "X" ícone sobre o elemento que tem atualmente foco.
Além disso, todos os elementos da barra de ferramentas no Android 8.0 são automaticamente clusters de navegação por teclado, o que facilita a navegação dos usuários dentro e fora de cada barra de ferramentas como uma inteira.
Para saber mais sobre como melhorar o suporte à navegação pelo teclado no seu aplicativo, leia a documentação de Suporte Guia de navegação pelo teclado.
Preenchimento automático de formulários Web
Agora que o preenchimento automático do Android
Framework oferece suporte integrado à funcionalidade de preenchimento automático, o
os seguintes métodos relacionados a objetos WebView
foram alterados
para apps instalados em dispositivos com o Android 8.0 (nível 26 da API):
WebSettings
-
- A
getSaveFormData()
agora retornafalse
. Antes, esse método retornavatrue
. - Ligando
Quantas pessoas recusaram:
setSaveFormData()
não tem mais efeito.
- A
WebViewDatabase
-
- Ligando
Quantas pessoas recusaram:
clearFormData()
não tem mais efeito. - A
Método
hasFormData()
agora retornafalse
. Antes, esse método retornavatrue
quando o formulário continha dados.
- Ligando
Quantas pessoas recusaram:
Acessibilidade
O Android 8.0 (API de nível 26) inclui as seguintes mudanças de acessibilidade:
-
O framework de acessibilidade agora converte todos os gestos de dois toques em
ACTION_CLICK
ações. Essa mudança permite que o TalkBack se comporte de forma mais parecida serviços de acessibilidade.Se os objetos
View
do seu app usam toque personalizado verifique se eles ainda funcionam com o TalkBack. Talvez você basta registrar o gerenciador de cliques que seuView
objetos usam. Se o TalkBack ainda não reconhecer os gestos realizados nessesView
objetos, substituirperformAccessibilityAction()
. - Os serviços de acessibilidade agora conhecem
ClickableSpan
de instâncias no objetosTextView
.
Para saber mais sobre como tornar seu app mais acessível, consulte Acessibilidade.
Redes e conectividade HTTP(S)
O Android 8.0 (API de nível 26) inclui as seguintes mudanças de comportamento para rede e conectividade HTTP(S):
- Solicitações OPTIONS sem corpo têm um
Content-Length: 0
cabeçalho. Anteriormente, elas não tinham cabeçalhoContent-Length
. - HttpURLConnection normaliza URLs que contêm caminhos vazios anexando
uma barra após o nome do host ou da autoridade com uma barra. Por exemplo, ela
converte
http://example.com
emhttp://example.com/
. - Um seletor de proxy personalizado definido por ProxySelector.setDefault(). segmenta apenas o endereço (esquema, host e porta) de um URL solicitado. Com isso, a seleção de proxy pode se basear apenas nesses valores. Um URL passado para um seletor de proxy personalizado não inclui o URL parâmetros de consulta ou fragmentos.
- OS URIs não podem conter rótulos vazios.
Antes, a plataforma oferecia uma solução alternativa para aceitar rótulos vazios em nomes de host, o que é um uso ilegal de URIs. Essa solução era para compatibilidade com versões libcore mais antigas. Desenvolvedores que usam a API incorretamente veria uma mensagem ADB: "URI example.com tem rótulos vazios em o nome do host. Isso está incorreto e não será aceito no futuro lançamentos". O Android 8.0 remove essa solução alternativa. o sistema retorna nulo para URIs malformados.
- Implementação de HttpsURLConnection do Android 8.0 não executa substituto de versão do protocolo TLS/SSL não seguro.
- A manipulação de conexões HTTP(S) de encapsulamento mudou da seguinte forma:
- Ao encapsular uma conexão HTTPS por conexão, o sistema coloca corretamente o número da porta (:443) na linha do host ao enviar essas informações para um servidor intermediário. Antes, a porta número só ocorreu na linha CONNECT.
- O sistema não envia mais o user agent e a autorização de proxy
cabeçalhos de uma solicitação encapsulada para o servidor proxy.
O sistema não envia mais um cabeçalho de autorização-proxy em um encapsulava Http(s)URLConnection ao proxy ao configurar a túnel do Cloud. Em vez disso, o sistema gera um cabeçalho proxy-autorização, e a envia para o proxy quando ele envia HTTP 407 em resposta à solicitação inicial.
Da mesma forma, o sistema não copia mais o cabeçalho user agent da solicitação encapsulada para a solicitação de proxy que configura túnel do Cloud. Em vez disso, a biblioteca gera um cabeçalho user agent para esse solicitação.
- O
send(java.net.DatagramPacket)
gera uma SocketException se o método connect() executado anteriormente falhou.- DatagramSocket.connect() define um pendingSocketException se houver um um erro interno. Antes do Android 8.0, uma função recv() subsequente chamada gerou uma SocketException, mesmo que uma chamada send() tivesse sido bem-sucedida. Para dar mais consistência, ambas as chamadas agora geram uma SocketException.
- InetAddress.isReachable() tenta ICMP antes de voltar para o eco TCP
protocolo.
- Alguns hosts que bloqueiam a porta 7 (eco TCP), como google.com, podem se tornam acessíveis se aceitarem o protocolo ICMP de eco.
- Para hosts realmente inacessíveis, essa alteração significa que o dobro da quantidade do tempo é gasto antes do retorno da chamada.
Bluetooth
O Android 8.0 (API de nível 26) faz as seguintes alterações no comprimento de
os dados que o ScanRecord.getBytes()
recupera:
- O método
getBytes()
não faz suposições o número de bytes recebidos. Portanto, os apps não devem depender de nenhuma número mínimo ou máximo de bytes retornados. Em vez disso, eles devem avaliar o comprimento da matriz resultante. - Dispositivos compatíveis com Bluetooth 5 podem retornar comprimentos de dados que excedam o no máximo 60 bytes.
- Se um dispositivo remoto não fornecer uma resposta de verificação, menos de 60 bytes também podem ser retornados.
Conectividade uniforme
O Android 8.0 (API de nível 26) traz várias melhorias nas configurações de Wi-Fi para facilitar a escolha a rede Wi-Fi que oferece a melhor experiência do usuário. Mudanças específicas incluem:
- Melhorias de estabilidade e confiabilidade.
- Uma IU de leitura mais intuitiva.
- Um só menu consolidado de preferências de Wi-Fi.
- Em dispositivos compatíveis, ativação automática do Wi-Fi quando uma rede salva de alta qualidade está por perto.
Segurança
O Android 8.0 inclui os seguintes recursos de segurança: muda:
- A plataforma não oferece mais suporte a SSLv3.
- Ao estabelecer uma conexão HTTPS com um servidor que
implementa a negociação de versão do protocolo TLS,
HttpsURLConnection
não tenta mais a solução alternativa de voltar para versões anteriores do protocolo TLS e tentar novamente. - O Android 8.0 (nível 26 da API) aplica uma chave de computação filtrar por todos os apps. A lista de chamadas do sistema permitidas é restrita exposto por meio do biônico. Embora existam várias outras chamadas do sistema fornecidas para compatibilidade com versões anteriores, não recomendamos o uso deles.
- Os objetos
WebView
do seu app agora são executados em multiprocesso modo O conteúdo da web é tratado em um processo separado e isolado que contém o processo do app para aumentar a segurança. -
Não é mais possível presumir que os APKs estão em diretórios com nomes terminados em
em -1 ou -2. Os apps devem usar
sourceDir
para acessar e não dependem diretamente do formato do diretório. - Para mais informações sobre melhorias de segurança relacionadas ao uso de bibliotecas, consulte Bibliotecas nativas.
Além disso, o Android 8.0 (API de nível 26) introduz as seguintes mudanças relacionadas à instalação apps desconhecidos de fontes desconhecidas:
- O valor da configuração legada
INSTALL_NON_MARKET_APPS
agora é sempre 1. Para determinar se uma fonte desconhecida pode instalar apps usando o instalador de pacote, use o valor de retorno docanRequestPackageInstalls()
: - Se você tentar alterar o valor
INSTALL_NON_MARKET_APPS
emsetSecureSetting()
eUnsupportedOperationException
é gerado. Para impedir que os usuários instalem apps desconhecidos usando esse recurso fontes, em vez disso, aplique oDISALLOW_INSTALL_UNKNOWN_SOURCES
usuário e a segunda é a restrição de recursos. -
Os perfis gerenciados criados em dispositivos com o Android 8.0 (nível 26 da API) têm a
DISALLOW_INSTALL_UNKNOWN_SOURCES
usuário restrição ativada. Para perfis gerenciados existentes em dispositivos que são atualizado para o Android 8.0, aDISALLOW_INSTALL_UNKNOWN_SOURCES
usuário a restrição será ativada automaticamente, a menos que o proprietário do perfil tenha desativou essa restrição (antes do upgrade) configurandoINSTALL_NON_MARKET_APPS
para 1.
Para mais detalhes sobre a instalação de apps desconhecidos, consulte a App desconhecido Permissões de instalação.
Para diretrizes adicionais sobre como tornar seu aplicativo mais seguro, consulte Segurança para desenvolvedores Android.
Privacidade
O Android 8.0 (API de nível 26) torna os seguintes controles de privacidade na plataforma.
- Agora, a plataforma gerencia identificadores de forma diferente.
-
Para aplicativos que foram instalados antes de um OTA para uma versão do
Android 8.0 (nível 26 da API)
(API de nível 26), o valor do
ANDROID_ID
continua igual a menos que desinstalado e reinstalado após o OTA. Para preservar os valores em desinstalações após o OTA, os desenvolvedores podem associar os valores antigos e novos usando Backup de chave-valor. - Para aplicativos instalados em um dispositivo com o Android 8.0, o valor de
ANDROID_ID
agora está no escopo por chave de assinatura do app e por usuário. O valor deANDROID_ID
é único para cada combinação de chave de assinatura do app, usuário e dispositivo. Por isso, apps com chaves de assinatura diferentes são executados no mesmo dispositivo não vão mais ver o mesmo ID do Android (mesmo para o mesmo usuário). - O valor de
ANDROID_ID
não se altera na desinstalação ou reinstalação do pacote, contanto que o é a mesma (e o aplicativo não foi instalado antes de um OTA para um do Android 8.0). - O valor de
ANDROID_ID
não muda, mesmo que uma atualização do sistema faça com que a chave de assinatura do pacote mude. - Em dispositivos que enviam com o Google Play Services e o ID de publicidade,
é preciso usar
ID de publicidade. Um sistema padrão simples para gerar receita com apps,
O ID de publicidade é único, reajustável pelo usuário e usado para publicidade. Ela é fornecida
pelo Google Play Services.
Outros fabricantes de dispositivos devem continuar para fornecer
ANDROID_ID
.
-
Para aplicativos que foram instalados antes de um OTA para uma versão do
Android 8.0 (nível 26 da API)
(API de nível 26), o valor do
- Consultar a propriedade do sistema
net.hostname
produz um valor nulo resultado.
Registro de exceções não capturadas
Se um app instalar um Thread.UncaughtExceptionHandler
que
não chamar o Thread.UncaughtExceptionHandler
padrão,
o sistema faz
não encerrar o app quando ocorrer uma exceção não capturada. A partir de
No Android 8.0 (API de nível 26), o sistema registra o stack trace da exceção
situação; em versões anteriores da plataforma, o sistema não teria
registrou o stack trace da exceção.
Recomendamos que o Thread.UncaughtExceptionHandler
personalizado
as implementações sempre chamam
o gerenciador padrão, os apps que seguem essa recomendação não são afetados pelas
a mudança no Android 8.0.
Mudança de assinatura findViewById()
Todas as instâncias do método findViewById()
agora retornam
<T extends View> T
, em vez de View
. Essa mudança
tem as seguintes implicações:
- Isso pode fazer com que o código tenha um tipo de retorno ambíguo,
Por exemplo, se houver
someMethod(View)
esomeMethod(TextView)
, que usa o resultado de uma chamada parafindViewById()
- Ao usar a linguagem de origem Java 8, isso exige uma transmissão explícita para
View
quando o tipo de retorno não tem restrições (por exemplo,assertNotNull(findViewById(...)).someViewMethod())
. - Substituições de métodos
findViewById()
não finais (para exemplo,Activity.findViewById()
) vão precisar do retorno tipo atualizado.
Mudança de estado de uso do provedor de contatos
Nas versões anteriores do Android, o componente do Provedor de contatos
permite que os desenvolvedores recebam dados de uso de cada contato. Esses dados de uso
expõe informações para cada endereço de e-mail e cada número de telefone associado
com um contato, incluindo o número de vezes que ele foi contatado
e a última vez em que o contato foi contatado. Apps que solicitam a
READ_CONTACTS
permissão podem ler esses dados.
Os apps ainda poderão ler esses dados se solicitarem
READ_CONTACTS
permissão. No Android 8.0 (nível 26 da API) e versões mais recentes, as consultas para dados de uso são retornadas
aproximações em vez de valores exatos. O sistema Android mantém a
valores exatos internamente, de modo que essa alteração não afete
API de preenchimento automático.
Essa mudança de comportamento afeta os seguintes parâmetros de consulta:
Gerenciamento de coleta
AbstractCollection.removeAll()
e AbstractCollection.retainAll()
agora gera uma NullPointerException
. antes,
NullPointerException
não foi gerada quando a coleta foi
vazio. Essa mudança deixa o comportamento mais coerente com a documentação.
Android empresarial
O Android 8.0 (API de nível 26) altera a comportamento de algumas APIs e recursos para apps empresariais, incluindo as e controladores de política (DPCs). As mudanças incluem:
- Novos comportamentos para ajudar os aplicativos a dar suporte a perfis de trabalho em dispositivos totalmente gerenciados.
- Mudanças no tratamento de atualizações do sistema, verificação de apps e autenticação no aumentar a integridade do dispositivo e do sistema.
- Melhorias na experiência do usuário para provisionamento, notificações, Tela "Recentes" e VPN sempre ativada.
Para conferir todas as mudanças empresariais no Android 8.0 (nível 26 da API) e saber como elas podem afetar seu aplicativo, leia Android nas empresas.
Apps destinados ao Android 8.0
Essas mudanças de comportamento se aplicam exclusivamente a apps direcionados
Android 8.0 (nível 26 da API) ou mais recente Apps que podem ser compilados com o Android 8.0,
ou definir targetSdkVersion
como Android 8.0 ou versão posterior precisa modificar
para oferecer suporte a esses comportamentos de forma adequada, quando aplicável.
Janelas de alerta
Apps que usam SYSTEM_ALERT_WINDOW
a permissão não pode mais usar os seguintes tipos de janela para exibir alertas
acima de outros apps e janelas do sistema:
Em vez disso, os apps precisam usar um novo tipo de janela chamado
TYPE_APPLICATION_OVERLAY
:
Ao usar o botão
TYPE_APPLICATION_OVERLAY
janela
para exibir janelas de alerta para seu app, mantenha as seguintes características
do novo tipo de janela em mente:
- As janelas de alerta de um app sempre aparecem embaixo de janelas críticas do sistema, como como a barra de status e os IMEs.
- O sistema pode mover ou redimensionar janelas que usam o
TYPE_APPLICATION_OVERLAY
tipo de janela para melhorar a apresentação na tela. - Ao abrir a aba de notificações, os usuários podem acessar as configurações para bloquear uma
aplicativo de exibir janelas de alerta mostradas usando o
TYPE_APPLICATION_OVERLAY
tipo de janela.
Notificações de alteração de conteúdo
O Android 8.0 (API de nível 26) muda a forma
ContentResolver.notifyChange()
e registerContentObserver(Uri, boolean, ContentObserver)
se comportam em apps destinados ao Android 8.0.
Essas APIs agora exigem que um objeto ContentProvider
válido
é definido para a autoridade em todos os URIs. Definir um ContentProvider
válido com permissões relevantes vai
ajudam a defender seu aplicativo contra alterações de conteúdo por aplicativos maliciosos e evitam que você
do vazamento de dados potencialmente particulares para aplicativos maliciosos.
Foco de visualização
Os objetos View
clicáveis agora também são focalizáveis por
padrão. Se você quiser que um objeto View
seja clicável, mas não
focalizável, defina
Atributo android:focusable
para false
no layout
Arquivo XML que contém o View
ou transmita false
como setFocusable()
na interface do app
lógica.
Correspondência de user agent na detecção do navegador
O Android 8.0 (API de nível 26) e versões mais recentes incluem a
string do identificador de build OPR
. Algumas correspondências de padrões podem
fazer com que a lógica de detecção do navegador identifique incorretamente um navegador que não seja Opera como o Opera.
Um exemplo dessa correspondência de padrão pode ser:
if(p.match(/OPR/)){k="Opera";c=p.match(/OPR\/(\d+.\d+)/);n=new Ext.Version(c[1])}
Para evitar problemas decorrentes dessa identificação incorreta, use uma string diferente
OPR
como uma correspondência de padrão para o navegador Opera.
Segurança
As seguintes mudanças afetam a segurança no Android 8.0 (nível 26 da API):
- Se a configuração de segurança de rede do seu app
o que
do suporte ao tráfego de texto não criptografado,
Os objetos
WebView
não podem acessar sites por HTTP. Cada O objetoWebView
precisa usar HTTPS. - A configuração do sistema Permitir fontes desconhecidas foi removida. na a permissão Instalar apps desconhecidos gerencia instalações de apps desconhecidos de fontes desconhecidas. Para saber mais sobre essa nova permissão, consulte a App desconhecido Permissões de instalação.
Para diretrizes adicionais sobre como tornar seu aplicativo mais seguro, consulte Segurança para desenvolvedores Android.
Detectabilidade e acesso a contas
No Android 8.0 (nível 26 da API), os apps não podem mais ter acesso
a contas de usuário, a menos que o autenticador seja proprietário das contas ou
usuário concede esse acesso. A
Permissão para GET_ACCOUNTS
não é mais suficiente. Para receber acesso a uma conta, os apps devem
use AccountManager.newChooseAccountIntent()
ou uma configuração de autenticação
. Depois de ter acesso às contas, um app pode chamar
AccountManager.getAccounts()
para acessá-las.
O Android 8.0 foi descontinuado
LOGIN_ACCOUNTS_CHANGED_ACTION
: Aplicativos
deve usar
addOnAccountsUpdatedListener()
para receber atualizações sobre as contas durante o tempo de execução.
Para informações sobre novas APIs e métodos adicionados para acesso à conta e detecção do dispositivo, consulte Acesso à conta e facilidade de descoberta na seção "Novas APIs" deste documento.
Privacidade
As mudanças abaixo afetam a privacidade no Android 8.0 (nível 26 da API).
-
As propriedades do sistema
net.dns1
,net.dns2
,net.dns3
enet.dns4
não estão mais disponível, uma mudança que melhora a privacidade na plataforma. -
Para obter informações de rede, como servidores DNS, aplicativos com
ACCESS_NETWORK_STATE
permissão podem registrar umNetworkRequest
ou objetoNetworkCallback
. Essas classes estão disponíveis no Android 5.0 (API de nível 21) e em versões posteriores. -
Build.SERIAL está obsoleta.
Os apps que precisam saber o número de série do hardware devem
use o novo método
Build.getSerial()
, que requer oREAD_PHONE_STATE
permissão. -
A API
LauncherApps
não permite mais o perfil de trabalho para acessar informações sobre o perfil principal. Quando um usuário está em um trabalho perfil, a APILauncherApps
se comporta como se nenhum app estejam instalados em outros perfis dentro do mesmo grupo de perfis. Como antes, tentativas de acessar perfis não relacionados causam SecurityExceptions.
Permissões
Antes do Android 8.0 (nível 26 da API), se um app solicitava uma permissão durante a execução e a permissão foi concedida, o sistema também concedeu ao app as outras permissões que pertenciam ao mesmo grupo de permissões e que foram registrados no manifesto.
Para aplicativos destinados ao Android 8.0, esse comportamento foi corrigidas. O aplicativo recebe apenas as permissões que explicitamente solicitado. No entanto, depois que o usuário concede uma permissão ao aplicativo, todos solicitações subsequentes para permissões nesse grupo de permissões são concedidas automaticamente.
Por exemplo, suponha que um aplicativo liste READ_EXTERNAL_STORAGE
e
WRITE_EXTERNAL_STORAGE
no manifesto.
O app solicita READ_EXTERNAL_STORAGE
e
que o usuário concede. Se o aplicativo for direcionado ao nível de API 25 ou inferior, o sistema também
concede WRITE_EXTERNAL_STORAGE
ao mesmo
momento, porque pertence ao mesmo grupo de permissões STORAGE
e também é
registrados no manifesto. Se o aplicativo for direcionado ao Android 8.0 (nível 26 da API), o sistema concederá
somente READ_EXTERNAL_STORAGE
naquele momento;
No entanto, se o app solicitar WRITE_EXTERNAL_STORAGE
depois, o sistema imediatamente
concede esse privilégio sem notificar o usuário.
Mídia
- O framework pode realizar
redução automática de áudio
sozinho. Nesse caso, quando outro aplicativo solicita o foco com
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
, o aplicativo com foco reduz o volume, mas geralmente não recebe umaonAudioFocusChange()
de retorno de chamada e não vai e perder a seleção de áudio. Novas APIs estão disponíveis para substituir esse comportamento por aplicativos que precisam pausar em vez de diminuir. - Quando o usuário atende a uma chamada, os streams de mídia ativos são silenciados durante o a chamada.
- Todas as APIs relacionadas a áudio precisam usar
AudioAttributes
. em vez de tipos de stream de áudio para descrever o caso de uso de reprodução de áudio. Continue a usar tipos de stream de áudio somente para controles de volume. Outros usos dos tipos de stream ainda funcionam Por exemplo, o argumentostreamType
para a solicitação construtorAudioTrack
), mas o sistema registra isso como um erro. - Ao usar um
AudioTrack
, se o aplicativo solicitar um buffer de áudio grande o suficiente, o o framework tentará usar a saída do buffer profundo se ela estiver disponível. - No Android 8.0 (API de nível 26), o processamento de eventos do botão de mídia é diferente:
- Como gerenciar os botões de mídia em uma atividade de interface não mudou: as atividades em primeiro plano ainda têm prioridade no processamento. eventos do botão de mídia.
- Se a atividade em primeiro plano não processar o evento do botão de mídia, o sistema vai rotear o evento ao app que reproduziu áudio localmente mais recentemente. O status ativo, as flags e a reprodução de uma sessão de mídia não são considerados ao determinar qual app recebe mídia eventos do botão.
- Se a sessão de mídia do app tiver sido lançada,
o sistema envia o evento do botão de mídia para o
MediaButtonReceiver
, se houver. - Para todos os demais casos de uso, o sistema descarta o evento de botão de mídia.
Bibliotecas nativas
Em apps destinados ao Android 8.0 (nível 26 da API), as bibliotecas nativas não carregam mais se contiverem algum segmento de carregamento que possa ser gravado e executável. Alguns apps podem parar de funcionar devido a essa mudança se tiverem bibliotecas nativas com segmentos de carregamento incorretos. Esta é uma medida de aumento de proteção.
Para obter mais informações, consulte Segmentos graváveis e executáveis.
As mudanças no vinculador são ligadas ao nível da API com que o aplicativo visa a trabalhar. Se houver é uma mudança do vinculador nível desejado da API, o app não vai conseguir carregar a biblioteca. Se você segmenta um nível de API inferior ao nível da API em que ocorre a mudança do vinculador o logcat exibe um aviso.
Gerenciamento de coleta
No Android 8.0 (nível 26 da API),
Collections.sort()
foi implementado em
parte superior de List.sort()
. O inverso
era verdadeiro no Android 7.x (API de níveis 24 e 25):
A implementação padrão de List.sort()
chamado Collections.sort()
.
Essa mudança permite que o app Collections.sort()
para aproveitar os List.sort()
otimizados
implementações, mas tem as seguintes restrições:
Implementações de
List.sort()
não pode chamarCollections.sort()
, porque isso resultaria em um estouro de pilha devido à recursão infinita. Em vez disso, se você quiser que o comportamento padrão na implementação deList
, evite substituirsort()
.Se uma classe mãe implementar
sort()
incorretamente, ela será geralmente pode substituirList.sort()
com uma implementação criada com baseList.toArray()
,Arrays.sort()
eListIterator.set()
. Exemplo:@Override public void sort(Comparator<? super E> c) { Object[] elements = toArray(); Arrays.sort(elements, c); ListIterator<E> iterator = (ListIterator<Object>) listIterator(); for (Object element : elements) { iterator.next(); iterator.set((E) element); } }
Na maioria dos casos, também é possível substituir
List.sort()
com um que delega para diferentes e implementações dependendo do nível da API. Exemplo:@Override public void sort(Comparator<? super E> comparator) { if (Build.VERSION.SDK_INT <= 25) { Collections.sort(this); } else { super.sort(comparator); } }
Se você estiver fazendo a segunda opção apenas porque quer ter um
sort()
disponível em todos os níveis de API, dê um nome exclusivo a ela comosortCompat()
, em vez de substituirsort()
:-
Collections.sort()
agora conta como uma modificação estrutural Liste implementações que chamamsort()
. Por exemplo, nas versões plataforma anterior ao Android 8.0 (API de nível 26), iterando umArrayList
e chamarsort()
nele no meio da iteração geraria umaConcurrentModificationException
. se a classificação foi feita chameList.sort()
.Collections.sort()
não gerou uma exceção.Essa mudança deixa o comportamento da plataforma mais consistente: abordagem agora resulta em uma
ConcurrentModificationException
.
Comportamento de carregamento de classe
O Android 8.0 (API de nível 26) faz verificações para garantir que os carregadores de classe não
e quebrar as suposições do ambiente de execução ao carregar novas classes. Essas verificações são
executada se a classe é referenciada em Java (do
forName()
).
Bytecode Dalvik, ou JNI. A plataforma não intercepta chamadas diretas do Java para o
loadClass()
, nem verifica
os resultados dessas chamadas. Esse comportamento não deve afetar o funcionamento de pessoas
carregadores de classe.
A plataforma verifica se o descritor da classe retornado pelo carregador de classes
corresponde ao descritor esperado. Se o descritor retornado não for correspondente,
a plataforma gera um erro NoClassDefFoundError
e armazena em
para a exceção de uma mensagem
detalhada indicando a discrepância.
A plataforma também analisa se os descritores das classes solicitadas são válidos. Isso
a verificação captura chamadas JNI que carregam indiretamente classes como GetFieldID()
,
passando descritores inválidos para essas classes. Por exemplo, um campo com assinatura
java/lang/String
não foi encontrado porque essa assinatura é inválida.
ele precisa ser Ljava/lang/String;
.
Isso é diferente de uma chamada JNI para FindClass()
em que java/lang/String
é um nome totalmente qualificado válido.
O Android 8.0 (API de nível 26) não oferece suporte a vários carregadores de classes que tentam definir classes.
usando o mesmo objeto DexFile. Uma tentativa de fazer isso faz com que o ambiente de execução do Android gere uma
InternalError
com a mensagem "Tentativa de registrar o arquivo dex <filename>
com vários carregadores de classe".
A API DexFile foi descontinuada. Recomendamos o uso
um dos carregadores de classe da plataforma, incluindo PathClassLoader
ou
BaseDexClassLoader
.
Observação: você pode criar vários carregadores de classe que referenciam
mesmo contêiner de arquivos APK ou JAR do sistema de arquivos. Fazer isso normalmente não
causar sobrecarga de memória: se os arquivos DEX no contêiner forem armazenados em vez de
compactado, a plataforma poderá executar uma operação mmap
neles em vez de
extraí-los diretamente. No entanto, se a plataforma precisar extrair o arquivo DEX do contêiner,
referenciar um arquivo DEX dessa forma pode consumir muita memória.
No Android, todos os carregadores de classe são considerados passíveis de paralelismo. Quando várias linhas de execução competem para carregar a mesma classe com a mesma classe carregador, o primeiro encadeamento que concluir a operação vence, e o resultado é usado para as outras linhas. Esse comportamento ocorre independentemente de o carregador de classe retornou a mesma classe, retornou uma classe diferente ou acionou uma exceção. A plataforma ignora essas exceções silenciosamente.
Atenção : nas versões da plataforma anteriores ao Android 8.0 (API de nível 26), quebrar essas premissas pode levar à definição dos mesmos várias vezes, corrupção de heap devido à confusão de classes, e outros efeitos indesejáveis.