Mudanças do Android 6.0

Junto com novos recursos e funcionalidades, o Android 6.0 (API de nível 23) inclui uma série de mudanças de comportamento do sistema e da API. Este documento destaca algumas das alterações principais que você deve entender e levar em consideração nos aplicativos.

Caso você já tenha um aplicativo para Android publicado, saiba que ele pode ser afetado pelas mudanças da plataforma.

Permissões em tempo de execução

Esta versão introduz um novo modelo de permissões em que os usuários podem gerenciar diretamente as permissões do aplicativo em tempo de execução. Este modelo fornece aos usuários uma visibilidade aprimorada e controle sobre permissões, enquanto agiliza os processos de atualização automática e instalação para os desenvolvedores de aplicativos. Os usuários podem conceder ou revogar as permissões individualmente para os aplicativos instalados.

Nos aplicativos voltados para o Android 6.0 (API de nível 23) ou posterior, não deixe de verificar e solicitar permissões em tempo de execução. Para determinar se o aplicativo recebeu uma permissão, chame o novo método checkSelfPermission(). Para solicitar uma permissão, chame o novo método requestPermissions(). Mesmo que o aplicativo não seja voltado ao Android 6.0 (nível da API 23), ele deverá ser testado com o novo modelo de permissões.

Para obter mais detalhes sobre como compatibilizar o novo modelo de permissões no aplicativo, consulte Como trabalhar com permissões do sistema. Para obter dicas sobre como avaliar o impacto no aplicativo, consulte Práticas recomendadas para permissões.

Soneca e App em espera

Esta versão introduz novas otimizações de economia de energia para dispositivos e aplicativos ociosos. Esses recursos afetam todos os aplicativos, portanto, não deixe de testar os aplicativos nesses novos modos.

  • Soneca: Se um usuário desconecta um dispositivo e deixa-o parado com a tela desativada por um período, ele entra no modo de Soneca para tentar manter o sistema em estado de suspensão. Neste modo, os dispositivos retomam as operações normais periodicamente por breves períodos para que a sincronização dos aplicativos possa ocorrer e para que o sistema possa realizar eventuais operações pendentes.
  • App em espera: O App em espera permite que o sistema determine se um aplicativo está ocioso quando o usuário não o está usando ativamente. O sistema determina isso quando o usuário fica sem tocar no aplicativo por determinado período. Se o dispositivo está desconectado, o sistema desabilita o acesso à rede e suspende as sincronizações e as tarefas do aplicativo considerado ocioso.

Para saber mais sobre essas mudanças de economia de energia, consulte Otimização para soneca e App em espera.

Remoção do cliente Apache HTTP

A versão Android 6.0 remove a compatibilidade com cliente Apache HTTP. Se o aplicativo estiver usando este cliente e for voltado para o Android 2.3 (API de nível 9) ou mais recente, use a classe HttpURLConnection. Essa API é mais eficiente, já que reduz o uso de rede por meio de compressão transparente e armazenamento de respostas em cache, além de minimizar o consumo de energia. Para continuar usando as APIs do Apache HTTP, declare a dependência de tempo de compilação no arquivo build.gradle:

android {
    useLibrary 'org.apache.http.legacy'
}

BoringSSL

O Android está mudando da biblioteca OpenSSL para a BoringSSL. Caso esteja usando o Android NDK no aplicativo, não vincule-o a bibliotecas criptográficas que não façam parte da NDK API, como libcrypto.so e libssl.so. Estas bibliotecas não são APIs públicas e podem ser modificadas ou apresentar erros nas diversas versões e dispositivos sem aviso prévio. Além disso, você pode se expor a vulnerabilidades de segurança. Em vez disso, modifique o código nativo para chamar as APIs de criptografia Java pelo JNI ou para vincular estaticamente a uma biblioteca criptográfica de sua escolha.

Acesso ao identificador de hardware

Para oferecer aos usuários uma maior proteção dos dados, a partir desta versão, o Android remove o acesso programático ao identificador de hardware local do dispositivo para aplicativos que usam as APIs Wi-Fi e Bluetooth. Os métodos WifiInfo.getMacAddress() e BluetoothAdapter.getAddress() agora retornam um valor constante de 02:00:00:00:00:00.

Para acessar os identificadores de hardware de dispositivos externos próximos via busca de Bluetooth e Wi-Fi, seu aplicativo agora precisa ter as permissões ACCESS_FINE_LOCATION ou ACCESS_COARSE_LOCATION:

