O Android 8.0 introduz diversos recursos novos para usuários e desenvolvedores. Este documento destaca as novidades para os desenvolvedores.
Não deixe de conferir Mudanças de comportamento do Android 8.0 para conhecer as áreas em que as mudanças da plataforma podem afetar seus aplicativos.
Experiência do usuário
Notificações
No Android 8.0, reestruturamos as notificações para oferecer uma forma mais fácil e uniforme de gerenciar o comportamento e as configurações de notificações. Essas mudanças incluem:
- Canais de notificação: O Android 8.0 introduz canais de notificação que permitem criar um canal personalizável pelo usuário para cada tipo de notificação que você quiser exibir. A interface do usuário chama os canais de notificação de categorias de notificação. Para saber como implementar canais de notificação, consulte o guia Canais de notificação.
- Badge de notificação: O Android 8.0 introduz o suporte para a exibição de badges de notificação em ícones de inicialização de aplicativos. Os badges de notificação refletem a presença de notificações em um aplicativo, as quais o usuário ainda não tenha dispensado ou seguido. Os badges de notificação também são conhecidos como pontos de notificação. Para saber como ajustar os badges de notificação consulte o guia sobre Badges de notificação.
- Adiar: os usuários podem adiar as notificações para nova exibição mais tarde. As notificações reaparecem com o mesmo nível de importância da primeira exibição. Os aplicativos podem remover ou atualizar uma notificação adiada, mas a atualização de uma notificação adiada não causa uma nova exibição.
- Tempos limite de notificação: Agora, você pode definir um tempo limite na criação de uma notificação usando
setTimeoutAfter()
. Você pode usar esse método para especificar um período após o qual uma notificação deve ser cancelada. Se necessário, você pode cancelar uma notificação antes do decorrer do tempo limite especificado. - Configurações de notificação: Você pode chamar
setSettingsText()
para definir a exibição de texto ao criar um link para as configurações de notificação do seu aplicativo a partir de uma notificação usando o intentNotification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES
. O sistema pode fornecer os seguintes extras com o intent para filtrar as configurações que seu aplicativo deve exibir para os usuários:EXTRA_CHANNEL_ID
,NOTIFICATION_TAG
eNOTIFICATION_ID
. - Dispensa de notificação: o sistema agora distingue entre a dispensa de uma notificação pelo usuário e a remoção da notificação por um aplicativo. Para verificar como as notificações são dispensadas, você deve implementar o novo método
onNotificationRemoved()
da classeNotificationListenerService
. - Cores de fundo: agora, você pode definir e ativar uma cor de fundo para uma notificação. Use esse recurso somente para notificações de tarefas contínuas e essenciais que o usuário deve ver rapidamente. Por exemplo, você pode definir uma cor de fundo para notificações relacionadas a rotas de condução ou a uma chamada de telefone em andamento. Você também pode definir a cor de fundo desejada usando
Notification.Builder.setColor()
. Isso permite usarNotification.Builder.setColorized()
para ativar o uso de uma cor de fundo para uma notificação. - Estilo de mensagem: Notificações que usam a classe
MessagingStyle
agora podem exibir mais conteúdo no seu formulário recolhido. Você deve usar a classeMessagingStyle
para notificações relacionadas a mensagens. Você também pode usar o métodoaddHistoricMessage()
para fornecer contexto a uma conversação, adicionando mensagens históricas às notificações relacionadas a mensagens.

