Funzionalità e API di Android 8.1

Android 8.1 (livello API 27) introduce una serie di nuove caratteristiche per utenti e sviluppatori. Questo documento mette in evidenza le novità per gli sviluppatori.

Android Oreo (Go edition)

Android Go è la nostra iniziativa per ottimizzare l'esperienza Android per miliardi di persone in tutto il mondo che si collegano a internet. A partire da Android 8.1, renderemo Android un'ottima piattaforma per i dispositivi di base. Le funzionalità della configurazione di Android Oreo (Go Edition) includono:

  • Ottimizzazioni della memoria. Miglioramento dell'utilizzo della memoria in tutta la piattaforma per garantire un'efficienza efficiente delle app su dispositivi con 1 GB o meno di RAM.
  • Opzioni di targeting flessibili. Nuove costanti delle funzionalità hardware per consentirti di indirizzare la distribuzione delle tue app a dispositivi con RAM normale o bassa tramite Google Play.
  • Google Play.Sebbene tutte le app saranno disponibili sui dispositivi con Android Oreo (Go Edition), Google Play darà visibilità alle app ottimizzate specificamente dagli sviluppatori per offrire un'esperienza straordinaria a miliardi di persone, creando miliardi di linee guida.

Abbiamo aggiornato la struttura per miliardi di linee guida con ulteriori indicazioni su come ottimizzare l'app per i dispositivi con Android Oreo (Go Edition). Per la maggior parte degli sviluppatori, ottimizzare l'APK esistente o utilizzare la funzionalità di più APK di Google Play per scegliere come target di una versione dell'APK i dispositivi con poca RAM è il modo migliore per prepararsi ai dispositivi con Android Oreo (Go Edition). Ricorda che rendere l'app più leggera ed efficiente è un vantaggio per tutto il pubblico, indipendentemente dal dispositivo.

API Neural Networks

L'API Neural Networks fornisce un calcolo e un'inferenza accelerati per framework di machine learning on-device come TensorFlow Lite, la libreria ML multipiattaforma di Google per dispositivi mobili, oltre a Caffe2 e altri. Visita il repository open source di TensorFlow Lite per download e documenti. TensorFlow Lite funziona con l'API Neural Networks per eseguire in modo efficiente modelli come MobileNets, Inception v3 e Risposta rapida sul tuo dispositivo mobile.

Aggiornamenti del framework di compilazione automatica

Android 8.1 (livello API 27) offre diversi miglioramenti al framework di compilazione automatica che puoi incorporare nelle tue app.

La classe BaseAdapter ora include il metodo setAutofillOptions(), che consente di fornire rappresentazioni stringa dei valori in un adattatore. Questo è utile per i controlli spinner che generano dinamicamente i valori nei propri adattatori. Ad esempio, puoi utilizzare il metodo setAutofillOptions() per fornire una rappresentazione stringa dell'elenco di anni che gli utenti possono scegliere come parte della data di scadenza di una carta di credito. I servizi di compilazione automatica possono usare la rappresentazione stringa per compilare correttamente le viste che richiedono i dati.

Inoltre, la classe AutofillManager include il metodo notifyViewVisibilityChanged(View, int, boolean) che puoi chiamare per notificare al framework le modifiche alla visibilità di una vista in una struttura virtuale. C'è anche un sovraccarico del metodo per le strutture non virtuali. Tuttavia, le strutture non virtuali di solito non richiedono una notifica esplicita al framework perché il metodo è già chiamato dalla classe View.

Android 8.1 offre inoltre ai Servizi di compilazione automatica una maggiore capacità di personalizzare l'affordanza dell'interfaccia utente di salvataggio aggiungendo il supporto per CustomDescription and Validator in SaveInfo.

Le descrizioni personalizzate sono utili per aiutare il servizio di compilazione automatica a chiarire cosa viene salvato. Ad esempio, se la schermata contiene una carta di credito, potrebbe essere mostrato il logo della banca che ha emesso la carta, le ultime quattro cifre del numero della carta di credito e il numero di scadenza. Per saperne di più, consulta il corso CustomDescription.