Observação: Quando um dispositivo com Android 6.0 (API de nível 23) inicia uma busca de Wi-Fi ou Bluetooth em segundo plano, a operação fica visível para dispositivos externos, como se tivesse sido originada em um endereço MAC aleatório.

Notificações

Esta versão remove o método Notification.setLatestEventInfo(). Em vez disso, use a classe Notification.Builder para construir notificações. Para atualizar repetidamente uma notificação, reutilize a instância Notification.Builder. Chame o método build() para obter instâncias de Notification atualizadas.

O comando adb shell dumpsys notification não apresenta mais o texto da notificação. Em vez disso, use o comando adb shell dumpsys notification --noredact para apresentar o texto em um objeto de notificação.

Mudanças no AudioManager

Ajustar o volume diretamente ou desativar o áudio de transmissões específicas por meio da classe AudioManager não são mais recursos disponíveis. O método setStreamSolo() está obsoleto, por isso, você deve chamar o método requestAudioFocus(). De forma semelhante, o método setStreamMute() está obsoleto. Por isso, chame o método adjustStreamVolume() e passe o valor da direção ADJUST_MUTE ou ADJUST_UNMUTE.

Seleção de texto

Quando os usuários selecionam o texto no aplicativo, agora é possível exibir ações de seleção de texto como Recortar, Copiar e Colar na barra de ferramentas flutuante. A implementação da interação do usuário é semelhante ao processo da barra de ação contextual, como descrito em Ativação do modo de ação contextual para visualizações individuais.

Para implementar uma barra de ferramentas flutuante para seleção de texto, faça as seguintes alterações nos aplicativos existentes:

  1. No objeto View ou Activity, altere as chamadas ActionMode de startActionMode(Callback) para startActionMode(Callback, ActionMode.TYPE_FLOATING).
  2. Pegue a implementação existente de ActionMode.Callback e faça-a estender ActionMode.Callback2.
  3. Substitua o método onGetContentRect() para fornecer as coordenadas do conteúdo do objeto Rect (como um retângulo de seleção de texto) na visualização.
  4. Se a posição do retângulo não for mais válida, e for o único elemento a ser invalidado, chame o método invalidateContentRect().

Caso esteja usando a Android Support Library revisão 22.2, saiba que as barras de ferramentas flutuantes não têm compatibilidade com versões anteriores e que o appcompat tem controle sobre os objetos ActionMode por padrão. Isso evita que barras de ferramentas flutuantes sejam exibidas. Para ativar a compatibilidade com ActionMode em uma AppCompatActivity, chame getDelegate() e, em seguida, chame setHandleNativeActionModesEnabled() no objeto AppCompatDelegate retornado e defina o parâmetro de entrada como false. Esta chamada retorna o controle dos objetos ActionMode à estrutura. Em dispositivos com Android 6.0 (API de nível 23), a estrutura de trabalho pode suportar os modos de ActionBar ou de barra de ferramentas flutuante, enquanto que, para dispositivos com Android 5.1 (API de nível 22) ou anterior, somente os modos de ActionBar são compatíveis.

Mudanças nos favoritos de navegadores

Esta versão remove a compatibilidade com favoritos globais. Os métodos android.provider.Browser.getAllBookmarks() e android.provider.Browser.saveBookmark() foram removidos. Da mesma forma, as permissões READ_HISTORY_BOOKMARKS e WRITE_HISTORY_BOOKMARKS foram removidas. Se o aplicativo for voltado ao Android 6.0 (API de nível 23) ou posterior, não acesse as marcações do provedor global nem use as permissões de adição aos favoritos. Em vez disso, o aplicativo deve armazenar internamente os favoritos.

Mudanças no Android Keystore

Com esta versão, o provedor Android Keystore não oferece mais compatibilidade com aDSA. Ainda há compatibilidade com ECDSA.

As chaves que não requerem criptografia quando não usadas não precisam ser excluídas quando a tela de bloqueio protegida for desativada ou redefinida (por exemplo, pelo usuário ou por um administrador do dispositivo). As chaves que requerem criptografia quando não usadas serão excluídas durante esses eventos.

Mudanças de rede e Wi-Fi

Esta versão introduz as alterações de comportamento a seguir nas APIs de rede e Wi-Fi.

  • Os aplicativos agora poderão alterar o estado dos objetos WifiConfiguration somente se você os tiver criado. Você não tem permissão para modificar nem excluir objetos WifiConfiguration criados pelo usuário ou por outros aplicativos.
  • No passado, se um aplicativo forçasse o dispositivo a se conectar a uma rede Wi-Fi específica usando enableNetwork() com a configuração disableAllOthers=true, o dispositivo se desconectava de outras redes, como a de dados móveis. Nesta versão, o dispositivo não interrompe mais a conexão com outras redes. Se a targetSdkVersion do aplicativo for “20” ou anterior, ele será fixado à rede Wi-Fi selecionada. Se a targetSdkVersion do aplicativo for “21” ou posterior, use as Multinetowrk APIs (como openConnection(), bindSocket() e o novo método bindProcessToNetwork()) para garantir que o tráfego de rede seja enviado para a rede selecionada.