Figura 1. Os usuários podem realizar pressionamentos longos em ícones de inicialização de aplicativos para visualizar notificações no Android 8.0.
Estrutura de preenchimento automático
As atividades de criação de conta, acesso e transação de cartão de crédito são demoradas e propensas a erros. Aplicativos que exigem esse tipo de tarefa repetitiva podem frustrar facilmente os usuários.
O Android 8.0 introduz a estrutura de preenchimento automático para facilitar o preenchimento de formulários, como os de login e de cartões de crédito. Depois que o usuário optar pelo preenchimento automático, aplicativos novos e existentes funcionarão com o Autofill Framework.
Você pode realizar algumas etapas para otimizar a maneira com a qual seu aplicativo trabalha com a estrutura. Para saber mais, consulte Visão geral da estrutura de preenchimento automático.
Modo Imagem em imagem
O Android 8.0 permite que atividades sejam inicializadas no modo imagem em imagem (PIP). O PIP é um tipo especial do modo de várias janelas, usado principalmente para reprodução de vídeo. O modo PIP já está disponível para Android TV. O Android 8.0 disponibiliza o recurso para outros dispositivos Android.
Quando uma atividade está no modo PIP, está no estado pausado, mas deve continuar a mostrar conteúdo. Por esse motivo, você deve verificar se o aplicativo não pausa a reprodução em seu gerenciador onPause()
. Em vez disso, você deve pausar o vídeo em onStop()
e retomar a reprodução em onStart()
. Para obter mais informações, consulte Ciclo de vida do modo de várias janelas.
Para especificar que a sua atividade pode usar o modo PIP, defina android:supportsPictureInPicture
como verdadeiro no manifesto. (A partir do Android 8.0, não é necessário definir android:resizeableActivity
como verdadeiro se você permite o modo PIP para Android TV ou outros dispositivos Android. Somente é necessário definir android:resizeableActivity
se sua atividade é compatível com outros modos de várias janelas.)
Mudanças na API
O Android 8.0 introduz um novo objeto, PictureInPictureParams
, que você passa a métodos de PIP para especificar como uma atividade deverá se comportar quando estiver no modo PIP. Esse objeto especifica propriedades como a proporção preferencial da atividade.
Os métodos PIP existentes, descritos em Adicionar imagem em imagem, podem agora ser usados em todos os dispositivos Android e não apenas na Android TV. Além disso, o Android 8.0 oferece os métodos a seguir para permitir o modo PIP:
Activity.enterPictureInPictureMode(PictureInPictureParams args)
: coloca a atividade no modo imagem em imagem. A proporção da atividade e outras definições de configuração são especificadas por args. Se qualquer campo em args estiver vazio, o sistema usará os valores definidos na última vez que você chamouActivity.setPictureInPictureParams()
.A atividade especificada é colocada em um canto da tela. O resto da tela é preenchido com a atividade anterior que estava na tela. A atividade que entra no modo PIP assume o estado pausado, mas continua iniciada. Se o usuário tocar a atividade PIP, o sistema mostrará um menu para interação com o usuário. Nenhum evento de toque chega à atividade enquanto ela está no estado PIP.
-
Activity.setPictureInPictureParams()
: atualiza as definições de configuração de PIP de uma atividade. Se a atividade estiver no modo PIP no momento, as configurações serão atualizadas. Isso é útil quando a proporção da atividade muda. Se a atividade não estiver no modo PIP, essas definições de configuração serão usadas, independentemente do métodoenterPictureInPictureMode()
chamado.
Fontes para download
O Android 8.0 e a Biblioteca de Suporte 26 do Android permitem solicitar fontes pelo aplicativo de um provedor, em vez incorporar fontes ao APK ou deixar o APK baixar fontes. Esse recurso reduz o tamanho do APK, aumenta a taxa de instalação do aplicativo e permite que diversos aplicativos compartilhem a mesma fonte.
Para saber mais sobre como baixar fontes, consulte Fontes para download.
Fontes em XML
O Android 8.0 introduz um novo recurso, Fonts in XML, que permite usar fontes como recursos. Isso significa que não há necessidade de empacotar fontes como ativos. As fontes são compiladas em um arquivo R
e disponibilizadas automaticamente no sistema como recurso. Você pode acessar essas fontes com a ajuda de um novo tipo de recurso, font
.
A Biblioteca de suporte 26 oferece suporte completo a esse recurso em dispositivos com a API versões 14 e posteriores.
Para saber mais sobre como usar fontes como recursos e buscar fontes do sistema, leia Fontes em XML.
Dimensionamento automático do TextView
O Android 8.0 permite definir automaticamente o tamanho da expansão ou contração do texto com base no tamanho da TextView. Com isso, ficou muito mais fácil otimizar o tamanho do texto em telas diferentes ou com conteúdo dinâmico. Para obter mais informações sobre o dimensionamento automático da TextView no Android 8.0, consulte Dimensionamento automático de TextViews.
Ícones adaptativos
O Android 8.0 introduz ícones de inicialização adaptativos. Ícones adaptativos oferecem suporte a efeitos visuais e podem exibir uma variedade de formas em diferentes modelos de dispositivos. Para saber como criar ícones adaptativos, consulte o guia de recursos da prévia Ícones adaptativos.
Gerenciamento de cores
Agora, os desenvolvedores Android de aplicativos de imagem podem aproveitar as vantagens dos novos dispositivos que têm uma tela capaz de exibir uma ampla variedade de cores. Para exibir imagens com uma ampla gama de cores, os aplicativos precisam ativar um sinalizador no manifesto (para cada atividade) e carregar bitmaps com um perfil de cor amplo incorporado (AdobeRGB, Pro Photo RGB, DCI-P3 etc.).
WebView APIs
O Android 8.0 fornece diversas APIs para ajudar você a gerenciar os objetos WebView
que exibem conteúdo Web no seu aplicativo. Essas APIs, que melhoram a estabilidade e a segurança do seu aplicativo, incluem:
- Version API
- Google SafeBrowsing API
- Termination Handle API
- Renderer Importance API
Para saber mais sobre como usar essas APIs, consulte Gerenciar WebViews.
Fixação de atalhos e widgets
O Android 8.0 introduz a fixação no aplicativo de atalhos e widgets. No aplicativo, você pode criar atalhos e widgets fixos para os inicializadores compatíveis, dependendo da permissão do usuário.
Para saber mais, consulte o guia de recursos de preview Fixar atalhos e widgets.
Proporção máxima da tela
Aplicativos direcionados ao Android 7.1 (nível de API 25) ou anterior têm uma taxa de proporção de tela máxima padrão de 1.86. Aplicativos direcionados ao Android 8.0 ou posterior não têm uma taxa de proporção máxima padrão. Se seu aplicativo precisar definir uma taxa de proporção máxima, use o atributo maxAspectRatio no arquivo de manifesto que definir sua atividade.Suporte a várias telas
A partir do Android 8.0, a plataforma oferecerá suporte aprimorado a várias telas. Se uma atividade é compatível com o modo de várias janelas e estiver executando em um dispositivo com várias telas, os usuários poderão mover a atividade de uma tela para a outra. Quando um aplicativo lança uma atividade, o aplicativo pode especificar em que tela a atividade deve ser executada.
Observação: Se uma atividade permitir o modo de várias janelas, o Android 8.0 ativará automaticamente o suporte a várias telas para essa atividade. Você deve testar o aplicativo para verificar se funciona adequadamente em um ambiente de várias telas.
Apenas uma atividade poderá estar no estado retomado por vez, mesmo se tiver várias telas. A atividade com o foco estará no estado retomado. Todas as outras atividades estarão pausadas, mas não paradas. Para obter mais informações sobre o ciclo de vida da atividade quando várias atividades estiverem visíveis, consulte Ciclo de vida do modo de várias janelas.
Quando um usuário move uma atividade de uma tela para a outra, o sistema redimensiona a atividade e emite as alterações de tempo de execução necessárias. A própria atividade pode processar a mudança de configuração, ou permitir que o sistema destrua o processo que contém a atividade e recrie a atividade com as novas dimensões. Para saber mais, consulte Processar alterações de configuração.
A ActivityOptions
oferece dois novos métodos para permitir várias telas:
setLaunchDisplayId()
- Especifica em que tela a atividade deve ser exibida quando inicializada.
getLaunchDisplayId()
- Retorna a tela de inicialização atual da atividade.
O shell adb foi ampliado para permitir várias telas. O comando shell start
agora pode ser usado para iniciar uma atividade e para especificar a tela de destino da atividade:
adb shell start <activity_name> --display <display_id>
Margens e preenchimento unificados de layout
O Android 8.0 facilita a especificação de situações nas quais lados opostos de um elemento View
usam a mesma margem ou preenchimento. Especificamente, agora é possível usar os seguintes atributos nos seus arquivos XML de layout:
-
layout_marginVertical
, que definelayout_marginTop
elayout_marginBottom
ao mesmo tempo. -
layout_marginHorizontal
, que definelayout_marginLeft
elayout_marginRight
ao mesmo tempo. -
paddingVertical
, que definepaddingTop
epaddingBottom
ao mesmo tempo. -
paddingHorizontal
, que definepaddingLeft
epaddingRight
ao mesmo tempo.
Observação: se você personalizar a lógica do seu aplicativo para oferecer suporte a diferentes idiomas e culturas, incluindo a direção do texto, lembre-se de que esses atributos não afetam os valores de layout_marginStart
, layout_marginEnd
, paddingStart
ou paddingEnd
. Você mesmo pode definir esses valores, além dos novos atributos de layout horizontal e vertical, para criar o comportamento de layout de acordo com a direção do texto.
Captura de ponteiro
Alguns aplicativos, como jogos e clientes de desktop removo e virtualização, se beneficiam significativamente com o controle do ponteiro do mouse. A captura do ponteiro é um novo recurso do Android 8.0 que oferece esse controle enviando todos os eventos do mouse para uma visualização focada do seu aplicativo.
A partir do Android 8.0, uma View
no seu aplicativo pode solicitar a captura do ponteiro e definir um detector para processar eventos de ponteiro capturado. O ponteiro do mouse fica oculto nesse modo. A visualização pode liberar a captura do ponteiro quando não precisar mais das informações do mouse. O sistema também pode liberar a captura do ponteiro quando a visualização perder o foco, por exemplo, quando o usuário abrir outro aplicativo.
Para saber mais sobre como usar esse recursos no seu aplicativo, consulte Captura do ponteiro.
Categorias de aplicativo
O Android 8.0 permite que cada aplicativo declare uma categoria adequada a ele, quando relevante. Essas categorias são usadas para reunir aplicativos com objetivo ou função semelhante quando apresentados aos usuários, como uso de dados, uso de bateria ou uso de armazenamento. Você pode definir uma categoria para o aplicativo definindo o atributo android:appCategory
com uma tag <application>
no seu manifesto.
Inicializador do Android TV
O Android 8.0 inclui uma nova experiência de tela inicial da Android TV com foco no conteúdo, que é disponibilizada com o emulador da Android TV e a imagem de dispositivo Nexus Player para o Android 8.0. A nova tela inicial organiza o conteúdo de vídeo em linhas correspondentes a canais, cada uma preenchida com programas de um aplicativo no sistema. Aplicativos podem publicar diversos canais e usuários podem configurar quais canais desejam ver na tela inicial. A tela inicial do Android TV também inclui uma linha Watch Next, que é preenchida com programas de aplicativos com base nos hábitos de visualização do usuário. Os aplicativos também podem fornecer prévias dos vídeos, que são reproduzidas automaticamente quando um usuário foca em um programa. A API para preencher canais e programas faz parte das TvProvider APIs, que são distribuídas como um módulo da Biblioteca de Suporte do Android com o Android 8.0.
AnimatorSet
A partir do Android 8.0, a API AnimatorSet
passa a permitir busca e reprodução ao contrário. A busca permite posicionar o conjunto de animações em um ponto específico no tempo. A reprodução ao contrário será útil se o aplicativo incluir animações para ações que podem ser desfeitas. Em vez de definir dois conjuntos de animação separados, você pode reproduzir o mesmo conjunto ao contrário.
Interação e navegação
Clusters de navegação por teclado
Se uma atividade do seu aplicativo usa uma hierarquia de vistas complexa, como a da Figura 2, pense em organizar grupos de elementos da IU em clusters para facilitar a navegação por teclado. Os usuários podem pressionar Meta+Tab ou Search+Tab em dispositivos Chromebook para navegar de um cluster a outro. Alguns bons exemplos de cluster são: painéis laterais, barras de navegação, principais áreas de conteúdo e elementos que podem conter diversos elementos secundários.

Para transformar um elemento View
ou ViewGroup
em um cluster, defina o atributo android:keyboardNavigationCluster
como true
no arquivo XML do layout do elemento ou passe true
para setKeyboardNavigationCluster()
na lógica da IU do aplicativo.
Observação: os clusters não podem ser aninhados, embora clusters não aninhados possam aparecer em diversos níveis da hierarquia. Se você tentar aninhar clusters, a estrutura tratará somente o elemento ViewGroup
do nível mais alto como um cluster.
Em dispositivos de tela tátil, é possível definir como true
o elemento android:touchscreenBlocksFocus
do objeto ViewGroup
designado como cluster para permitir entrar e sair da navegação somente nesse cluster. Se você aplicar essa configuração a um cluster, os usuários não poderão usar a tecla "Tab" nem as setas para entrar e sair da navegação no cluster — eles terão que pressionar a combinação do teclado de navegação no cluster.
Foco padrão da vista
No Android 8.0, é possível atribuir a View
que deve receber foco depois que uma atividade (re)criada é retomada e o usuário pressiona uma tecla de navegação no teclado, como o "Tab". Para aplicar essa configuração de "foco por padrão", defina como true
o atributo android:focusedByDefault
do elemento View
no arquivo XML do layout que contém o elemento da IU, ou passe true
parasetFocusedByDefault()
na lógica da IU do seu aplicativo.
Sistema
Novos detectores de StrictMode
O Android 8.0 adiciona três novos detectores de StrictMode para ajudar a identificar possíveis bugs no seu aplicativo:
detectUnbufferedIo()
detectará quando seu aplicativo ler ou gravar dados sem buffer, o que pode afetar o desempenho de forma significativa.detectContentUriWithoutPermission()
detectará quando seu aplicativo acidentalmente esquecer de conceder permissões a outro aplicativo ao iniciar uma atividade fora do aplicativo.detectUntaggedSockets()
detectará quando seu aplicativo executar tráfego de rede sem usarsetThreadStatsTag(int)
para marcar seu tráfego para fins de depuração.
Dados em cache
O Android 8.0 oferece melhores orientações e comportamentos sobre dados em cache. Cada aplicativo agora recebe uma cota de espaço em disco para dados em cache, conforme é retornado por getCacheQuotaBytes(UUID)
.
Quando o sistema precisa liberar espaço em disco, ele começará excluindo arquivos em cache dos aplicativos que mais ultrapassaram a cota alocada. Dessa forma, se você manter seus dados em cache dentro da cota alocada, os arquivos em cache serão alguns dos últimos que serão excluídos do sistema quando necessário. Quando o sistema está decidindo quais arquivos em cache excluir de dentro do seu aplicativo, ele considerará primeiro os mais antigos (conforme é determinado pelo tempo modificado).
Há também dois novos comportamentos que podem ser ativados de acordo com o diretório para controlar a forma com que o sistema libera o cache com dados:
StorageManager.setCacheBehaviorAtomic()
pode ser usado para indicar que um diretório e todo o seu conteúdo deve ser excluído como apenas uma unidade atômica.setCacheBehaviorTombstone(File, boolean)
pode ser usado para indicar que, em vez de excluir arquivos de um diretório, eles devem ser truncados para terem 0 bytes de tamanho, deixando o arquivo vazio intacto.
Por fim, quando você precisa alocar espaço em disco para arquivos grandes, considere usar a nova allocateBytes(FileDescriptor, long)
API, que automaticamente liberará arquivos em cache que pertençam a outros aplicativos (conforme for necessário) para atender à sua solicitação. Ao decidir se o dispositivo tem espaço em disco suficiente para armazenar seus novos dados, chame getAllocatableBytes(UUID)
em vez de usar getUsableSpace()
, pois ele vai levar em consideração todos os dados em cache que o sistema esteja disposto a apagar em seu nome.
Paginação do provedor de conteúdo
Atualizamos os provedores de conteúdo para incluir o recurso de carregar um conjunto de dados grande, uma página por vez. Por exemplo, um aplicativo de fotografia com vários milhares de imagens pode consultar um subconjunto dos dados para exibição em uma página. Cada página de resultados retornada por um provedor de conteúdo é representada por um único objeto Cursor. Para usar esse recurso, o cliente e o provedor devem implementar a paginação.
Para obter informações detalhadas sobre as mudanças nos provedores de conteúdo, consulte ContentProvider
e ContentProviderClient
.
Solicitações de atualização de conteúdo
Agora, cada uma das classes ContentProvider
e ContentResolver
contém um método refresh()
. Assim, os clientes conseguem saber se as informações que solicitaram são as atuais.
É possível adicionar lógica personalizada de atualização de conteúdo ampliando ContentProvider
. Não se esqueça de neutralizar o método refresh()
para retornar true
, indicando aos clientes do seu provedor que você tentou atualizar os dados por conta própria.
O seu aplicativo do cliente pode solicitar conteúdo atualizado explicitamente chamando um método diferente, também chamado refresh()
. Ao chamar este método, passe o URI dos dados para atualizar.
Observação: como sua solicitação de dados pode vir por uma rede, você deve invocar refresh()
no lado do cliente somente se houver grandes indícios de que o conteúdo é antigo. O motivo mais comum para se realizar esse tipo de atualização de conteúdo é em resposta a um gesto de deslizar para atualizar, solicitando explicitamente que a IU atual exiba conteúdo atualizado.
Melhorias no JobScheduler
O Android 8.0 introduz diversas melhorias no JobScheduler
. Essas melhorias permitem que seu aplicativo cumpra com facilidade os novos limites de execução em segundo plano, pois você geralmente pode usar jobs agendados para substituir os serviços de segundo plano agora restringidos ou receptores de transmissão implícitos.
As atualizações do JobScheduler
incluem:
-
Agora é possível associar uma fila de trabalho a um job agendado. Para adicionar um item de trabalho à fila de um job, chame
JobScheduler.enqueue()
. Quando o job estiver em execução, ele pode retirar o trabalho pendente da fila e processá-lo. Essa funcionalidade lida com muitos dos casos de uso que anteriormente teriam exigido a inicialização de um serviço de segundo plano, particularmente serviços que implementamIntentService
. -
Agora é possível chamar
JobInfo.Builder.setClipData()
para associar umClipData
a um job. Essa opção permite que você associe concessões de permissão de URI a um job, semelhante a como essas permissões podem ser propagadas paraContext.startService()
. Você também pode usar concessões de permissão de URI com intents em filas de trabalho. -
Jobs agendados agora oferecem suporte a diversas novas limitações:
JobInfo.isRequireStorageNotLow()
- O job não é executado se o armazenamento disponível do dispositivo for baixo.
JobInfo.isRequireBatteryNotLow()
- O job não é executado se o nível da bateria atingir ou for inferior ao limite crítico; esse é o nível no qual o dispositivo mostra a caixa de diálogo de sistema Low battery warning.
NETWORK_TYPE_METERED
- O job exige uma conexão de rede tarifada, como a maioria dos planos de dados de celular.
Repositório de dados personalizado
O Android 8.0 permite fornecer um repositório de dados personalizado para as suas preferências, o que pode ser útil se o seu aplicativo armazena as preferências em banco de dados local ou na nuvem, ou se as preferências são de um dispositivo específico. Para saber mais sobre como implementar o repositório de dados, consulte Repositório de dados personalizado.
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 consequências:
- pode fazer o código atual ter tipos de retorno ambíguos. Por exemplo, se houver
someMethod(View)
esomeMethod(TextView)
, leva-se o resultado de uma chamada afindViewById()
. - Quando se usa a linguagem Java 8, é necessária uma transmissão explícita para
View
quando o tipo retornado não tem restrições (por exemplo,assertNotNull(findViewById(...)).someViewMethod())
. - Neutralizações de métodos
findViewById()
não finais (por exemplo,Activity.findViewById()
) precisarão ter o próprio tipo retornado atualizado.
Aprimoramentos de mídia
VolumeShaper
Há uma nova classe VolumeShaper. Você pode usá-la para realizar transições curtas de volume automatizadas, como fade-ins, fade-outs e cross fades.
Melhorias no foco do áudio
Aplicativos de áudio compartilham a saída de áudio em um dispositivo ao solicitar e abandonar o foco do áudio. Um aplicativo lida com as mudanças de foco ao iniciar ou interromper a reprodução, ou atenuando o volume. Há uma nova classe AudioFocusRequest
. Com ela, os aplicativos têm novos recursos para lidar com mudanças no foco do áudio: atenuação automática e ganho de foco atrasado.
Métricas de mídia
Um novo método getMetrics()
retorna um objeto PersistableBundle
contendo informações de configuração e desempenho, expressos como mapa de atributos e valores. O método getMetrics()
é definido para estas classes de mídia:
MediaPlayer.getMetrics()
MediaRecorder.getMetrics()
MediaCodec.getMetrics()
MediaExtractor.getMetrics()
As métricas são coletadas separadamente para cada instância e persistem durante o tempo de vida da instância. Se nenhuma métrica estiver disponível, o método retornará nulo. As métricas reais retornadas dependem da classe.
MediaPlayer
O Android 8.0 adiciona vários novos métodos à classe MediaPlayer. Esses métodos não podem melhorar a forma com a qual seu aplicativo gerencia a reprodução de mídia de várias maneiras:
- Controle detalhado durante a busca de um quadro.
- Capacidade de reproduzir material protegido por DRM.
O MediaPlayer agora oferece suporte à criptografia em nível de amostra.
MediaRecorder
- MediaRecorder agora oferece suporte ao formato MPEG2_TS, que é útil para o streaming:
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS);
consulte
MediaRecorder.OutputFormat
- O
MediaMuxer
agora pode gerenciar qualquer quantidade de streams de áudio e vídeo. Você não está mais limitado a uma faixa de áudio e/ou uma faixa de vídeo. UseaddTrack()
para combinar quantas faixas você quiser. - O
MediaMuxer
também pode adicionar uma ou mais faixas de metadados que contenham informações por frame definidas pelo usuário. O formato dos metadados é definido por seu aplicativo. A faixa de metadados é compatível apenas com contêineres MP4.
Metadados podem ser úteis para o processamento offline. Por exemplo, sinais de giroscópio do sensor podem ser usados para estabilizar o vídeo.
Ao adicionar uma faixa de metadados, o formato MIME da faixa deve ser iniciado pelo prefixo “application/". Escrever metadados é o mesmo que escrever dados de áudio/vídeo, mas os dados não são originados de um MediaCodec
. Em vez disso, o aplicativo passa um ByteBuffer
com um timestamp associado ao método writeSampleData()
. O timestamp deve ter a mesma base que as faixas de áudio e vídeo.
O arquivo MP4 gerado usa o TextMetaDataSampleEntry
definido na seção 12.3.3.2 do ISOBMFF para sinalizar o formato MIME dos metadados. Ao usar MediaExtractor
para extrair o arquivo com a faixa de metadados, o formato MIME dos metadados será extraído para MediaFormat
.
Controle de reprodução de áudio
O Android 8.0 permite que você consulte e solicite como um dispositivo produz som. Os aspectos a seguir do controle da reprodução de áudio permitem que seu serviço produza som com somente em condições de dispositivo favoráveis.
Novo tipo de uso de áudio para Google Assistente
A classe AudioAttributes
contém um novo tipo de som, USAGE_ASSISTANT
, que corresponde às respostas que o Google Assistente fala em um dispositivo.
Alterações na reprodução de áudio do dispositivo
Se quiser que seu serviço comece a produzir som apenas quando uma configuração de áudio de dispositivo específica estiver ativada, você pode usar a classe AudioManager
para registrar uma instância de AudioManager.AudioPlaybackCallback
, cujo método onPlaybackConfigChanged()
ajuda você a identificar o conjunto de atributos de áudio atualmente ativos.
Solicitações explícitas de foco de áudio
Seu serviço pode enviar uma solicitação mais específica para receber foco de áudio em todo o dispositivo ao usar o método requestAudioFocus()
. Passe um objeto AudioFocusRequest
, que é criado usando AudioFocusRequest.Builder
. Nessa classe builder, você pode especificar as seguintes opções:
- O tipo de foco que você deseja obter, como
AUDIOFOCUS_GAIN_TRANSIENT
ouAUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
. - Se seu serviço deve continuar a um volume mais baixo ou pausar totalmente quando outro serviço de áudio assume o foco do dispositivo.
- Se seu serviço pode esperar para obter o foco até que o dispositivo esteja pronto.
Observação: Ao compilar sua instância de AudioFocusRequest
, se você indicar que seu serviço pode esperar para produzir som ao chamar setAcceptsDelayedFocusGain()
, você também deve chamar setOnAudioFocusChangeListener()
para que o serviço saiba quando pode começar a produzir som.
Acesso melhorado a arquivos de mídia
A Estrutura de Acesso ao Armazenamento (SAF) permite que aplicativos exponham DocumentsProvider
, que pode conceder acesso a arquivos em uma fonte de dados para outros aplicativos. Na verdade, provedor de documentos pode até mesmo conceder acesso a arquivos que residam no armazenamento de rede ou que use um protocolo como Media Transfer Protocol (MTP).
Entretanto, acessar grandes arquivos de mídia de uma fonte de dados remota apresenta alguns desafios.
- Media players exigem acesso com busca a um arquivo de um provedor de documentos. Em casos nos quais um grande arquivo de mídia reside em uma fonte de dados remota, o provedor de documentos deve recuperar todos os dados antecipadamente e criar um instantâneo de descritor de arquivo. O media player não pode reproduzir o arquivo sem o descritor, portanto, a reprodução não pode ser iniciada até que o provedor de documentos termine de baixar o arquivo.
- Gerenciadores de coleta de mídia, como aplicativos de foto, devem passar por uma série de URIs para alcançar as mídias armazenadas em um cartão SD externo por meio de pastas com escopo. Esse padrão de acesso torna operações em massa em mídias — como mover, copiar e excluir — muito lentas.
- Gerenciadores de coleta de mídia não podem determinar a localização de um documento por seu URI. Isso torna difícil para que esses tipos de aplicativos permitam que os usuários escolham onde salvar um arquivo de mídia.
O Android 8.0 soluciona cada um desses desafios ao melhorar a Estrutura de Acesso ao Armazenamento.
Provedores de documentos personalizados
A partir do Android 8.0, a Estrutura de Acesso ao Armazenamento permite que provedores de documentos personalizados criem descritores de arquivo com busca para arquivos que residem em uma fonte de dados remota. A SAF pode abrir um arquivo para obter um descritor de arquivo com busca. A SAF então entrega solicitações de bytes discretas para o provedor de documentos. Esse recurso permite que um provedor de documentos retorne o intervalo exato de bytes que um aplicativo de media player tenha solicitado em vez de armazenar todo o arquivo em cache antecipadamente.
Para usar esse recurso, você precisa chamar o novo método StorageManager.openProxyFileDescriptor()
. O método openProxyFileDescriptor()
aceita um objeto ProxyFileDescriptorCallback
como callback. A SAF invoca um callback sempre que um aplicativo cliente executa operações de arquivo no descritor de arquivo retornado do provedor de documentos.
Acesso direto a documentos
A partir do Android 8.0, você pode usar o método getDocumentUri()
para obter um URI que referencie o mesmo documento que o mediaUri
fornecido. Entretanto, como o URI retornado tem o suporte de um DocumentsProvider
, os gestores de coleta de mídia podem acessar o documento diretamente, sem precisar passar por árvores de diretórios com escopo. Consequentemente, os gerenciadores de mídia podem realizar operações de arquivo no documento a uma velocidade significativamente superior.
Atenção: O método getDocumentUri()
somente localiza arquivos de mídia; ele não concede aos aplicativos permissão para acessar esses arquivos. Para saber mais sobre como obter permissão de acesso aos arquivos de mídia, consulte a documentação de referência.
Caminhos para documentos
Ao usar a Estrutura de Acesso ao Armazenamento no Android 8.0, você pode usar o método findDocumentPath()
, disponível nas classes DocumentsContract
e DocumentsProvider
, para determinar o caminho da raiz de um arquivo pelo ID de um documento. O método retorna esse caminho em um objeto DocumentsContract.Path
. Em casos nos quais um sistema de arquivos tem diversos caminhos definidos para o mesmo documento, o método retorna o caminho usado com mais frequência para alcançar o documento com o ID fornecido.
Essa funcionalidade é particularmente útil nos seguintes cenários:
- Seu aplicativo usa uma caixa de diálogo "save as" que exibe a localização de um documento específico.
- O aplicativo mostra pastas em uma visualização de resultados de pesquisa e deve carregar os documentos filhos que se encontram dentro de uma pasta em particular, caso o usuário a tenha selecionado.
Observação: se seu aplicativo tiver permissão para acessar apenas alguns dos documentos no caminho, o valor de retorno de findDocumentPath()
incluirá apenas as pastas e os documentos que o aplicativo pode acessar.
Conectividade
Wi-Fi Aware
O Android 8.0 adiciona suporte para Wi-Fi Aware, que é baseado na especificação Rede de Reconhecimento de Vizinhos (NAN). Em dispositivos com o hardware Wi-Fi Aware apropriado, aplicativos e dispositivos próximos podem descobrir e comunicar-se por Wi-Fi sem um ponto de acesso à Internet. Estamos trabalhando com nossos parceiros de hardware para levar a tecnologia Wi-Fi Aware para os dispositivos assim que possível. Para saber mais sobre como integrar o Wi-Fi Aware em um aplicativo, consulte Wi-Fi Aware.
Bluetooth
O Android 8.0 contribui com o suporte a Bluetooth da plataforma por adicionar os seguintes recursos:
- Suporte ao padrão AVRCP 1.4, que permite navegação em bibliotecas de música.
- Suporte ao padrão Bluetooth Low-Energy (BLE) 5.0.
- Integração com o codec Sony LDAC na pilha Bluetooth.
Pareamento de dispositivo complementar
O Android 8.0 oferece APIs que permitem personalizar a caixa de diálogo da solicitação a ser pareada durante a tentativa de pareamento com dispositivos complementares usando Bluetooth, BLE e Wi-Fi. Para obter mais informações, consulte Pareamento de dispositivo complementar.
Para obter mais informações sobre como usar o Bluetooth no Android, consulte o guia Bluetooth. Para saber quais mudanças no Bluetooth são específicas do Android 8.0, consulte a seção Bluetooth da página Mudanças de comportamento do Android 8.0.
Compartilhamento
Compartilhamento inteligente
O Android 8.0 reconhece as preferências de compartilhamento personalizado dos usuários e compreende melhor o tipo de conteúdo que deve ser compartilhado como cada aplicativo. Por exemplo, se um usuário tira uma foto de um recibo, o Android 8.0 pode sugerir um aplicativo de rastreamento de despesas; se o usuário tirar uma selfie, um aplicativo de mídia social pode ser mais adequado para a imagem. O Android 8.0 automaticamente reconhece todos esses padrões de acordo com as preferências personalizadas dos usuários.
O compartilhamento inteligente funciona para tipos de conteúdo diferentes de image
, como audio
, video
, text
, URL
etc.
Para ativar o compartilhamento inteligente, adicione uma ArrayList
de até três anotações de string ao intent que compartilhar o conteúdo. As anotações devem descrever os principais componentes ou tópicos do conteúdo. O exemplo de código a seguir mostra como adicionar anotações ao intent:
ArrayList<String> annotations = new ArrayList<>(); annotations.add("topic1"); annotations.add("topic2"); annotations.add("topic3"); intent.putStringArrayListExtra( Intent.EXTRA_CONTENT_ANNOTATIONS, annotations );
Para obter informações detalhadas sobre anotações de compartilhamento inteligente, consulte EXTRA_CONTENT_ANNOTATIONS
.
Seleção inteligente de texto
Em dispositivos compatíveis, o Android 8.0 permite que os aplicativos ajudem os usuários a interagir com texto de formas mais significativos. Quando os usuários pressionam longamente uma palavra em uma entidade — um formato reconhecido como, por exemplo um endereço ou nome de restaurante — o sistema seleciona toda a entidade. O usuário vê uma barra de ferramentas flutuante que pode incluir um aplicativo que pode processar a entidade de texto selecionada. Por exemplo, se o sistema reconhecer um endereço, ele pode direcionar o usuário para o aplicativos Maps.
Entidades reconhecidas pelo sistema incluem endereços, URLs, números de telefone e endereços de e-mail. Para saber mais, consulte TextClassifier
.
Acessibilidade
O Android 8.0 oferece suporte aos seguintes recursos de acessibilidade para desenvolvedores que criam seus próprios serviços de acessibilidade. Saiba mais sobre como tornar o aplicativo mais acessível consultando Acessibilidade.
Botão de acessibilidade
Agora, seu serviço de acessibilidade pode solicitar a exibição de um botão de acessibilidade na área de navegação do sistema, dando ao usuário uma forma rápida de ativar o recurso do seu serviço a partir de qualquer tela do dispositivo. Para isso acontecer, adicione o sinalizador FLAG_REQUEST_ACCESSIBILITY_BUTTON
em um atributo android:accessibilityFlags
do objeto AccessibilityServiceInfo
. Você ainda pode registrar retornos de chamada usando registerAccessibilityButtonCallback()
.
Observação: O recurso está disponível somente em dispositivos que fornecem uma área de navegação renderizada por software. Sempre use isAccessibilityButtonAvailable()
e responda a mudanças baseadas na disponibilidade do botão de acessibilidade implementando onAvailabilityChanged()
. Assim, os usuários sempre poderão acessar o recurso do seu serviço, mesmo se o botão de acessibilidade não for suportado ou não estiver disponível.
Ajuste de volume independente
O Android 8.0 introduz a categoria de volume STREAM_ACCESSIBILITY
, que permite controlar o volume da saída de áudio do serviço de acessibilidade de forma independente dos outros sons do dispositivo.
Para usar esse novo tipo de fluxo para controlar o volume do recurso de acessibilidade, insira a opção FLAG_ENABLE_ACCESSIBILITY_VOLUME
no serviço de acessibilidade. Assim, é possível alterar o volume do áudio de acessibilidade do dispositivo usando adjustStreamVolume()
.
Gestos de impressão digital
Seu serviço de acessibilidade também pode responder a um mecanismo de entrada alternativo, gestos de deslizamento direcionais (para cima, para baixo, para a esquerda e para a direita) juntamente com o sensor de impressão digital de um dispositivo. Para receber retornos de chamada sobre essas interações, execute a sequência de etapas a seguir:
- Declare a permissão
USE_FINGERPRINT
e a capacidadeCAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES
. - Defina o sinalizador
FLAG_REQUEST_FINGERPRINT_GESTURES
no atributoandroid:accessibilityFlags
. - Registre-se para callbacks usando
registerFingerprintGestureCallback()
.
Lembre-se de que nem todos os dispositivos incluem sensores de impressão digital. Você pode usar o método isHardwareDetected()
para identificar se um dispositivo oferece suporte ao sensor. Mesmo em dispositivos que incluam um sensor de impressão digital, seu serviço pode usar o sensor somente quando ele não estiver em uso para fins de autenticação. Para identificar quando o sensor está disponível, chame o método isGestureDetectionAvailable()
para implementar o callback onGestureDetectionAvailabilityChanged()
.
Destaque em nível mundial
Para determinar as localizações dos caracteres visíveis em um objeto TextView
, você pode passar EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY
como o primeiro argumento em refreshWithExtraData()
. Um objeto Bundle
, que você fornece como o segundo argumento para refreshWithExtraData()
é então atualizado para incluir uma matriz analisável de objetos Rect
. Cada objeto Rect
representa a caixa limitadora de um caractere específico.
Se o serviço usar um objeto TextToSpeech
para ler em voz alta o conteúdo exibido na tela, você poderá obter informações de tempo mais precisas sobre quando os mecanismos de conversão de texto em fala começam a falar palavras sintetizadas específicas, desde que o mecanismo forneça essa informação. Quando se espera que um mecanismo comece a reproduzir áudio em uma faixa de texto específica, a API de conversão de texto em fala usa o método onRangeStart()
para informar o seu serviço de que a fala da faixa de texto está começando.
Se você criar sua própria implementação de TextToSpeechService
, você pode oferecer suporte a essa nova funcionalidade usando o método rangeStart()
.
Valores padronizados de intervalo unilateral
Algumas instâncias de AccessibilityNodeInfo
usam uma instância de AccessibilityNodeInfo.RangeInfo
para indicar que um elemento da IU pode assumir um intervalo de valores. Ao criar um intervalo usando RangeInfo.obtain()
, ou ao recuperar os valores extremos do intervalo usando getMin()
e getMax()
, não se esqueça de que o Android 8.0 tem definições padronizadas para intervalos unilaterais:
- Nos intervalos sem valor mínimo,
Float.NEGATIVE_INFINITY
representa o valor mínimo. - Nos intervalos sem valor máximo,
Float.POSITIVE_INFINITY
representa o valor máximo.
Texto de dica
O Android 8.0 contém diversos métodos de interação com texto de dica de um objeto de texto editável:
- Os métodos
isShowingHintText()
esetShowingHintText()
indicam e definem, respectivamente, se o conteúdo de texto atual do nó representa o texto de dica do nó. Se o nó não contém texto editável, não deve conter texto de dica. - Para acessar o próprio texto de dica, use
getHintText()
. Mesmo que um objeto não esteja exibindo o texto de dica no momento, chamargetHintText()
funciona corretamente.
Envio de gesto continuado
Seu serviço agora pode especificar sequências de movimentos que pertencem ao mesmo gesto programático usando o argumento final willContinue
no construtor GestureDescription.StrokeDescription
.
Segurança e privacidade
Permissões
O Android 8.0 introduz diversas novas permissões relacionadas à telefonia:
- As permissões
ANSWER_PHONE_CALLS
permitem que seu aplicativo atenda a chamadas telefônicas de forma programática. Para lidar com uma chamada telefônica recebida em seu aplicativo, você pode usar o métodoacceptRingingCall()
. - A permissão
READ_PHONE_NUMBERS
concede ao seu aplicativo acesso de leitura aos números de telefone armazenados em um dispositivo.
Essas permissões são classificadas como perigosas e ambas fazem parte do grupo de permissões PHONE
.
Novas APIs de acesso e descoberta de contas
O Android 8.0 introduz várias melhorias sobre como obter acesso a contas de usuário. Para as contas que gerenciam, os autenticadores podem usar suas próprias políticas para decidir se devem ocultar ou revelar contas para um aplicativo. O Android rastreia aplicativos que podem acessar uma conta em particular.
Nas versões anteriores do Android, aplicativos que queriam controlar a lista de contas de usuário tinham de obter atualizações sobre todas as contas, incluindo as contas com tipos não relacionados. O Android 8.0 adiciona o método addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[])
, que permite que aplicativos especifiquem uma lista de tipos de conta para os quais as mudanças de conta devem ser recebidas.
Mudanças na API
O AccountManager oferece seis novos métodos para ajudar os autenticadores a gerenciar quais aplicativos podem ver uma conta:
setAccountVisibility(android.accounts.Account, java.lang.String, int)
: define o nível de visibilidade para uma combinação específica de conta de usuário e pacote.-
getAccountVisibility(android.accounts.Account, java.lang.String)
: obtém o nível de visibilidade para uma combinação específica de conta de usuário e pacote. -
getAccountsAndVisibilityForPackage(java.lang.String, java.lang.String)
: permite que autenticadores obtenham as contas e níveis de visibilidade de um determinado pacote. -
getPackagesAndVisibilityForAccount(android.accounts.Account)
: permite que autenticadores obtenham valores de visibilidade armazenados de uma determinada conta. -
addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.String, java.lang.Integer>)
: permite que autenticadores inicializem os valores de visibilidade de uma conta. -
addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[])
: adiciona um detectorOnAccountsUpdateListener
ao objetoAccountManager
. O sistema chamará esse detector sempre que a lista de contas no dispositivo for alterada.
O Android 8.0 introduz dois valores especiais de nome de pacote para especificar níveis de visibilidade para aplicativos que não foram definidos usando o método setAccountVisibility(android.accounts.Account, java.lang.String, int)
. O valor de visibilidade PACKAGE_NAME_KEY_LEGACY_VISIBLE
é aplicado a aplicativos que têm a permissão GET_ACCOUNTS
, e às versões de destino do Android anteriores ao Android 8.0 ou cujas assinaturas correspondam ao autenticador direcionado a qualquer versão Android. O PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE
fornece um valor de visibilidade padrão para aplicativos que não foram definidos anteriormente e para os quais PACKAGE_NAME_KEY_LEGACY_VISIBLE
não é aplicável.
Para obter mais informações sobre o acesso a novas contas e sobre as APIs de descoberta, consulte a referência para AccountManager
e OnAccountsUpdateListener
.
API de navegação segura do Google
A classe WebView
agora inclui uma Safe Browsing API para melhorar a segurança na navegação na Web. Para saber mais, consulte API de navegação segura do Google.
Teste
Teste de instrumentação
O Android 8.0 fornece os seguintes suportes adicionais para testes de instrumentação do seu aplicativo.
Executar em processos não padrão do aplicativo
Agora você pode especificar que um determinado teste de instrumentação seja executado em um processo externo aos processos padrão do aplicativo. Essa opção é muito útil se o seu aplicativo contiver diversas atividades executadas em processos diferentes.
Para configurar a instrumentação em processo não padrão, navegue para o arquivo de manifesto e siga para o elemento <instrumentation>
desejado. Adicione o atributo android:targetProcess
e defina seu valor como uma das opções a seguir:
- O nome de um determinado processo.
- Uma lista separada por vírgula de nomes de processo.
- Um caractere curinga (
"*"
), que permite que a instrumentação seja executada em qualquer processo iniciado que execute código no pacote especificado no atributoandroid:targetPackage
.
Enquanto o teste de instrumentação estiver em execução, você pode verificar que processo ele está testando chamando getProcessName()
.
Relatar resultados durante um teste
Agora é possível relatar os resultados durante o teste de instrumentação, em vez de depois, chamando addResults()
.
Intents simulados para testes
Para facilitar a criação de testes de IU independentes e isolados para as atividades do seu aplicativo, o Android 8.0 introduz o método onStartActivity()
. Você modifica esse método em uma subclasse personalizada da classe Instrumentation.ActivityMonitor
para lidar com um intent particular invocado pela classe do seu teste.
Quando sua classe de teste invoca o intent, o método retorna um objeto Instrumentation.ActivityResult
de stub em vez de executar o próprio intent. Ao usar essa lógica de intent simulado, você pode se concentrar em como sua atividade prepara e lida com o intent que você passar para uma atividade diferente ou para um aplicativo totalmente diferente.
Tempo de execução e ferramentas
Otimizações de plataforma
O Android 8.0 leva o tempo de execução e outras otimizações para a plataforma, resultando em diversas melhorias de desempenho. Essas otimizações incluem a coleta de lixo com compactação simultânea, um uso mais eficiente da memória e localidade de código.
Elas resultam em tempos de inicialização mais rápidos e um desempenho melhor tanto para o SO quanto para os aplicativos.
Suporte atualizado para Java
O Android 8.0 adiciona suporte para diversas OpenJDK Java APIs adicionais:
java.time
do OpenJDK 8.java.nio.file
ejava.lang.invoke
do OpenJDK 7.
Para saber mais sobre as classes e métodos desses pacotes recém-adicionados, consulte a documentação de referência da API.
Se quiser usar os recursos de linguagem do Java 8 no Android Studio, faça o download da versão preview mais recente.
ICU4J Android Framework APIs atualizadas
O Android 8.0 amplia as APIs da estrutura Android para ICU4J — que são um subconjunto das ICU4J APIs — para desenvolvedores usarem no pacote android.icu
. Essas APIs usam dados de localização presentes no dispositivo para você pode reduzir o tamanho do seu APK por não compilar as bibliotecas ICU4J nele.
Tabela 1. Versões ICU, CLDR e unicode usadas no Android.
Nível da Android API | Versão ICU | Versão CLDR | Versão unicode |
---|---|---|---|
Android 7.0 (API nível 24), Android 7.1 (API nível 25) | 56 | 28 | 8.0 |
Android 8.0 | 58.2 | 30.0.3 | 9.0 |
Android empresarial
Novos recursos e APIs para empresa foram introduzidos em dispositivos que usam o Android 8.0. Alguns dos destaques são:
- Perfis de trabalho em dispositivos totalmente gerenciados permitem separar dados de trabalho de dados pessoais, mas gerenciar ambos.
- A delegação de APIs permite que os proprietários do dispositivo e de perfil atribuam gerenciamento de aplicativo a outros aplicativos.
- Melhorias no fluxo de provisionamento da experiência do usuário (incluindo novas opções de personalização) reduzem o tempo de configuração.
- Novos controles sobre Bluetooth, Wi-Fi, backup e segurança permitem que as empresas gerenciem mais partes do dispositivo. Registro de atividades de rede ajudam as empresas a detectar problemas.
Para saber mais sobre esses e mais dos novos recursos e APIs para empresas do Android, acesse Android no Enterprise.