Fonctionnalités et API d'Android 8.1

Android 8.1 (niveau d'API 27) introduit de nombreuses nouvelles fonctionnalités pour les utilisateurs et les développeurs. Ce document présente les nouveautés pour les développeurs.

Android Oreo (édition Go)

Android Go est notre initiative visant à optimiser l'expérience Android pour les milliards d'utilisateurs qui se connectent à Internet dans le monde entier. À partir d'Android 8.1, Android devient une plate-forme idéale pour les appareils d'entrée de gamme. Les fonctionnalités de la configuration d'Android Oreo (édition Go) incluent:

  • Optimisations de la mémoire. Amélioration de l'utilisation de la mémoire sur la plate-forme pour garantir que les applications peuvent s'exécuter efficacement sur les appareils disposant de 1 Go de RAM ou moins.
  • Options de ciblage flexibles. De nouvelles constantes de fonctionnalités matérielles vous permettent de cibler la distribution de vos applications sur les appareils à mémoire RAM normale ou faible via Google Play.
  • Google Play.Bien que toutes les applications soient disponibles sur les appareils équipés d'Android Oreo (édition Go), Google Play offre une visibilité aux applications spécifiquement optimisées par les développeurs afin d'offrir une expérience de qualité à des milliards de personnes grâce à la création de milliards de consignes.

Nous avons mis à jour les consignes relatives à la conception de milliards d'applications en y ajoutant des conseils pour optimiser votre application pour les appareils équipés d'Android Oreo (édition Go). Pour la plupart des développeurs, optimiser votre APK existant ou utiliser la fonctionnalité Plusieurs APK de Google Play pour cibler les appareils à faible RAM avec une version de votre APK est le meilleur moyen de se préparer aux appareils exécutant Android Oreo (édition Go). N'oubliez pas que rendre votre application plus légère et plus efficace profite à l'ensemble de votre audience, quel que soit l'appareil utilisé.

API Neural Networks

L'API Neural Networks accélère les calculs et l'inférence pour les frameworks de machine learning sur l'appareil tels que TensorFlow Lite (la bibliothèque de ML multiplate-forme de Google pour mobile) et Caffe2, entre autres. Accédez au dépôt Open Source TensorFlow Lite pour les téléchargements et la documentation. TensorFlow Lite fonctionne avec l'API Neural Networks pour exécuter efficacement des modèles tels que MobileNets, Inception v3 et Réponse suggérée sur votre appareil mobile.

Mises à jour de Autofill Framework

Android 8.1 (niveau d'API 27) apporte plusieurs améliorations au framework de saisie automatique que vous pouvez intégrer à vos applications.

La classe BaseAdapter inclut désormais la méthode setAutofillOptions(), qui vous permet de fournir des représentations sous forme de chaînes des valeurs dans un adaptateur. Cela est utile pour les commandes spinner qui génèrent dynamiquement les valeurs dans leurs adaptateurs. Par exemple, vous pouvez utiliser la méthode setAutofillOptions() pour fournir une représentation sous forme de chaîne de la liste des années que les utilisateurs peuvent choisir dans le cadre de la date d'expiration d'une carte de crédit. Les services de saisie automatique peuvent utiliser la représentation sous forme de chaîne pour remplir correctement les affichages qui nécessitent les données.

En outre, la classe AutofillManager inclut la méthode notifyViewVisibilityChanged(View, int, boolean) que vous pouvez appeler pour avertir le framework des modifications apportées à la visibilité d'une vue dans une structure virtuelle. Il existe également une surcharge de la méthode pour les structures non virtuelles. Toutefois, les structures non virtuelles ne nécessitent généralement pas d'avertir explicitement le framework, car la méthode est déjà appelée par la classe View.

Android 8.1 permet également aux services de saisie automatique de personnaliser davantage l'affordance d'enregistrement de l'UI en ajoutant la prise en charge de CustomDescription and Validator dans SaveInfo.

Les descriptions personnalisées sont utiles pour aider le service de saisie automatique à clarifier ce qui est enregistré. Par exemple, lorsque l'écran contient une carte de crédit, il peut afficher le logo de la banque de la carte de crédit, les quatre derniers chiffres du numéro de la carte de crédit et son numéro d'expiration. Pour en savoir plus, consultez la classe CustomDescription.

Les objets Validator permettent d'éviter d'afficher l'UI de sauvegarde de saisie automatique lorsque la condition du validateur n'est pas remplie. Pour en savoir plus, consultez la classe Validator et ses sous-classes, LuhnChecksumValidator et RegexValidator.

Notifications

Android 8.1 apporte les modifications suivantes aux notifications:

  • Désormais, les applications ne peuvent émettre une alerte de notification qu'une fois par seconde. Les sons d'alerte dépassant ce taux ne sont pas mis en file d'attente et sont perdus. Cette modification n'affecte pas d'autres aspects du comportement des notifications. Les messages de notification sont toujours publiés comme prévu.
  • NotificationListenerService et ConditionProviderService ne sont pas compatibles avec les appareils Android à faible RAM qui renvoient true lorsque ActivityManager.isLowRamDevice() est appelé.

Mise à jour d'EditText

À partir du niveau d'API 27, la méthode EditText.getText() renvoie un Editable. Auparavant, elle renvoyait CharSequence. Cette modification est rétrocompatible, car Editable implémente CharSequence.

L'interface Editable offre des fonctionnalités supplémentaires intéressantes. Par exemple, comme Editable implémente également l'interface Spannable, vous pouvez appliquer un balisage au contenu dans une instance de EditText.

Actions programmatiques de la navigation sécurisée

En utilisant l' implémentation WebView de l'API Safe Browsing, votre application peut détecter lorsqu'une instance de WebView tente d'accéder à une URL que Google a classée comme menace connue. Par défaut, WebView affiche un interstitiel avertissant les utilisateurs de la menace connue. Cet écran permet aux utilisateurs de charger l'URL quand même ou de revenir à une page précédente sûre.

Dans Android 8.1, vous pouvez définir de manière programmatique la manière dont votre application réagit à une menace connue:

  • Vous pouvez contrôler si votre application signale les menaces connues à la navigation sécurisée.
  • Vous pouvez demander à votre application d'effectuer automatiquement une action particulière (par exemple, revenir en lieu sûr) chaque fois qu'elle rencontre une URL que la navigation sécurisée considère comme une menace connue.

Remarque:Pour une protection optimale contre les menaces connues, attendez d'avoir initialisé la navigation sécurisée avant d'appeler la méthode loadUrl() d'un objet WebView.

Les extraits de code suivants montrent comment indiquer aux instances de WebView de votre application de toujours revenir en lieu sûr après avoir rencontré une menace connue:

AndroidManifest.xml

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

MonActivitéWebWeb.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();
    }
}

Extracteur de miniatures vidéo

La classe MediaMetadataRetriever dispose d'une nouvelle méthode, getScaledFrameAtTime(), qui trouve un frame à proximité d'une position temporelle donnée et renvoie un bitmap ayant le même format que le frame source, mais ajusté pour tenir dans un rectangle d'une largeur et d'une hauteur données. Cela s'avère utile pour générer des vignettes à partir d'une vidéo.

Nous vous recommandons d'utiliser cette méthode plutôt que getFrameAtTime(), qui peut gaspiller de la mémoire, car elle renvoie un bitmap ayant la même résolution que la vidéo source. Par exemple, l'image d'une vidéo 4K possède un bitmap de 16 Mo, ce qui est beaucoup plus volumineux que pour une vignette.

API Shared Memory

Android 8.1 (niveau d'API 27) introduit une nouvelle API SharedMemory. Cette classe vous permet de créer, de mapper et de gérer une instance SharedMemory anonyme. Vous définissez la protection de la mémoire sur un objet SharedMemory pour la lecture et/ou l'écriture. Comme l'objet SharedMemory est Parcelable, vous pouvez facilement le transmettre à un autre processus via AIDL.

L'API SharedMemory interagit avec l'installation ASharedMemory dans le NDK. ASharedMemory donne accès à un descripteur de fichier, qui peut ensuite être mappé pour lecture et écriture. C'est un excellent moyen de partager de grandes quantités de données entre des applications ou entre plusieurs processus au sein d'une même application.

API WallpaperColors

Android 8.1 (niveau d'API 27) permet à votre fond d'écran animé de fournir des informations de couleur à l'UI du système. Pour ce faire, créez un objet WallpaperColors à partir d'un bitmap ou d'un drawable, ou utilisez trois couleurs sélectionnées manuellement. Vous pouvez également récupérer ces informations sur la couleur.

Pour créer un objet WallpaperColors, effectuez l'une des opérations suivantes:

  • Pour créer un objet WallpaperColors en utilisant trois couleurs, créez une instance de la classe WallpaperColors en transmettant la couleur principale, la couleur secondaire et la couleur tertiaire. La couleur principale ne doit pas être nulle.
  • Pour créer un objet WallpaperColors à partir d'un bitmap, appelez la méthode fromBitmap() en transmettant la source bitmap en tant que paramètre.
  • Pour créer un objet WallpaperColors à partir d'un drawable, appelez la méthode fromDrawable() en transmettant la source drawable en tant que paramètre.

Pour récupérer les détails de la couleur primaire, secondaire ou tertiaire à partir du fond d'écran, appelez les méthodes suivantes:

  • getPrimaryColor() renvoie la couleur la plus représentative visuellement du fond d'écran.
  • getSecondaryColor() renvoie la deuxième couleur la plus importante du fond d'écran.
  • La méthode getTertiaryColor() renvoie la troisième couleur la plus importante du fond d'écran.

Pour informer le système de tout changement de couleur important dans votre fond d'écran animé, appelez la méthode notifyColorsChanged(). Cette méthode déclenche un événement de cycle de vie onComputeColors() dans lequel vous avez la possibilité de fournir un nouvel objet WallpaperColors.

Pour ajouter un écouteur pour les changements de couleur, vous pouvez appeler la méthode addOnColorsChangedListener(). Vous pouvez également appeler la méthode getWallpaperColors() pour récupérer les couleurs primaires d'un fond d'écran.

Mises à jour de l'empreinte digitale

La classe FingerprintManager a introduit les codes d'erreur suivants:

  • FINGERPRINT_ERROR_LOCKOUT_PERMANENT : l'utilisateur a essayé de déverrouiller son appareil à de trop nombreuses reprises avec le lecteur d'empreinte digitale.
  • FINGERPRINT_ERROR_VENDOR : une erreur de lecteur d'empreinte digitale spécifique au fournisseur s'est produite.

Informations sur la cryptographie

Un certain nombre de modifications concernant la cryptographie ont été apportées à Android 8.1:

  • De nouveaux algorithmes ont été implémentés dans Conscrypt. L'implémentation de Conscrypt est privilégiée par rapport à l'implémentation existante de Bouncy Castle. Les nouveaux algorithmes sont les suivants :
    • 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) ne fonctionne plus pour les algorithmes utilisant GCM. Utilisez plutôt getParameterSpec(GCMParameterSpec.class).
  • De nombreuses classes Conscrypt internes associées à TLS ont été refactorisées. Étant donné que les développeurs y accèdent parfois de manière réfléchie, des shims ont été laissés en place pour prendre en charge l'utilisation précédente, mais certains détails ont changé. Par exemple, les sockets étaient auparavant de type OpenSSLSocketImpl, mais ils sont désormais de type ConscryptFileDescriptorSocket ou ConscryptEngineSocket, qui étendent tous deux OpenSSLSocketImpl.
  • Les méthodes SSLSession permettant de générer une exception IllegalArgumentException lorsqu'elle transmet une référence nulle, génèrent désormais NullPointerException.
  • Le RSA KeyFactory ne permet plus de générer des clés à partir de tableaux d'octets plus grands que la clé encodée. Les appels à generatePrivate() et generatePublic() qui fournissent un KeySpec où la structure de clé ne remplit pas tout le tampon génèrent une InvalidKeySpecException.
  • Lorsqu'une lecture de socket est interrompue par la fermeture du socket, Conscrypt renvoie la valeur -1 à partir de la lecture. La lecture génère désormais une exception SocketException.
  • L'ensemble de certificats CA racine a été modifié, ce qui a pour la plupart supprimé un grand nombre de certificats obsolètes, ainsi que les certificats racine de WoSign et StartCom. Pour en savoir plus sur cette décision, consultez l'article du blog Google sur la sécurité, Suppression finale de la confiance dans les certificats WoSign et StartCom.