Mudanças no serviço de câmera

Nesta versão, o modelo para acessar recursos compartilhados no serviço da câmera foi alterado do antigo modelo "primeiro a chegar, primeiro a ser atendido" para um modelo de acesso onde os processos de alta prioridade são favorecidos. As mudanças no comportamento do serviço incluem:

  • Acesso aos recursos do subsistema da câmera, incluindo abertura e configuração de um dispositivo de câmera, concedido com base na prioridade do processo do aplicativo do cliente. Processos de aplicativos com atividades visíveis ao usuário ou de primeiro plano são geralmente de alta prioridade, tornando a aquisição e o uso de recursos da câmera mais dependentes.
  • Os clientes de câmera ativa para aplicativos de menor prioridade podem ser "despejados" quando um aplicativo de alta prioridade tenta usar a câmera. Na Camera API obsoleta, isso resulta em onError() sendo chamado para o cliente despejado. Na Camera2 API, isso resulta em onDisconnected() sendo chamado para o cliente despejado.
  • Em dispositivos com hardware de câmera adequado, processos de aplicativo separados podem abrir e usar os dispositivos de câmera de forma simultânea e independente. No entanto, casos de uso de vários processos, em que o acesso simultâneo causa uma degradação significativa de desempenho ou recursos de qualquer um dos dispositivos de câmera abertos, agora são detectados e proibidos pelo serviço da câmera. Esta alteração pode resultar em "despejos" para clientes de menor prioridade quando nenhum aplicativo está tentando acessar o mesmo dispositivo de câmera diretamente.
  • Alterar o usuário atual faz com que os clientes da câmera ativa em aplicativos pertencentes à conta do usuário anterior sejam despejados. O acesso à câmera é limitado a perfis de usuário de posse do usuário atual do dispositivo. Na prática, isso significa que uma conta de "convidado", por exemplo, não poderá deixar processos que usam o subsistema da câmera em execução quando o usuário alternar para uma conta diferente.

Tempo de execução

O tempo de execução ART agora implementa adequadamente as regras de acesso para o método newInstance(). Essa mudança resolve o problema de versões anteriores, em que o Dalvik verificava as regras de acesso de forma incorreta. Se o aplicativo usa o método newInstance() e você quer substituir as verificações de acesso, chame o método setAccessible() com o parâmetro de entrada definido como true. Se o aplicativo usar a biblioteca v7 appcompat ou a biblioteca v7 recyclerview, atualize-o para usar as versões mais recentes dessas bibliotecas. Caso contrário, confira se as classes personalizadas referenciadas do XML estão atualizadas para que os construtores de classe possam ser acessados.

Esta versão atualiza o comportamento do vinculador dinâmico. O vinculador dinâmico agora entende a diferença entre um soname da biblioteca e o seu caminho (erro público 6670), e a pesquisa por soname agora está implementada. Os aplicativos que funcionavam anteriormente e têm entradas DT_NEEDED inválidas (geralmente caminhos absolutos no sistema de arquivos da máquina de programação) podem falhar ao serem carregados.

O sinalizador dlopen(3) RTLD_LOCAL agora está corretamente implementado. Observe que RTLD_LOCAL é o padrão. Portanto, chamadas de dlopen(3) que não usem RTLD_LOCAL explicitamente serão afetadas (a não ser que o aplicativo tenha usado RTLD_GLOBAL explicitamente). Com RTLD_LOCAL, os símbolos não serão disponibilizados para bibliotecas carregadas por chamadas posteriores a dlopen(3) (ao contrário de serem referenciados por entradas DT_NEEDED).

Em versões anteriores do Android, se o aplicativo pedia que o sistema carregasse uma biblioteca compartilhada com realocações de texto, o sistema exibia um aviso, mas a biblioteca podia ser carregada. A partir desta versão, o sistema rejeita a biblioteca se o aplicativo é direcionado à versão 23 ou posterior do SDK. Para ajudar a detectar uma biblioteca cujo carregamento falhou, o aplicativo deve registrar a falha dlopen(3) e incluir o texto de descrição que a chamada a dlerror(3) retornar. Para saber mais sobre realocações de texto, consulte este guia.

