O Android 8.0 (nível 26 da API) introduz vários novos recursos para usuários e desenvolvedores. Este documento destaca as novidades para os desenvolvedores.
Consulte também as Mudanças de comportamento do Android 8.0 para saber mais sobre as áreas em que as mudanças na plataforma podem afetar seus apps.
Experiência do usuário
Modo Imagem em imagem
O Android 8.0 (API de nível 26) permite que atividades sejam iniciadas no modo picture-in-picture (PIP). O PIP é um tipo especial de modo de várias janelas usado principalmente para reprodução de vídeos. O modo PIP estava disponível originalmente apenas para Android TV. O Android 8.0 disponibiliza o recurso em outros dispositivos Android.
Quando uma atividade está no modo PIP, ela está no estado pausado, mas precisa
continuar mostrando conteúdo. Por esse motivo, verifique se o app
não pausa a reprodução no gerenciador
onPause()
. Em vez disso, pause o vídeo em onStop()
e retome a reprodução em onStart()
. Para mais informações, consulte
Ciclo de vida
de várias janelas.
Para especificar que sua atividade pode usar o modo PIP, defina
android:supportsPictureInPicture
como verdadeiro no manifesto.
A partir do Android 8.0, o PIP não exige o
atributo de manifesto android:resizeableActivity
.
No entanto, você precisa definir
android:resizeableActivity
como "true" se sua atividade oferecer suporte a outros
modos de várias janelas.
O Android 8.0 (API de nível 26) introduz um novo objeto, PictureInPictureParams
,
que você transmite aos métodos do 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 Como adicionar o modo picture-in-picture, agora podem ser usados em todos os dispositivos Android, não apenas no Android TV. Além disso, o Android 8.0 oferece os seguintes métodos para oferecer suporte ao modo PIP:
Activity.enterPictureInPictureMode(PictureInPictureParams args)
: coloca a atividade no modo picture-in-picture. A proporção da atividade e outras definições de configuração são especificadas por args. Se algum 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, e o restante da tela é preenchido com a atividade anterior que estava na tela. A atividade que entra no modo PIP entra no estado pausado, mas permanece iniciada. Se o usuário tocar na atividade do PIP, o sistema mostrará um menu para interagir com o usuário. Nenhum evento de toque chega à atividade enquanto ela está no estado do PIP.
-
Activity.setPictureInPictureParams()
: atualiza as configurações de PIP de uma atividade. Se a atividade estiver no modo PIP, 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, independente do métodoenterPictureInPictureMode()
chamado.
Notificações
No Android 8.0 (API de nível 26), reformulamos as notificações para oferecer uma maneira mais fácil e consistente de gerenciar o comportamento e as configurações das notificações. Estas alterações incluem:
- Canais de notificação: o Android 8.0 apresenta canais de notificação que permitem criar um canal personalizável pelo usuário para cada tipo de notificação que você quer exibir. A interface do usuário se refere aos canais de notificação como categorias de notificação. Para saber como implementar canais de notificação, consulte Como gerenciar canais de notificação.
- Pontos de notificação: o Android 8.0 introduz o suporte à exibição de pontos ou selos em ícones na tela de início do app. Os pontos de notificação refletem a presença de notificações que o usuário ainda não dispensou ou realizou. Para saber como trabalhar com pontos de notificação, consulte Indicadores de notificação.
- Soneca: os usuários podem adiar as notificações, o que faz com que elas desapareçam por um período antes de reaparecerem. As notificações reaparecem com o mesmo nível de importância com que apareceram pela primeira vez. Os apps podem remover ou atualizar uma notificação adiada, mas isso não faz com que ela reapareça.
- Tempos limite de notificação: você pode definir um tempo limite ao criar uma notificação usando
setTimeoutAfter()
. Use esse método para especificar um período após o qual uma notificação precisa ser cancelada. Se necessário, você pode cancelar uma notificação antes do término do tempo limite especificado. - Configurações de notificação: você pode chamar
setSettingsText()
para definir o texto que aparece ao criar um link para as configurações de notificação do seu app usando a intentNotification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES
. O sistema pode fornecer os seguintes extras com a intent de filtrar as configurações que o app precisa mostrar aos usuários:EXTRA_CHANNEL_ID
,NOTIFICATION_TAG
eNOTIFICATION_ID
. - Dispensa de notificações: os usuários podem dispensar notificações e
os apps podem removê-las de forma programática. Você pode determinar quando uma notificação
é dispensada e por que ela foi dispensada implementando o
método
onNotificationRemoved()
da classeNotificationListenerService
. - Cores de plano de fundo: você pode definir e ativar uma cor de plano de fundo para uma notificação. Use esse recurso apenas em notificações de
tarefas em andamento que são essenciais para o usuário ver rapidamente. Por exemplo, você pode definir uma cor de fundo para notificações relacionadas a rotas de carro ou a uma chamada telefônica em andamento. Você também pode definir a
cor de fundo desejada usando
setColor()
. Isso permite que você usesetColorized()
para ativar o uso de uma cor de plano de fundo para uma notificação. - Estilo de mensagens: no Android 8.0, as notificações que usam a classe
MessagingStyle
exibem mais conteúdo na forma recolhida. Use a classeMessagingStyle
para notificações relacionadas a mensagens. Você também pode usar o métodoaddHistoricMessage()
para fornecer contexto a uma conversa, adicionando mensagens históricas a notificações relacionadas a mensagens.
Estrutura de preenchimento automático
A criação de contas, o login e as transações de cartão de crédito são demoradas e propensas a erros. Os usuários podem se frustrar facilmente com apps que exigem esses tipos de tarefas repetitivas.
O Android 8.0 (nível 26 da API) facilita o preenchimento de formulários, como de login e de cartão de crédito, com a introdução da estrutura de preenchimento automático. Apps novos e atuais funcionam com o Estrutura de preenchimento automático depois que o usuário ativa o preenchimento automático.
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.
Fontes para download
O Android 8.0 (API de nível 26) e a Biblioteca de Suporte 26 do Android permitem solicitar fontes de um aplicativo do provedor em vez de agrupar fontes no APK ou permitir que o APK faça o download de fontes. Esse recurso reduz o tamanho do APK, aumenta a taxa de sucesso da instalação do app e permite que vários apps compartilhem a mesma fonte.
Para mais informações sobre como fazer o download de fontes, consulte Fontes para download.
Fontes em XML
O Android 8.0 (nível 26 da API) introduz um novo recurso, o "Fontes em XML", que
permite usar fontes como recursos. Isso significa que não é necessário agrupar fontes
como recursos. As fontes são compiladas em um arquivo R
e ficam disponíveis
automaticamente no sistema como um recurso. É possível acessar essas fontes com
ajuda de um novo tipo de recurso, font
.
A Biblioteca de Suporte 26 oferece suporte total a esse recurso em dispositivos com a API 14 ou mais recentes.
Para saber mais sobre o uso de fontes como recursos e como extrair fontes do sistema, consulte Fontes em XML.
Dimensionamento automático do TextView
O Android 8.0 (nível 26 da API) permite definir o tamanho da expansão ou contração do texto automaticamente com base no tamanho da TextView. Isso significa que é muito mais fácil otimizar o tamanho do texto em diferentes telas ou com conteúdo dinâmico. Para saber mais sobre o dimensionamento automático da TextView no Android 8.0, consulte Dimensionamento automático da TextView.
Ícones adaptativos
O Android 8.0 (API de nível 26) introduz ícones adaptativos na tela de início. Os ícones adaptativos têm suporte a efeitos visuais e podem mostrar uma variedade de formas em diferentes modelos de dispositivos. Para aprender a criar ícones adaptativos, consulte o guia Ícones adaptativos.
Gerenciamento de cores
Os desenvolvedores Android de apps de imagens agora podem aproveitar os novos dispositivos que têm uma tela compatível com uma ampla gama de cores. Para exibir imagens de ampla gama, os apps precisam ativar uma flag no manifesto (por atividade) e carregar bitmaps com um perfil de cores amplo incorporado (AdobeRGB, Pro Photo RGB, DCI-P3 etc.).
WebView APIs
O Android 8.0 oferece várias APIs para ajudar você a gerenciar
os objetos WebView
que exibem conteúdo da Web no app.
Essas APIs, que melhoram a estabilidade e a segurança do app, incluem:
- API Version
- Google SafeBrowsing API
- Termination Handle API
- API Renderer Importance
Para saber mais sobre como usar essas APIs, consulte Gerenciar WebViews.
A classe WebView
agora inclui uma API Safe Browsing para melhorar a segurança
da navegação na Web. Para mais informações, consulte
API Google Safe Browsing.
Fixação de atalhos e widgets
O Android 8.0 (API de nível 26) introduz a fixação de atalhos e widgets no app. No seu app, você pode criar atalhos e widgets fixados para telas de início compatíveis, dependendo da permissão do usuário.
Para saber mais, consulte o guia de recursos Fixar atalhos e widgets.
Proporção máxima da tela
O Android 8.0 (API de nível 26) traz mudanças na forma de configurar a proporção máxima de um app.
Primeiro, o Android 8.0 introduz o atributo maxAspectRatio, que você pode usar para definir a proporção máxima do seu app. Além disso, no Android 8.0 e versões mais recentes, a proporção máxima padrão de um app é a proporção nativa do dispositivo em que o app está sendo executado.
Para mais informações sobre como declarar a proporção máxima, consulte Suporte a várias telas.
Suporte a várias telas
A partir do Android 8.0 (nível 26 da API), a plataforma oferece suporte avançado a várias telas. Se uma atividade oferece suporte ao modo de várias janelas e está sendo executada em um dispositivo com várias telas, os usuários podem mover a atividade de uma tela para outra. Quando um app inicia uma atividade, ele pode especificar em qual tela a atividade precisa ser executada.
Observação : se uma atividade oferece suporte ao modo de várias janelas, o Android 8.0 ativa automaticamente o suporte a várias telas. Teste seu app para garantir que ele funcione corretamente em um ambiente com várias telas.
Apenas uma atividade por vez pode estar no estado retomado, mesmo que o app tenha várias telas. A atividade em foco fica no estado retomado. Todas as outras atividades visíveis ficam pausadas, mas não interrompidas. Para mais informações sobre o ciclo de vida da atividade quando várias atividades estiverem visíveis, consulte Ciclo de vida de várias janelas.
Quando um usuário move uma atividade de uma tela para outra, o sistema redimensiona a atividade e emite mudanças no ambiente de execução conforme necessário. Sua atividade pode processar a mudança de configuração por conta própria ou permitir que o sistema destrua o processo que contém a atividade e a recrie com as novas dimensões. Para saber mais, consulte Gerenciar mudanças de configuração.
ActivityOptions
oferece dois novos métodos para compatibilidade com várias telas:
setLaunchDisplayId()
- Especifica em qual tela a atividade precisa ser mostrada quando iniciada.
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 (nível 26 da API) facilita a especificação de situações em que lados opostos
de um elemento View
usam a mesma margem ou padding.
Especificamente, agora você pode usar os seguintes atributos nos 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 app 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ê pode definir esses valores, além dos
novos atributos de layout vertical e horizontal, para criar um comportamento de layout
que depende da direção do texto.
Captura de ponteiro
Alguns apps, como jogos, área de trabalho remota e clientes de virtualização, se beneficiam muito de ter o controle sobre o ponteiro do mouse. A captura de ponteiro é um novo recurso do Android 8.0 (nível 26 da API) que oferece esse controle enviando todos os eventos do mouse para uma visualização focada no app.
A partir do Android 8.0, uma View
no app pode solicitar
a captura de ponteiro e definir um listener para processar eventos de ponteiro capturados. O
ponteiro do mouse fica oculto nesse modo. A visualização poderá liberar a captura do ponteiro
quando não precisar mais das informações do mouse. O sistema também pode liberar
a captura de ponteiro quando a visualização perder o foco, por exemplo, quando o usuário abrir
outro app.
Para mais informações sobre como usar esse recurso no seu app, consulte Captura de ponteiro.
Categorias de apps
O Android 8.0 (nível 26 da API) permite que cada app declare uma categoria adequada, quando relevante. Essas categorias são usadas para agrupar apps de finalidade ou função
semelhante quando apresentados aos usuários, como uso de dados, uso da bateria ou
uso do armazenamento. É possível definir uma categoria para o app definindo o
atributo android:appCategory
na tag de manifesto
<application>
.
Inicializador do Android TV
O Android 8.0 (nível 26 da API) inclui uma nova experiência da tela inicial do Android TV com foco em conteúdo, que está disponível com o emulador do Android TV e a imagem do dispositivo Nexus Player para o Android 8.0. A nova tela inicial organiza o conteúdo de vídeo em linhas correspondentes aos canais, cada uma preenchida com programas por um app no sistema. Os apps podem publicar vários canais, e os usuários podem configurar quais canais querem ver na tela inicial. A tela inicial do Android TV também inclui uma linha "Assistir a seguir", que é preenchida com programas de apps, com base nos hábitos de visualização do usuário. Os apps também podem oferecer prévias de vídeo, que são reproduzidas automaticamente quando um usuário foca em um programa. As APIs para preencher canais e programas fazem parte das APIs TvProvider, que são distribuídas como um módulo da Biblioteca de Suporte Android com o Android 8.0.
AnimatorSet
No Android 8.0 (nível 26 da API) e versões mais recentes, a API AnimatorSet
agora oferece suporte à busca e à reprodução
ao contrário. A busca permite definir a posição da animação definida em um ponto
específico. A reprodução ao contrário é útil se o app inclui 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 no seu app usa uma hierarquia de visualização complexa, como a da Figura 2, considere organizar grupos de elementos da interface em clusters para facilitar a navegação pelo teclado entre eles. Os usuários podem pressionar Meta+Tab ou Search+Tab nos dispositivos Chromebook para navegar de um cluster a outro. Bons exemplos de clusters incluem: painéis laterais, barras de navegação, principais áreas de conteúdo e elementos que podem conter muitos elementos filhos.
Para transformar um elemento View
ou ViewGroup
em um cluster, defina o atributo
android:keyboardNavigationCluster
como
true
no arquivo XML de layout do elemento ou transmita true
para setKeyboardNavigationCluster()
na lógica da interface do app.
Observação: os clusters não podem ser aninhados, embora os clusters não aninhados possam aparecer em níveis diferentes da hierarquia. Se você tentar
aninhar clusters, o framework tratará apenas o elemento ViewGroup
superior como um cluster.
Em dispositivos que têm tela touchscreen, é possível definir o elemento android:touchscreenBlocksFocus
de um objeto
ViewGroup
designado por um cluster como true
para
permitir a navegação somente de entrada e saída do cluster. Se você aplicar essa
configuração a um cluster, os usuários não poderão usar a tecla Tab ou de seta para
entrar ou sair do cluster. Em vez disso, eles precisarão pressionar a combinação de teclado de
navegação em cluster.
Foco padrão da vista
No Android 8.0 (nível 26 da API), é possível atribuir a View
que precisa
receber foco depois que uma atividade (re)criada é retomada e o usuário pressiona uma
tecla de navegação, como a tecla Tab. Para aplicar essa configuração de "foco por padrão",
defina o atributo
android:focusedByDefault
de um elemento View
como true
no
arquivo XML do layout que contém o elemento da interface ou transmita true
para
setFocusedByDefault()
na
lógica da interface do seu app.
Saída de voz
Atividades e serviços podem usar instâncias de
TextToSpeech
para ditar e pronunciar conteúdo. A partir do
Android 8.0 (nível 26 da API), seu app pode receber informações de tempo mais precisas
sobre quando um mecanismo de conversão de texto em voz começa a falar palavras sintetizadas individuais,
desde que o mecanismo forneça essas informações. Você pode usar essa funcionalidade
para chamar a atenção para palavras específicas à medida que o mecanismo de conversão de texto em voz
as fala.
Para usar essas melhorias no mecanismo de conversão de texto em voz no seu app, registre uma
instância de UtteranceProgressListener
. Como parte do
processo de registro, inclua um gerenciador para o
método
onRangeStart()
.
O mecanismo de conversão de texto em voz chama
rangeStart()
para gravar
o momento em que espera que a reprodução de áudio de um intervalo específico de texto
seja iniciada. Quando o áudio desse intervalo de texto inicia a reprodução, o método
onRangeStart()
do app é executado. Seu app poderá responder a esse callback, por exemplo,
destacando o intervalo de texto associado ao enunciado.
Para mais informações sobre como rastrear o progresso da reprodução de um mecanismo de conversão de texto
em voz, consulte a referência da classe
UtteranceProgressListener
.
Sistema
Novos detectores de StrictMode
O Android 8.0 (nível 26 da API) adiciona três novos detectores de StrictMode para ajudar a identificar possíveis bugs no seu app:
- O
detectUnbufferedIo()
detecta quando o app lê ou grava dados sem armazenamento em buffer, o que pode afetar consideravelmente o desempenho. - O
detectContentUriWithoutPermission()
vai detectar quando seu app acidentalmente se esquecer de conceder permissões a outro app ao iniciar uma atividade fora do app. - O
detectUntaggedSockets()
vai detectar quando o app realizar tráfego de rede sem usarsetThreadStatsTag(int)
para marcar o tráfego para fins de depuração.
Dados em cache
O Android 8.0 (API de nível 26) oferece melhores orientações e comportamentos sobre dados armazenados em cache. Cada
app agora recebe uma cota de espaço em disco para dados em cache, conforme retornado por
getCacheQuotaBytes(UUID)
.
Quando o sistema precisar liberar espaço em disco, ele vai começar excluindo arquivos em cache dos apps que estão mais acima da cota alocada. Assim, se você mantiver os dados armazenados em cache abaixo da cota alocada, os arquivos armazenados em cache serão alguns dos últimos no sistema a serem apagados quando necessário. Quando o sistema está decidindo quais arquivos armazenados em cache excluir no app, ele considera primeiro os arquivos mais antigos (conforme determinado pelo tempo modificado).
Há também dois novos comportamentos que podem ser ativados por diretório para controlar como o sistema libera os dados em cache:
StorageManager.setCacheBehaviorAtomic()
pode ser usado para indicar que um diretório e todo o conteúdo dele precisam ser excluídos como uma única unidade atômica.setCacheBehaviorTombstone(File, boolean)
pode ser usado para indicar que, em vez de excluir arquivos dentro de um diretório, eles precisam ser truncados para ter 0 bytes de comprimento, deixando o arquivo vazio intacto.
Por fim, quando você precisar alocar espaço em disco para arquivos grandes, use a nova API
allocateBytes(FileDescriptor, long)
, que vai limpar automaticamente
os arquivos em cache pertencentes a outros apps (conforme 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()
, já que o primeiro considera todos os dados
armazenados em cache que o sistema está disposto a limpar para você.
Paginação do provedor de conteúdo
Atualizamos os provedores de conteúdo para incluir a compatibilidade com o carregamento de um conjunto de dados grande, uma página por vez. Por exemplo, um app de fotos com muitos milhares de imagens pode consultar um subconjunto dos dados para apresentar em uma página. Cada página de resultados retornada por um provedor de conteúdo é representada por um único objeto Cursor. Tanto o cliente quanto o provedor precisam implementar a paginação para usar esse recurso.
Para informações detalhadas sobre as mudanças nos provedores de conteúdo, consulte
ContentProvider
e
ContentProviderClient
.
Solicitações de atualização de conteúdo
As classes ContentProvider
e
ContentResolver
agora incluem um
método refresh()
, tornando mais fácil para os clientes saberem se
as informações que solicitaram estão atualizadas.
Você pode adicionar uma lógica personalizada de atualização de conteúdo estendendo
ContentProvider
. Modifique o método
refresh()
para retornar
true
, indicando aos clientes do provedor que você tentou
atualizar os dados.
O app cliente pode solicitar conteúdo atualizado explicitamente chamando um
método diferente, também chamado de
refresh()
. Ao chamar esse
método, transmita o URI dos dados a serem atualizados.
Observação:como você pode estar solicitando dados em uma rede,
invoque refresh()
no
lado do cliente somente quando houver uma forte indicação de que o conteúdo está desatualizado.
O motivo mais comum para realizar esse tipo de atualização de conteúdo é em resposta a
um gesto de deslizar para atualizar, solicitando explicitamente que a interface atual mostre conteúdo atualizado.
Melhorias no JobScheduler
O Android 8.0 (API de nível 26) introduz diversas melhorias para o JobScheduler
. Essas melhorias facilitam a conformidade do app
com os novos limites de execução
em segundo plano, já que geralmente é possível usar jobs programados para substituir
os serviços em segundo plano agora restritos ou broadcast receivers 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 processa muitos dos casos de uso que anteriormente exigiam a inicialização de um serviço em segundo plano, principalmente serviços que implementamIntentService
. -
A Biblioteca de Suporte do Android 26.0.0 introduz uma nova classe
JobIntentService
, que fornece a mesma funcionalidade queIntentService
, mas usa jobs em vez de serviços ao executar no Android 8.0 (nível 26 da API) ou versões mais recentes. -
Agora é possível chamar
JobInfo.Builder.setClipData()
para associar umClipData
a um job. Essa opção permite associar concessões de permissão de URI a um job, da mesma forma que essas permissões podem ser propagadas paraContext.startService()
. Também é possível usar concessões de permissões de URI com intents em filas de trabalho. -
Os jobs programados agora oferecem suporte a várias novas restrições:
JobInfo.isRequireStorageNotLow()
- O job não será executado se o armazenamento disponível no dispositivo estiver baixo.
JobInfo.isRequireBatteryNotLow()
- O job não será executado se o nível da bateria estiver no limite crítico ou abaixo dele. Esse é o nível em que o dispositivo mostra a caixa de diálogo Aviso de bateria fraca.
NETWORK_TYPE_METERED
- O job requer uma conexão de rede limitada, como a maioria dos planos de dados móveis.
Repositório de dados personalizado
O Android 8.0 (API de nível 26) permite disponibilizar um armazenamento de dados personalizado para suas preferências, o que pode ser útil se o app armazenar as preferências em um banco de dados local ou na nuvem ou se as preferências forem específicas do dispositivo. Para mais informações sobre como implementar o repositório de dados, consulte Repositório de dados personalizado.
Aprimoramentos de mídia
VolumeShaper
Há uma nova classe VolumeShaper
. Use-o
para realizar transições de volume curtas automatizadas, como fade-ins, fade-outs e cross fades.
Consulte Como controlar a amplitude com o VolumeShaper
para saber mais.
Melhorias na seleção de á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
. Ao usar essa classe como o parâmetro de
requestAudioFocus()
,
os apps têm novas capacidades ao processar mudanças na seleção de áudio:
redução automática e
ganho de seleção 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 um 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 permanecem durante o ciclo 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
No Android 8.0 (nível 26 da API) e versões mais recentes, o MediaPlayer pode reproduzir materiais protegidos por DRM e mídia criptografada no nível de amostra HLS.
O Android 8.0 introduz um novo comando
seekTo()
sobrecarregado que fornece controle
refinado ao procurar um frame. Ela inclui um segundo parâmetro que especifica um modo de busca:
SEEK_PREVIOUS_SYNC
move a posição da mídia para um frame de sincronização (ou chave) associado a uma fonte de dados localizada logo antes ou no momento especificado.SEEK_NEXT_SYNC
move a posição da mídia para um frame de sincronização (ou chave) associado a uma fonte de dados localizada logo após ou no momento especificado.SEEK_CLOSEST_SYNC
move a posição da mídia para um frame de sincronização (ou chave) associado a uma fonte de dados localizada mais próxima ou no momento especificado.- O
SEEK_CLOSEST
move a posição da mídia para um frame (não necessariamente uma sincronização ou um frame-chave) associado a uma fonte de dados localizada mais perto ou no momento especificado.
Ao buscar continuamente, os apps precisam usar qualquer um dos modos SEEK_
em vez do SEEK_CLOSEST
, que é relativamente mais lento, mas pode ser mais preciso.
MediaRecorder
- O MediaRecorder agora é compatível com o formato MPEG2_TS, que é útil para
streaming:
Kotlin
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS)
Java
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS);
- O
MediaMuxer
agora pode processar qualquer número de streams de áudio e vídeo. Você não está mais limitado a uma faixa de áudio e/ou uma 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 processamento off-line. 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 precisa começar com o prefixo
"application/". A criação de metadados é igual à gravação de dados de vídeo/áudio, exceto
que os dados não vêm de um MediaCodec
. Em vez disso, o app transmite um
ByteBuffer
com um carimbo de data/hora associado ao
método writeSampleData()
.
O carimbo de data/hora precisa estar na mesma base de tempo que as faixas de vídeo e áudio.
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 faixa de metadados, o formato MIME dos metadados será extraído para MediaFormat
.
Acesso melhorado a arquivos de mídia
O
framework de acesso ao armazenamento (SAF, na sigla em inglês) permite que os apps exponham um
DocumentsProvider
personalizado, que pode fornecer acesso a arquivos
em uma fonte de dados para outros apps. Na verdade, um
provedor de documentos pode até fornecer acesso a arquivos
que residem no armazenamento em rede ou que usam um protocolo como o
Protocolo de transferência de mídia (MTP, na sigla em inglês).
No entanto, o acesso a arquivos de mídia grandes de uma fonte de dados remota apresenta alguns desafios:
- Media players exigem acesso com busca a um arquivo de um provedor de documentos. Nos casos em que um arquivo de mídia grande reside em uma fonte de dados remota, o provedor de documentos precisa buscar todos os dados antecipadamente e criar um descritor do arquivo de snapshot. O player de mídia não pode reproduzir o arquivo sem o descritor do arquivo. Portanto, a reprodução não pode começar até que o provedor de documentos termine de fazer o download do arquivo.
- Os gerenciadores de coleta de mídia, como apps de fotos, precisam passar por uma série de URIs para acessar a mídia armazenada em um cartão SD externo por pastas com escopo. Esse padrão de acesso torna as operações em massa na mídia muito lentas, como mover, copiar e excluir.
- Os gerenciadores de coleta de mídia não podem determinar o local de um documento dado o URI dele. Isso dificulta que esses tipos de apps permitam que os usuários escolham onde salvar um arquivo de mídia.
O Android 8.0 aborda cada um desses desafios melhorando o framework de acesso ao armazenamento.
Provedores de documentos personalizados
A partir do Android 8.0, o Framework de acesso ao armazenamento permite que provedores de documentos personalizados criem descritores de arquivos com busca para arquivos que residem em uma fonte de dados remota. A SAF pode abrir um arquivo para receber um descritor de arquivo pesquisável nativo. Em seguida, o SAF 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 app de player de mídia solicitou, 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 o 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 (nível 26 da API), é possível usar o
método getDocumentUri()
para
receber um URI que se refere ao mesmo documento que o mediaUri
fornecido.
No entanto, como o URI retornado tem o suporte de um
DocumentsProvider
, os gerenciadores de coleta de mídia podem acessar
o documento diretamente, sem precisar passar por árvores de diretórios com escopo.
Como resultado, os gerenciadores de mídia podem realizar operações de arquivos no documento
de maneira significativamente mais rápida.
Cuidado:o método getDocumentUri()
localiza apenas arquivos de mídia. Ele não concede aos apps
permissão para acessar esses arquivos. Para saber mais sobre como conseguir permissão
de acesso a arquivos de mídia, consulte a documentação de referência.
Caminhos para documentos
Ao usar o framework de acesso ao armazenamento no Android 8.0 (nível 26 da API), você pode usar o método
findDocumentPath()
, disponível nas classes
DocumentsContract
e
DocumentsProvider
,
para determinar o caminho da raiz de um sistema de arquivos, considerando o ID de um
documento. O método retorna esse caminho em um
objeto DocumentsContract.Path
. Nos casos em que um sistema
de arquivos tem vários caminhos definidos para o mesmo documento, o método retorna o
caminho usado com mais frequência para acessar o documento com o ID fornecido.
Essa funcionalidade é particularmente útil nos seguintes cenários:
- Seu app usa uma caixa de diálogo "salvar como" que exibe a localização de um documento específico.
- O app mostra pastas em uma visualização de resultados da pesquisa e precisa carregar os documentos filhos que estão em uma pasta específica caso o usuário a selecione.
Observação:caso seu app tenha permissão para acessar apenas alguns dos documentos
no caminho, o valor de retorno de findDocumentPath()
vai incluir apenas
as pastas e os documentos que ele pode acessar.
Monitoramento da reprodução de áudio
O serviço do sistema AudioManager
mantém uma lista de
objetos AudioPlaybackConfiguration
ativos, cada um
contendo informações sobre uma sessão específica de reprodução de áudio. Seu app pode
recuperar o conjunto de configurações ativas no momento chamando
getActivePlaybackConfigurations()
.
A partir do Android 8.0 (nível 26 da API), é possível registrar um callback que notifica
seu app quando um ou mais
objetos AudioPlaybackConfiguration
mudam. Para fazer isso,
chame registerAudioPlaybackCallback()
, transmitindo uma instância de
AudioManager.AudioPlaybackCallback
. A
classe AudioManager.AudioPlaybackCallback
contém o
método onPlaybackConfigChanged()
, que o sistema chama quando a configuração de
reprodução de áudio muda.
Conectividade
Wi-Fi Aware
O Android 8.0 (API de nível 26) adiciona suporte ao Wi-Fi Aware, que é baseado na especificação Rede de Reconhecimento de Vizinhos (NAN, na sigla em inglês). Em dispositivos com o hardware Wi-Fi Aware apropriado, apps e dispositivos próximos podem descobrir e se comunicar 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 o mais rápido possível. Para saber mais sobre como integrar o Wi-Fi Aware ao seu app, consulte Wi-Fi Aware.
Bluetooth
O Android 8.0 (API de nível 26) enriquece o suporte a Bluetooth da plataforma adicionando 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 (API de nível 26) oferece APIs que permitem personalizar a caixa de diálogo de solicitação de pareamento ao tentar parear com dispositivos complementares por Bluetooth, BLE e Wi-Fi. Para mais informações, consulte Pareamento de dispositivos complementares.
Para mais informações sobre como usar o Bluetooth no Android, consulte o guia Bluetooth. Para mudanças no Bluetooth específicas do Android 8.0 (nível 26 da API), consulte a seção Bluetooth da página Mudanças de comportamento do Android 8.0.
Compartilhamento
Compartilhamento inteligente
O Android 8.0 (API de nível 26) aprende sobre as preferências de compartilhamento personalizadas dos usuários e entende melhor cada tipo de conteúdo com que os apps corretos podem ser compartilhados. Por exemplo, se um usuário tirar uma foto de um recibo, o Android 8.0 poderá sugerir um app de monitoramento de despesas. Se o usuário tirar uma selfie, um app de mídias sociais poderá processar melhor a imagem. O Android 8.0 aprende automaticamente 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 um ArrayList
de até três
anotações de string à intent que compartilha o conteúdo. As anotações precisam
descrever os principais componentes ou tópicos do conteúdo. O exemplo de código a seguir
mostra como adicionar anotações à intent:
Kotlin
val annotations: ArrayList<String> = arrayListOf( "topic1", "topic2", "topic3" ) intent.putStringArrayListExtra( Intent.EXTRA_CONTENT_ANNOTATIONS, annotations )
Java
ArrayList<String> annotations = new ArrayList<>(); annotations.add("topic1"); annotations.add("topic2"); annotations.add("topic3"); intent.putStringArrayListExtra( Intent.EXTRA_CONTENT_ANNOTATIONS, annotations );
Para informações detalhadas sobre as anotações de compartilhamento inteligente, consulte
EXTRA_CONTENT_ANNOTATIONS
.
Classificador de texto
Em dispositivos compatíveis, os apps podem usar um novo classificador de texto para verificar se uma
string corresponde a um tipo de entidade de classificador conhecido e receber sugestões de alternativas
de seleção. Entidades reconhecidas pelo sistema incluem endereços, URLs,
números de telefone e endereços de e-mail. Para mais informações, consulte
TextClassifier
.
Acessibilidade
O Android 8.0 (nível 26 da API) oferece suporte a vários novos recursos de acessibilidade para desenvolvedores que criam os próprios serviços:
- Uma nova categoria de volume para ajustar o volume de acessibilidade.
- Gestos de impressão digital como um mecanismo de entrada.
- Recursos de conversão de texto em voz multilíngue.
- Um atalho de acessibilidade baseado em hardware para acessar rapidamente um serviço de acessibilidade preferido.
- Suporte a gestos contínuos ou sequências programáticas de traços.
- Um botão de acessibilidade para invocar um dos vários recursos de acessibilidade ativados (disponível apenas em dispositivos que usam uma área de navegação renderizada por software).
- Valores padronizados de intervalo unilateral.
- Diversos recursos para processar texto com mais facilidade, incluindo texto de dica e locais de caracteres de texto na tela.
Segurança e privacidade
Permissões
O Android 8.0 (API de nível 26) introduz várias novas permissões relacionadas à telefonia:
- A permissão
ANSWER_PHONE_CALLS
permite que o app atenda chamadas telefônicas de forma programática. Para processar uma chamada telefônica recebida no seu app, você pode usar o métodoacceptRingingCall()
. - A permissão
READ_PHONE_NUMBERS
concede ao app acesso de leitura aos números de telefone armazenados em um dispositivo.
Essas permissões são classificadas como
perigosas
e fazem parte do grupo de permissões
PHONE
.
Novas APIs de acesso e descoberta de contas
O Android 8.0 (API de nível 26) introduz várias melhorias no modo como os apps têm acesso a contas de usuário. Para as contas que gerenciam, os autenticadores podem usar a própria política para decidir se querem ocultar ou revelar contas para um app. O sistema Android rastreia aplicativos que podem acessar uma conta específica.
Nas versões anteriores do Android, os apps que queriam rastrear a lista de contas de usuário tinham que receber atualizações sobre todas as contas, incluindo 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 os apps especifiquem uma lista de tipos de conta
para os quais as mudanças precisam ser recebidas.
Mudanças na API
O AccountManager oferece seis novos métodos para ajudar os autenticadores a gerenciar quais apps podem ver uma conta:
setAccountVisibility(android.accounts.Account, java.lang.String, int)
: define o nível de visibilidade de uma combinação específica de conta de usuário e pacote.-
getAccountVisibility(android.accounts.Account, java.lang.String)
: recebe 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 recebam as contas e os níveis de visibilidade de um determinado pacote. -
getPackagesAndVisibilityForAccount(android.accounts.Account)
: permite que autenticadores recebam valores de visibilidade armazenados para uma determinada conta. -
addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.String, java.lang.Integer>)
: permite que os autenticadores inicializem os valores de visibilidade de uma conta. -
addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[])
: adiciona um listenerOnAccountsUpdateListener
ao objetoAccountManager
. O sistema chama esse listener sempre que a lista de contas no dispositivo muda.
O Android 8.0 (nível 26 da API) introduz dois valores de nome de pacote especiais 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 apps que têm a permissão
GET_ACCOUNTS
e versões de destino do
Android anteriores à 8.0 ou com
assinaturas que correspondem ao autenticador destinado a qualquer versão do Android.
PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE
fornece um valor de visibilidade padrão para
apps que não foram definidos anteriormente e para os quais
PACKAGE_NAME_KEY_LEGACY_VISIBLE
não é
aplicável.
Para mais informações sobre as novas APIs de acesso e descoberta de contas, consulte a
referência de
AccountManager
e
OnAccountsUpdateListener
.
Testes
Teste de instrumentação
O Android 8.0 (nível 26 da API) oferece as seguintes partes de suporte extra para os testes de instrumentação do seu app.
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 fora do processo padrão do app. Essa configuração é útil se o app contém várias atividades executadas em diferentes processos.
Para definir a instrumentação de processo não padrão, navegue até o arquivo de
manifesto e, em seguida, até o elemento
<instrumentation>
desejado. Adicione o
atributo android:targetProcess
e defina o valor dele como uma
destas opções:
- 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 está em execução, é possível verificar qual processo
ele está testando chamando getProcessName()
.
Relatar resultados durante um teste
Agora é possível relatar os resultados durante a execução do teste de instrumentação,
em vez de depois, chamando addResults()
.
Intents simulados para testes
Para facilitar a criação de testes de interface isolados e independentes para as atividades
do app, o Android 8.0 (API de nível 26) introduz o
método onStartActivity()
. Modifique esse método em uma subclasse personalizada da
classe Instrumentation.ActivityMonitor
para processar uma intent
específica invocada pela classe de teste.
Quando sua classe de teste invoca a intent, o método retorna um objeto
Instrumentation.ActivityResult
de stub em vez de executar
a intent em si. Ao usar essa lógica de intent simulada nos seus testes, você pode se concentrar
em como a atividade prepara e processa a intent transmitida para uma
atividade diferente ou para um app totalmente diferente.
Ambiente de execução e ferramentas
Otimizações de plataforma
O Android 8.0 (nível 26 da API) leva à plataforma o ambiente de execução e outras otimizações, resultando em diversas melhorias na performance. Essas otimizações incluem a coleta de lixo com compactação simultânea, uso mais eficiente da memória e localidade do código.
Essas otimizações resultam em tempos de inicialização mais rápidos, além de melhor desempenho no SO e nos apps.
Compatibilidade com a linguagem Java atualizada
O Android 8.0 (API de nível 26) adiciona suporte a várias outras APIs OpenJDK Java:
java.time
do OpenJDK 8.java.nio.file
ejava.lang.invoke
do OpenJDK 7.
Para saber mais sobre as classes e os métodos nesses pacotes recém-adicionados, consulte a documentação de referência da API.
Se você quiser usar os recursos da linguagem Java 8 no Android Studio, faça o download da versão de pré-lançamento mais recente.
ICU4J Android Framework APIs atualizadas
O Android 8.0 (nível 26 da API) estende as
APIs ICU4J do framework
Android, que são um subconjunto das APIs ICU4J, para desenvolvedores de apps
usarem no pacote android.icu
. Essas APIs usam dados de localização
presentes no dispositivo para que você possa reduzir o tamanho do APK ao não compilar as
bibliotecas ICU4J nele.
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 (API de nível 26) | 58.2 | 30.0.3 | 9.0 |
Para mais informações sobre internacionalização no Android, incluindo suporte a ICU4J, consulte Internacionalização no Android (link em inglês).
Android empresarial
Novos recursos e APIs empresariais foram introduzidos para dispositivos que executam o Android 8.0 (nível 26 da API). Os destaques incluem:
- Perfis de trabalho em dispositivos totalmente gerenciados permitem que as empresas separem os dados profissionais dos pessoais enquanto gerenciam ambos.
- A delegação de API permite que os proprietários de dispositivos e de perfis atribuam gerenciamento de apps 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. Os registros de atividade de rede ajudam as empresas a identificar problemas.
Para saber mais sobre esses e outros novos recursos e APIs para empresas do Android, consulte Android no Enterprise.