Gli oggetti Validator vengono utilizzati per evitare di visualizzare l'interfaccia utente per il salvataggio della compilazione automatica quando la condizione dello strumento di convalida non è soddisfatta. Per saperne di più, consulta la classe Validator e le relative sottoclassi, LuhnChecksumValidator e RegexValidator.

Notifiche

Android 8.1 include le seguenti modifiche alle notifiche:

  • Ora le app possono emettere un suono di avviso di notifica solo una volta al secondo. I suoni di avviso che superano questa frequenza non vengono messi in coda e vengono persi. Questa modifica non influisce su altri aspetti del comportamento delle notifiche e i messaggi di notifica vengono comunque pubblicati come previsto.
  • NotificationListenerService e ConditionProviderService non sono supportati sui dispositivi basati su Android con poca RAM che restituiscono true quando viene chiamato ActivityManager.isLowRamDevice().

Aggiornamento EditText

A partire dal livello API 27, il metodo EditText.getText() restituisce Editable; in precedenza, restituisce CharSequence. Questa modifica è compatibile con le versioni precedenti, in quanto Editable implementa CharSequence.

L'interfaccia Editable offre preziose funzionalità aggiuntive. Ad esempio, poiché Editable implementa anche l'interfaccia Spannable, puoi applicare il markup ai contenuti all'interno di un'istanza di EditText.

Azioni di Navigazione sicura programmatica

Se utilizzi l' implementazione WebView dell'API Navigazione sicura, la tua app può rilevare quando un'istanza di WebView tenta di accedere a un URL che Google ha classificato come minaccia nota. Per impostazione predefinita, WebView mostra un annuncio interstitial che avvisa gli utenti della minaccia nota. Questa schermata offre agli utenti la possibilità di caricare comunque l'URL o di tornare a una pagina precedente sicura.

In Android 8.1, puoi definire in modo programmatico il modo in cui la tua app risponde a una minaccia nota:

  • Puoi controllare se la tua app segnala o meno minacce note a Navigazione sicura.
  • Puoi fare in modo che la tua app esegua automaticamente una determinata azione, ad esempio tornare nell'area protetta, ogni volta che rileva un URL che Navigazione sicura classifica come minaccia nota.

Nota: per una protezione ottimale contro le minacce note, attendi di aver inizializzato Navigazione sicura prima di richiamare il metodo loadUrl() di un oggetto WebView.

I seguenti snippet di codice mostrano come indicare alle istanze della tua app di WebView di tornare sempre in sicurezza dopo aver riscontrato una minaccia nota:

AndroidManifest.xml

<manifest>
    <application>
        ...
        <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
                   android:value="true" />
    </application>
</manifest>

AttivitàWeb.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();
    }
}

Estrattore miniature video

La classe MediaMetadataRetriever ha un nuovo metodo, getScaledFrameAtTime(), che trova un frame vicino a una determinata posizione temporale e restituisce una bitmap con le stesse proporzioni del frame di origine, ma ridimensionata per adattarla a un rettangolo di larghezza e altezza specificate. Ciò è utile per generare immagini in miniatura di un video.

Ti consigliamo di utilizzare questo metodo anziché getFrameAtTime(), che può sprecare memoria, perché restituisce una bitmap con la stessa risoluzione del video di origine. Ad esempio, un frame di un video 4K sarebbe una bitmap di 16 MB, molto più grande di quanto necessario per un'immagine in miniatura.

API Shared Memory

Android 8.1 (livello API 27) introduce una nuova API SharedMemory. Questa classe ti consente di creare, mappare e gestire un'istanza di SharedMemory anonima. Puoi impostare la protezione della memoria su un oggetto SharedMemory per la lettura e/o la scrittura e, poiché l'oggetto SharedMemory è Parcelable, puoi facilmente passarlo a un altro processo tramite AIDL.

L'API SharedMemory interagisce con la struttura ASharedMemory nell'NDK. ASharedMemory dà accesso a un descrittore di file, che può quindi essere mappato per la lettura e la scrittura. È un ottimo modo per condividere grandi quantità di dati tra le app o tra più processi all'interno di una singola app.

API BackgroundColors

Android 8.1 (livello API 27) consente allo sfondo animato di fornire informazioni sul colore all'interfaccia utente di sistema. Per farlo, crea un oggetto WallpaperColors da una bitmap, una traccia disegnabile o utilizza tre colori selezionati manualmente. Puoi anche recuperare queste informazioni sul colore.

Per creare un oggetto WallpaperColors, esegui una delle seguenti operazioni:

  • Per creare un oggetto WallpaperColors utilizzando tre colori, crea un'istanza della classe WallpaperColors trasmettendo il colore principale, secondario e terziario. Il colore principale non deve essere nullo.
  • Per creare un oggetto WallpaperColors da una bitmap, chiama il metodo fromBitmap() passando l'origine bitmap come parametro.
  • Per creare un oggetto WallpaperColors da un oggetto disegnabile, chiama il metodo fromDrawable() passando l'origine disegnabile come parametro.

Per recuperare i dettagli del colore principale, secondario o terziario dallo sfondo, chiama i seguenti metodi:

Per segnalare al sistema eventuali modifiche significative di colore dello sfondo animato, chiama il metodo notifyColorsChanged(). Questo metodo attiva un evento del ciclo di vita di onComputeColors() in cui hai l'opportunità di fornire un nuovo oggetto WallpaperColors.

Per aggiungere un listener per le modifiche dei colori, puoi chiamare il metodo addOnColorsChangedListener(). Puoi anche chiamare il metodo getWallpaperColors() per recuperare i colori principali di uno sfondo.

Aggiornamenti dell'impronta

La classe FingerprintManager ha introdotto i seguenti codici di errore:

  • FINGERPRINT_ERROR_LOCKOUT_PERMANENT – L'utente ha provato troppe volte a sbloccare il dispositivo usando il lettore di impronte.
  • FINGERPRINT_ERROR_VENDOR: si è verificato un errore del lettore di impronte specifico del fornitore.

Aggiornamenti sulla crittografia

Con Android 8.1 sono state apportate diverse modifiche alla crittografia:

  • In Conscrypt sono stati implementati nuovi algoritmi. L'implementazione Conscrypt è utilizzata preferenzialmente rispetto all'implementazione esistente di Bouncy Castle. I nuovi algoritmi includono:
    • AlgorithmParameters:GCM
    • KeyGenerator:AES
    • KeyGenerator:DESEDE
    • KeyGenerator:HMACMD5
    • KeyGenerator:HMACSHA1
    • KeyGenerator:HMACSHA224
    • KeyGenerator:HMACSHA256
    • KeyGenerator:HMACSHA384
    • KeyGenerator:HMACSHA512
    • SecretKeyFactory:DESEDE
    • Signature:NONEWITHECDSA
  • Cipher.getParameters().getParameterSpec(IvParameterSpec.class) non più funziona per gli algoritmi che utilizzano GCM. Utilizza invece getParameterSpec(GCMParameterSpec.class).
  • È stato eseguito il refactoring di molte classi Conscrypt interne associate a TLS. Poiché a volte gli sviluppatori accedono a queste informazioni in modo riflettente, le shim sono state lasciate in uso per supportare l'utilizzo precedente, ma alcuni dettagli sono cambiati. Ad esempio, i socket in precedenza erano di tipo OpenSSLSocketImpl, ma ora sono di tipo ConscryptFileDescriptorSocket o ConscryptEngineSocket, entrambi estensione OpenSSLSocketImpl.
  • SSLSession metodi utilizzati per generare IllegalArgumentException quando viene passato un riferimento nullo, ora generano NullPointerException.
  • L'RSA KeyFactory non consente più la generazione di chiavi da array di byte più grandi della chiave codificata. Le chiamate a generatePrivate() e generatePublic() che forniscono un KeySpec in cui la struttura della chiave non riempie l'intero buffer daranno come risultato un InvalidKeySpecException.
  • Quando una lettura di un socket viene interrotta dal socket che viene chiuso, Conscrypt viene utilizzato per restituire -1 dalla lettura. La lettura ora genera SocketException.
  • Il set di certificati CA radice è stato modificato, rimuovendo principalmente un numero elevato di certificati obsoleti, ma anche i certificati radice per WoSign e StartCom. Per ulteriori informazioni su questa decisione, consulta il post del blog sulla sicurezza di Google, Final rimozione dell'attendibilità in WoSign e StartCom Certificates.