Validação de APK

A plataforma agora realiza validações mais estritas de APKs. Considera-se um APK corrompido quando um arquivo é declarado no manifesto, mas não está presente no próprio APK. Deve-se reatribuir o APK se alguma parte do conteúdo for removida.

Conexão USB

Conexões de dispositivo na porta USB são agora definidas, por padrão, para o modo "somente carga". Para acessar o dispositivo e seu conteúdo por uma conexão USB, os usuários devem conceder explicitamente a permissão para esse tipo de interação. Se o aplicativo oferecer compatibilidade com interações do usuário com o dispositivo por meio de uma porta USB, não se esqueça de que a interação deverá ser explicitamente habilitada.

Mudanças no Android for Work

Esta versão inclui as seguintes mudanças de comportamento no Android for Work:

  • Contatos de trabalho em contextos pessoais. O Google Dialer Call Log agora exibe contatos de trabalho quando o usuário visualiza chamadas passadas. Definir setCrossProfileCallerIdDisabled() como true oculta os contatos do perfil de trabalho no Google Dialer Call Log. Os contatos de trabalho só poderão ser exibidos aos dispositivos juntos com os contatos pessoais por meio de Bluetooth se setBluetoothContactSharingDisabled() estiver definido como false. Por padrão, ele é definido como true.
  • Remoção de configuração Wi-Fi: As configurações de Wi-Fi adicionadas por um proprietário de perfil (por exemplo, por meio de chamadas ao método addNetwork()) serão removidas se esse perfil de trabalho for excluído.
  • Bloqueio de configuração Wi-Fi: Qualquer configuração Wi-Fi criada por um proprietário de dispositivo ativo não pode mais ser modificada nem excluída pelo usuário se WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN é diferente de zero. O usuário ainda pode criar e modificar as próprias configurações de Wi-Fi. Proprietários de dispositivo ativos têm o privilégio de editar ou remover qualquer configuração Wi-Fi, incluindo as não criadas por eles.
  • Baixe o Work Policy Controller adicionando uma conta Google: Quando uma conta Google que exige gerenciamento por meio do aplicativo Work Policy Controller (WPC) é adicionada ao dispositivo fora de um contexto gerenciado, o fluxo da conta adicionada agora solicita ao usuário a instalação do WPC adequado. Esse comportamento também se aplica a contas adicionadas via Settings > Accounts e no assistente de instalação inicial do dispositivo.
  • Mudanças em comportamentos específicos da DevicePolicyManager API:
    • Chamar o método setCameraDisabled() afeta a câmera somente para o usuário que realizou a chamada. Chamá-lo pelo perfil gerenciado não afeta os aplicativos de câmera em execução no usuário principal.
    • Além disso, o método setKeyguardDisabledFeatures() agora está disponível para proprietários de perfil e de dispositivo.
    • Um proprietário de perfil pode definir estas restrições de proteção de bloqueio:
    • Os métodos DevicePolicyManager.createAndInitializeUser() e DevicePolicyManager.createUser() ficaram obsoletos.
    • O método setScreenCaptureDisabled() agora bloqueia a estrutura de auxílio quando um aplicativo de um determinado usuário está em primeiro plano.
    • Agora, EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM usa SHA-256 por padrão. SHA-1 ainda é suportado para compatibilidade reversa, mas será removido no futuro. EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM agora só aceita SHA-256.
    • As APIs inicializadoras de dispositivo que existiam no Android 6.0 (API de nível 23) foram removidas.
    • EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS foi removido para que o provisionamento de impulsão do NFC não possa desbloquear programaticamente um dispositivo protegido redefinido de fábrica.
    • Agora é possível usar o EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE extra para passar dados ao aplicativo do proprietário de dispositivo durante o provisionamento de NFC do dispositivo gerenciado.
    • As Android for Work APIs estão otimizadas para permissões em tempo de execução M, incluindo perfis de trabalho, camadas de assistência e outros. As novas APIs de permissão DevicePolicyManager não afetam aplicativos anteriores ao M.
    • Quando os usuários desistem da parte síncrona do fluxo de configuração iniciado com uma intenção ACTION_PROVISION_MANAGED_PROFILE ou ACTION_PROVISION_MANAGED_DEVICE, o sistema agora retorna um código de resultado RESULT_CANCELED.
  • Mudanças em outras APIs:
    • Uso de dados: A classe android.app.usage.NetworkUsageStats foi renomeada para NetworkStats.
  • Mudanças nas configurações gerais: