O Android 8.1 (nível da API 27) apresenta vários recursos e funcionalidades novos para usuários e desenvolvedores. Este documento destaca as novidades para os desenvolvedores.
Android Oreo (versão Go)
O Android Go é nossa iniciativa para otimizar a experiência do Android para bilhões de pessoas que estão entrando on-line no mundo todo. A partir do Android 8.1, o Android se tornou uma ótima plataforma para dispositivos básicos. Os recursos na configuração do Android Oreo (versão Go) incluem:
- Otimizações de memória. Melhoria no uso da memória em toda a plataforma para garantir que os apps possam ser executados com eficiência em dispositivos com 1 GB ou menos de RAM.
- Opções de segmentação flexíveis. Novas constantes de recursos de hardware para permitir que você direcione a distribuição dos apps para dispositivos com RAM normal ou baixa pelo Google Play.
- Google Play: todos os apps vão estar disponíveis em dispositivos com o Android Oreo (versão Go), mas o Google Play vai dar visibilidade aos apps otimizados especificamente pelos desenvolvedores para oferecer uma ótima experiência a bilhões de pessoas com as diretrizes (link em inglês).
Atualizamos as diretrizes do programa "Building for Billions" com mais orientações sobre como otimizar seu app para dispositivos que usam o Android Oreo (versão Go). Para a maioria dos desenvolvedores, otimizar o APK atual ou usar o recurso de vários APKs do Google Play para direcionar uma versão do APK a dispositivos com pouca RAM é a melhor maneira de se preparar para dispositivos com o Android Oreo (edição Go). Lembre-se de que tornar seu app mais leve e eficiente beneficia todo o público, independente do dispositivo.
API Neural Networks
A API Neural Networks oferece computação e inferência aceleradas para frameworks de aprendizado de máquina no dispositivo, como o TensorFlow Lite, a biblioteca de ML multiplataforma do Google para dispositivos móveis, além do Caffe2 e outros. Acesse o repositório de código aberto do TensorFlow Lite para downloads e documentação. O TensorFlow Lite funciona com a API Neural Networks para executar modelos como MobileNets, Inception v3 e Respostas inteligentes de maneira eficiente no seu dispositivo móvel.
Atualizações do framework de preenchimento automático
O Android 8.1 (nível 27 da API) oferece várias melhorias na Estrutura de preenchimento automático que podem ser incorporadas aos seus apps.
A classe BaseAdapter
agora inclui o método setAutofillOptions(), que permite fornecer representações de string dos valores em um
adaptador. Isso é útil para controles de spinner que geram dinamicamente os valores nos adaptadores. Por exemplo,
você pode usar o método setAutofillOptions() para fornecer uma representação de string
da lista de anos que os usuários podem escolher como parte de uma
data de validade do cartão de crédito. Os serviços de preenchimento automático podem usar a representação de string
para preencher adequadamente as visualizações que exigem os dados.
Além disso, a classe AutofillManager inclui o método notifyViewVisibilityChanged(View, int, boolean), que pode ser chamado para notificar a estrutura sobre mudanças na visibilidade de uma visualização em uma estrutura virtual. Há também uma sobrecarga do método para estruturas não
virtuais. No entanto, estruturas não virtuais geralmente não exigem que você
notifique explicitamente o framework porque o método já é chamado pela
classe
View.
O Android 8.1 também oferece aos serviços de preenchimento automático mais capacidade de personalizar a interface de salvamento
ao adicionar suporte para CustomDescription
and Validator
em SaveInfo.
As descrições personalizadas são úteis para ajudar o serviço de preenchimento automático a esclarecer o que está sendo salvo. Por exemplo, quando a tela contém um cartão de crédito, ela pode mostrar um logotipo do banco, os quatro últimos dígitos do número do cartão e a data de validade. Para saber mais, consulte a classe
CustomDescription.
Os objetos
Validator
são usados para evitar a exibição da interface de salvamento do preenchimento automático quando a condição do
Validator não é atendida. Para saber mais, consulte a classe
Validator e as subclasses
LuhnChecksumValidator e RegexValidator.
Notificações
O Android 8.1 inclui as seguintes alterações nas notificações:
- Os aplicativos agora só podem emitir sons de notificação uma vez por segundo. Sons de alerta que excedem essa taxa não são enfileirados e são perdidos. Essa mudança não afeta outros aspectos do comportamento das notificações, e as mensagens ainda são postadas como esperado.
-
NotificationListenerServiceeConditionProviderServicenão são compatíveis com dispositivos Android de baixa RAM que retornamtruequandoActivityManager.isLowRamDevice()é chamado.
Atualização do EditText
A partir do nível 27 da API, o método EditText.getText() retorna um Editable. Antes, ele retornava um CharSequence. Essa mudança é
compatível com versões anteriores, já que Editable implementa
CharSequence.
A interface Editable oferece funcionalidades adicionais valiosas. Por exemplo, como Editable também implementa a interface Spannable, é possível aplicar marcação ao conteúdo em uma instância de EditText.
Ações programáticas de navegação segura
Ao usar a
implementação WebView da API Navegação segura, seu app pode detectar quando uma instância de WebView tenta navegar até um URL que o Google classificou como uma ameaça conhecida. Por padrão, o
WebView mostra um intersticial que avisa os usuários sobre a ameaça conhecida.
Essa tela dá aos usuários a opção de carregar o URL mesmo assim ou voltar a uma página anterior segura.
No Android 8.1, é possível definir de forma programática como seu app responde a uma ameaça conhecida:
- Você pode controlar se o app informa ameaças conhecidas à Navegação segura.
- Você pode fazer com que seu app execute automaticamente uma ação específica, como voltar à segurança, sempre que encontrar um URL que a Navegação segura classifica como uma ameaça conhecida.
Observação:para ter uma proteção ideal contra ameaças conhecidas, aguarde
até inicializar a Navegação Segura antes de invocar o método loadUrl() de um objeto
WebView.
Os snippets de código a seguir mostram como instruir as instâncias do
WebView do app a sempre voltar à segurança depois de encontrar uma
ameaça conhecida:
AndroidManifest.xml
<manifest>
<application>
...
<meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
android:value="true" />
</application>
</manifest>MyWebActivity.java
Kotlin
private var superSafeWebView: WebView? = null private var safeBrowsingIsInitialized: Boolean = false // ... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) superSafeWebView = WebView(this).apply { webViewClient = MyWebViewClient() safeBrowsingIsInitialized = false startSafeBrowsing(this@SafeBrowsingActivity, { success -> safeBrowsingIsInitialized = true if (!success) { Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!") } }) } }
Java
private WebView superSafeWebView; private boolean safeBrowsingIsInitialized; // ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); superSafeWebView = new WebView(this); superSafeWebView.setWebViewClient(new MyWebViewClient()); safeBrowsingIsInitialized = false; superSafeWebView.startSafeBrowsing(this, new ValueCallback<Boolean>() { @Override public void onReceiveValue(Boolean success) { safeBrowsingIsInitialized = true; if (!success) { Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!"); } } }); }
MyWebViewClient.java
Kotlin
class MyWebViewClient : WebViewClient() { // Automatically go "back to safety" when attempting to load a website that // Safe Browsing has identified as a known threat. An instance of WebView // calls this method only after Safe Browsing is initialized, so there's no // conditional logic needed here. override fun onSafeBrowsingHit( view: WebView, request: WebResourceRequest, threatType: Int, callback: SafeBrowsingResponse ) { // The "true" argument indicates that your app reports incidents like // this one to Safe Browsing. callback.backToSafety(true) Toast.makeText(view.context, "Unsafe web page blocked.", Toast.LENGTH_LONG).show() } }
Java
public class MyWebViewClient extends WebViewClient { // Automatically go "back to safety" when attempting to load a website that // Safe Browsing has identified as a known threat. An instance of WebView // calls this method only after Safe Browsing is initialized, so there's no // conditional logic needed here. @Override public void onSafeBrowsingHit(WebView view, WebResourceRequest request, int threatType, SafeBrowsingResponse callback) { // The "true" argument indicates that your app reports incidents like // this one to Safe Browsing. callback.backToSafety(true); Toast.makeText(view.getContext(), "Unsafe web page blocked.", Toast.LENGTH_LONG).show(); } }
Extrator de miniaturas de vídeos
A classe MediaMetadataRetriever tem um novo método, getScaledFrameAtTime(), que encontra um frame próximo a uma posição de tempo especificada e retorna um bitmap com a mesma proporção do frame de origem, mas dimensionado para caber em um retângulo de largura e altura especificadas. Isso é útil para gerar imagens em miniatura de vídeos.
Recomendamos usar esse método em vez de getFrameAtTime(), que pode desperdiçar memória porque retorna um bitmap com a mesma resolução do vídeo de origem. Por exemplo, um frame de um vídeo em 4K seria um bitmap de 16 MB, muito maior do que o necessário para uma miniatura.
API de memória compartilhada
O Android 8.1 (nível 27 da API) introduz uma nova API
SharedMemory. Essa classe permite criar, mapear e gerenciar uma instância anônima de
SharedMemory. Você define a proteção de memória
em um
objeto SharedMemory
para leitura e/ou gravação. Como o objeto
SharedMemory
é Parcelable, você pode transmiti-lo facilmente para outro processo usando AIDL.
A API SharedMemory
interopera com o
recurso ASharedMemory no NDK.
ASharedMemory dá acesso
a um descritor do arquivo, que pode ser mapeado para leitura e gravação. É uma ótima
maneira de compartilhar grandes quantidades
de dados entre apps ou entre vários processos em um único app.
API WallpaperColors
O Android 8.1 (nível 27 da API) permite que seu plano de fundo dinâmico forneça informações de cor à interface do sistema. Para isso, crie um objeto WallpaperColors
de um bitmap, um elemento combinável ou usando três cores selecionadas manualmente.
Você também pode recuperar essas informações de cor.
Para criar um objeto WallpaperColors, faça uma destas ações:
- Para criar um objeto
WallpaperColorsusando três cores, crie uma instância da classeWallpaperColorstransmitindo a cor primária, secundária e terciária. A cor primária não pode ser nula. - Para criar um objeto
WallpaperColorsde um bitmap, chame o métodofromBitmap()transmitindo a origem do bitmap como parâmetro. - Para criar um objeto
WallpaperColorsde um elemento drawable, chame o métodofromDrawable()transmitindo a origem do elemento como parâmetro.
Para recuperar os detalhes da cor primária, secundária ou terciária do plano de fundo, chame os seguintes métodos:
getPrimaryColor()retorna a cor mais representativa visualmente do plano de fundo.getSecondaryColor()retorna a segunda cor mais proeminente do plano de fundo.- O método
getTertiaryColor()retorna a terceira cor mais proeminente do plano de fundo.
Para notificar o sistema sobre mudanças significativas de cor no seu plano de fundo interativo,
chame o método notifyColorsChanged() Esse método aciona um evento de ciclo de vida onComputeColors()
em que você tem a oportunidade de fornecer um novo objeto WallpaperColors.
Para adicionar um listener de mudanças de cor, chame o método addOnColorsChangedListener(). Você também pode chamar o método getWallpaperColors() para recuperar as cores principais de um plano de fundo.
Atualizações de impressão digital
A classe FingerprintManager introduziu os seguintes códigos de erro:
-
FINGERPRINT_ERROR_LOCKOUT_PERMANENT– O usuário tentou desbloquear o dispositivo usando o leitor de impressão digital muitas vezes. -
FINGERPRINT_ERROR_VENDOR– Ocorreu um erro específico do fornecedor no leitor de impressão digital.
Atualizações de criptografia
Várias alterações de criptografia foram feitas no Android 8.1:
- Novos algoritmos foram implementados no Conscrypt. A implementação do Conscrypt é usada preferencialmente em vez da implementação atual do Bouncy Castle. Os novos algoritmos incluem:
AlgorithmParameters:GCMKeyGenerator:AESKeyGenerator:DESEDEKeyGenerator:HMACMD5KeyGenerator:HMACSHA1KeyGenerator:HMACSHA224KeyGenerator:HMACSHA256KeyGenerator:HMACSHA384KeyGenerator:HMACSHA512SecretKeyFactory:DESEDESignature:NONEWITHECDSA
Cipher.getParameters().getParameterSpec(IvParameterSpec.class)não funciona mais para algoritmos que usam GCM. Em vez disso, usegetParameterSpec(GCMParameterSpec.class).- Muitas classes internas do Conscrypt associadas ao TLS foram refatoradas. Como os desenvolvedores às vezes acessam esses dados de forma reflexiva, os shims foram mantidos para oferecer suporte ao uso anterior, mas alguns detalhes mudaram. Por exemplo, os soquetes
eram do tipo
OpenSSLSocketImpl, mas agora são do tipoConscryptFileDescriptorSocketouConscryptEngineSocket, que estendemOpenSSLSocketImpl. - Os métodos
SSLSessionusados para gerarIllegalArgumentExceptionquando uma referência nula era transmitida agora geramNullPointerException. - O RSA
KeyFactorynão permite mais a geração de chaves de matrizes de bytes maiores que a chave codificada. As chamadas parageneratePrivate()egeneratePublic()que fornecem umKeySpecem que a estrutura de chave não preenche o buffer inteiro resultam em umInvalidKeySpecException. - Quando uma leitura de soquete era interrompida pelo fechamento do soquete, o Conscrypt retornava -1 da leitura. O "ler agora" gera
SocketException. - O conjunto de certificados de CA raiz foi alterado, principalmente removendo um grande número de certificados obsoletos, mas também removendo os certificados raiz da WoSign e da StartCom. Para mais informações sobre essa decisão, consulte a postagem do blog de segurança do Google Remoção final da confiança em certificados da WoSign e da StartCom (em inglês).