API Android 4.2

Niveau d'API : 17

Android 4.2 (JELLY_BEAN_MR1) est une mise à jour de Jelly Bean qui propose de nouvelles fonctionnalités aux utilisateurs et aux développeurs d'applications. Ce document présente les nouvelles API les plus notables et utiles pour les développeurs.

En tant que développeur d'applications, vous devez télécharger l'image système et la plate-forme SDK Android 4.2 depuis SDK Manager dès que possible. Si vous ne disposez pas d'appareil exécutant Android 4.2 sur lequel tester votre application, utilisez l'image système Android 4.2 pour tester votre application sur Android Emulator. Ensuite, compilez vos applications avec la plate-forme Android 4.2 pour commencer à utiliser les dernières API.

Pour optimiser davantage votre application pour les appareils équipés d'Android 4.2, vous devez définir votre targetSdkVersion sur "17", l'installer sur une image système Android 4.2, la tester, puis publier une mise à jour avec cette modification.

Toi peuvent utiliser les API sous Android 4.2 tout en étant compatible avec les anciennes versions en ajoutant des conditions à votre code qui vérifient le niveau d'API du système avant d'exécuter API non compatibles avec votre minSdkVersion. Pour en savoir plus sur le maintien de la rétrocompatibilité, consultez Créer des UI rétrocompatibles.

Pour en savoir plus sur le fonctionnement des niveaux d'API, consultez Qu'est-ce que l'API ? Niveau ?

Nouveaux comportements importants

Si vous avez déjà publié une application pour Android, tenez compte des points suivants modifications susceptibles d'affecter le comportement de votre application:

  • Par défaut, les fournisseurs de contenu ne sont plus exportés. C'est-à-dire que la valeur par défaut pour l'attribut android:exported est désormais “false". Si vous souhaitez que d'autres applications puissent accéder à votre fournisseur de contenu, vous devez désormais définir explicitement android:exported="true".

    Cette modification ne s'applique que si vous définissez android:targetSdkVersion ou android:minSdkVersion sur 17 ou plus. Sinon, la valeur par défaut est toujours “true". même sous Android 4.2 ou version ultérieure.

  • Par rapport aux versions précédentes d'Android, les résultats de la position de l'utilisateur peuvent être moins précis si votre application demande l'autorisation ACCESS_COARSE_LOCATION, mais pas l'autorisation ACCESS_FINE_LOCATION.

    Pour répondre aux attentes des utilisateurs en matière de confidentialité lorsque votre application demande l'autorisation d'accéder à la position approximative (et non à la position exacte), le système ne fournit pas d'estimation de la position de l'utilisateur plus précise qu'un pâté de maisons.

  • Certains paramètres de l'appareil définis par Settings.System sont désormais en lecture seule. Si votre application tente d'écrire des modifications apportées aux paramètres définis dans Settings.System qui ont été déplacés vers Settings.Global, l'opération d'écriture échoue de manière silencieuse lorsqu'elle s'exécute sur Android 4.2 ou version ultérieure.

    Même si votre valeur pour android:targetSdkVersion et android:minSdkVersion est inférieure à 17, votre application ne pourra pas modifier les paramètres qui ont ont été déplacés vers Settings.Global sur les appareils équipés d'Android 4.2 ou version ultérieure.

  • Si votre application utilise WebView, Android 4.2 ajoute une couche de sécurité supplémentaire pour que vous puissiez lier JavaScript à votre code Android de manière plus sécurisée. Si vous définissez votre targetSdkVersion sur 17 ou plus, vous devez maintenant ajouter l'annotation @JavascriptInterface à toute méthode que vous souhaitez mettre à la disposition de votre code JavaScript (la méthode doit également être publique). Si vous ne fournissez pas la méthode n'est pas accessible par une page Web dans votre WebView sous Android 4.2 ou version ultérieure. Si vous définissez le paramètre targetSdkVersion vers la version 16 ou une version antérieure, l'annotation n'est pas obligatoire, mais nous vous recommandons de mettre à jour votre version cible et ajouter l'annotation pour plus de sécurité.

    En savoir plus sur la liaison du code JavaScript au code Android

Daydream

Daydream est un nouveau mode d'économiseur d'écran interactif pour les appareils Android. Il s'active automatiquement lorsque l'appareil est inséré dans une station d'accueil ou qu'il est inactif alors qu'il est branché sur une (au lieu d'éteindre l'écran). L'écran de veille interactif ne s'affiche qu'un seul rêve à la fois, être un écran purement visuel et passif qui se ferme au toucher, ou qui peut être interactif et réactif. à la suite complète d'événements d'entrée. Vos rêves s'exécutent dans le processus de votre application et ont un accès complet à le kit UI Android, y compris les vues, les mises en page et les animations, pour qu'elles soient plus flexibles et plus puissant que les fonds d'écran animés ou les widgets d'application.

Vous pouvez créer un rêve pour Daydream en implémentant une sous-classe de DreamService. Les API DreamService sont conçus pour être semblables à ceux de Activity. Pour spécifier l'UI de votre rêve, transmettez un ID de ressource de mise en page ou View à setContentView() à tout moment après avoir créé une fenêtre, par exemple à partir du rappel onAttachedToWindow().

La classe DreamService fournit d'autres méthodes de rappel de cycle de vie importantes en plus des API Service de base, telles que onDreamingStarted(), onDreamingStopped() et onDetachedFromWindow(). Vous ne pouvez pas lancer de DreamService depuis votre application, celle-ci est lancée automatiquement par le système.

Si votre rêve est interactif, vous pouvez démarrer une activité à partir du rêve pour diriger l'utilisateur vers l'UI complète de votre application pour plus de détails ou de contrôle. Vous pouvez utiliser finish() pour mettre fin au rêve afin que l'utilisateur puisse voir le nouvelle activité.

Pour que le système puisse accéder à votre écran de veille interactif, déclarez votre DreamService avec un élément <service>. dans votre fichier manifeste. Vous devez ensuite inclure un filtre d'intent avec l'action "android.service.dreams.DreamService". Exemple :

<service android:name=".MyDream" android:exported="true"
    android:icon="@drawable/dream_icon" android:label="@string/dream_label" >
    <intent-filter>
        <action android:name="android.service.dreams.DreamService" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</service>

DreamService propose d'autres méthodes utiles à connaître :

  • setInteractive(boolean) contrôle si le rêve reçoit des événements d'entrée ou s'il se ferme immédiatement à la suite d'une entrée utilisateur. Si le rêve est interactif, l'utilisateur peut utiliser les boutons Retour ou Accueil pour quitter le rêve, ou vous pouvez appeler finish() pour l'arrêter.
  • Si vous souhaitez un affichage totalement immersif, vous pouvez appeler setFullscreen() pour masquer la barre d'état.
  • Avant le démarrage de l'écran de veille interactif, la luminosité de l'écran s'assombrit pour signaler à l'utilisateur que le délai d'inactivité est dépassé. approche. En appelant setScreenBright(true), vous pouvez régler la luminosité habituelle de l'écran.

Pour en savoir plus, consultez la documentation DreamService.

Écrans secondaires

Android permet désormais à votre application d'afficher du contenu unique sur des écrans supplémentaires connectés à l'appareil de l'utilisateur via une connexion filaire ou Wi-Fi. Pour créer un contenu unique pour un écran secondaire, étendez Presentation et implémentez le rappel onCreate(). Dans onCreate() : spécifiez votre UI pour l'écran secondaire. en appelant setContentView(). En tant qu'extension de la classe Dialog, la classe Presentation fournit la région dans laquelle votre application peut afficher une UI unique sur le l'écran secondaire.

Pour détecter les écrans secondaires sur lesquels vous pouvez afficher votre Presentation, utilisez les API DisplayManager ou MediaRouter. Bien que les API DisplayManager vous permettent d'énumérer plusieurs écrans pouvant être connectés en même temps, vous devez généralement utiliser MediaRouter pour accéder rapidement à l'écran par défaut du système pour les présentations.

Pour obtenir l'affichage par défaut de votre présentation, appelez MediaRouter.getSelectedRoute() et transmettez-le ROUTE_TYPE_LIVE_VIDEO Cette opération renvoie un objet MediaRouter.RouteInfo qui décrit le parcours actuellement sélectionné par le système pour les présentations vidéo. Si MediaRouter.RouteInfo n'est pas nul, appelez getPresentationDisplay() pour obtenir Display représentant l'écran connecté.

Vous pouvez ensuite afficher votre présentation en transmettant l'objet Display à un constructeur de votre classe Presentation. Votre présentation s'affiche alors sur l'écran secondaire.

Pour détecter au moment de l'exécution un nouvel écran connecté, créez une instance de MediaRouter.SimpleCallback dans laquelle vous implémentez la méthode de rappel onRoutePresentationDisplayChanged(), que le système appellera lorsqu'une nouvelle écran de présentation est connecté. Enregistrez ensuite le MediaRouter.SimpleCallback en le transmettant à MediaRouter.addCallback() avec le type de route ROUTE_TYPE_LIVE_VIDEO. Lorsque vous recevez un appel à onRoutePresentationDisplayChanged(), appelez simplement MediaRouter.getSelectedRoute() comme indiqué ci-dessus.

Pour optimiser davantage l'UI de votre Presentation pour les écrans secondaires, vous pouvez appliquer un thème différent en spécifiant l'attribut android:presentationTheme dans le <style> que vous avez appliqué à votre application ou activité.

Gardez à l'esprit que les écrans connectés à l'appareil de l'utilisateur ont souvent une taille d'écran plus grande et que probablement une densité d’écran différente. Comme les caractéristiques de l'écran peuvent être différentes, vous devez fournissent des ressources optimisées spécifiquement pour des écrans aussi grands. Si vous avez besoin Pour demander des ressources supplémentaires à votre Presentation, appelez getContext().getResources() pour obtenir l'objet Resources correspondant à l'écran. Cela fournit les ressources appropriées de votre application les plus adaptées à la taille et à la densité de l'écran secondaire.

Pour en savoir plus et obtenir des exemples de code, consultez la documentation de la classe Presentation.

Widgets de l'écran de verrouillage

Android permet désormais aux utilisateurs d'ajouter des widgets d'application à l'écran de verrouillage. Pour pouvoir utiliser votre widget d'application sur la l'écran de verrouillage, ajoutez l'attribut android:widgetCategory à votre fichier XML qui spécifie AppWidgetProviderInfo. Cet attribut accepte deux valeurs : home_screen et keyguard. Par défaut, l'attribut est défini sur home_screen afin que les utilisateurs puissent ajouter vos sur l'écran d'accueil. Si vous souhaitez que le widget de votre application soit également disponible sur l'écran de verrouillage, ajoutez la valeur keyguard :

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:widgetCategory="keyguard|home_screen">
</appwidget-provider>

Vous devez également spécifier une mise en page initiale pour votre widget d'application sur l'écran de verrouillage avec l'attribut android:initialKeyguardLayout. Elle fonctionne de la même manière que android:initialLayout, en ce sens qu'elle fournit Une mise en page qui peut s'afficher immédiatement jusqu'à ce que le widget de votre application soit initialisé et puisse mettre à jour mise en page.

Pour en savoir plus sur la création de widgets d'application pour l'écran de verrouillage, y compris pour dimensionner votre widget d'application sur l'écran de verrouillage, consultez le guide Widgets d'application.

Fonctionnalité multi-utilisateur

Android permet désormais de créer plusieurs espaces utilisateur sur des appareils partageables tels que des tablettes. Chaque utilisateur d'un appareil dispose de son propre ensemble de comptes, d'applications, de paramètres système, de fichiers et de toute autre donnée associée à l'utilisateur.

En tant que développeur d'applications, vous n'avez rien de différent à faire pour que votre application fonctionne correctement avec plusieurs utilisateurs sur un seul appareil. Quel que soit le nombre d'utilisateurs sur un appareil, les données que votre application enregistre pour un utilisateur donné sont conservées séparément des données qu'elle enregistre pour les autres utilisateurs. Le système suit les données utilisateur appartenant au processus utilisateur dans lequel votre application s'exécute et n'autorise votre application à accéder qu'aux données de cet utilisateur, et non aux données d'autres utilisateurs.

Enregistrer des données dans un environnement multi-utilisateur

Chaque fois que votre application enregistre des préférences utilisateur, crée une base de données ou écrit un fichier interne ou externe, ces données ne sont accessibles que lorsqu'il est en cours d'exécution sous l'identité de cet utilisateur.

Pour vous assurer que votre application se comporte correctement dans un environnement multi-utilisateur, ne faites pas référence à votre répertoire interne de l'application ou emplacement de stockage externe à l'aide de chemins d'accès codés en dur, et utilisez toujours les API appropriées:

Quelle que soit l'API que vous utilisez pour enregistrer des données pour un utilisateur donné, les données ne seront pas accessibles lorsque vous exécuterez l'application en tant qu'utilisateur différent. Du point de vue de votre application, chaque utilisateur s'exécute sur un appareil complètement distinct.

Identifier les utilisateurs dans un environnement multi-utilisateur

Si votre application souhaite identifier des utilisateurs uniques, par exemple pour collecter des données analytiques ou créer un autre compte d'associations, vous devez suivre les pratiques recommandées pour identifier des installations uniques. En créant un UUID lorsque votre application démarre pour le la première fois, vous êtes certain d'obtenir un identifiant unique pour suivre chaque utilisateur, quel que soit le nombre les utilisateurs installent votre application sur un seul appareil. Vous pouvez également enregistrer un jeton local extrait de votre serveur ou utiliser l'ID d'enregistrement fourni par Google Cloud Messaging.

Notez que si votre application demande l'un des identifiants de l'appareil matériel (tel que l'adresse MAC du Wi-Fi ou le numéro SERIAL), elle fournira la même valeur pour chaque utilisateur, car ces identifiants sont liés au matériel et non à l'utilisateur. Sans parler des autres les problèmes que ces identifiants introduisent, comme indiqué dans la section Article de blog sur les installations d'applications.

Nouveaux paramètres généraux

Les paramètres système ont été mis à jour pour prendre en charge plusieurs utilisateurs avec l'ajout de Settings.Global. Cet ensemble de paramètres est semblable aux paramètres Settings.Secure, car ils sont en lecture seule, mais s'appliquent globalement à tous les espaces utilisateur de l'appareil.

Plusieurs paramètres existants ont été déplacés ici de Settings.System ou Settings.Secure. Si votre application est vous modifiez actuellement des paramètres précédemment définis dans Settings.System (comme AIRPLANE_MODE_ON), attendez-vous à elle ne fonctionnera plus sur un appareil équipé d'Android 4.2 ou version ultérieure si ces paramètres étaient déplacé vers Settings.Global. Vous pouvez continuer à lire les paramètres Settings.Global, mais comme les paramètres ne sont plus considérés comme sûrs des modifications des applications, cette opération échoue en mode silencieux et le système affiche un avertissement le journal système lorsque votre application est exécutée sur Android 4.2 ou version ultérieure.

Compatibilité avec la mise en page de droite à gauche

Android propose désormais plusieurs API qui vous permettent de créer des interfaces utilisateur Transformation de l'orientation de la mise en page pour prendre en charge les langues qui utilisent les interfaces utilisateur qui se lisent de droite à gauche et qui utilisent la lecture (arabe et hébreu, par exemple).

Pour commencer à prendre en charge les mises en page RTL dans votre application, définissez l'attribut android:supportsRtl sur l'élément <application> dans votre fichier manifeste et définissez-le sur “true". Une fois cette option activée, le système activera plusieurs API de lecture de droite à gauche pour afficher votre application avec des mises en page de ce type. Par exemple, la barre d'action affiche l'icône et le titre sur le côté droit et les boutons d'action à gauche, ainsi que toutes les mises en page que vous avez créées avec la les classes View fournies par le framework seront également inversées.

Si vous devez optimiser davantage l'apparence de votre application lorsqu'elle est affichée avec une mise en page de droite à gauche, il existe deux niveaux d'optimisation de base :

  1. Convertissez les propriétés de mise en page orientées à gauche et à droite en propriétés de mise en page orientées au début et à la fin.

    Par exemple, utilisez android:layout_marginStart au lieu de android:layout_marginLeft et android:layout_marginEnd au lieu de android:layout_marginRight.

    La classe RelativeLayout fournit également la mise en page correspondante. pour remplacer les positions gauche/droite, tels que android:layout_alignParentStart par remplacez android:layout_alignParentLeft et android:layout_toStartOf au lieu de android:layout_toLeftOf

  2. Pour optimiser complètement les mises en page RTL, vous pouvez fournir des fichiers de mise en page entièrement distincts à l'aide du qualificatif de ressource ldrtl (ldrtl signifie "layout-direction-right-to-left"). Par exemple, vous pouvez enregistrer vos fichiers de mise en page par défaut dans res/layout/ et vos mises en page optimisées pour le RTL dans res/layout-ldrtl/.

    Le qualificatif ldrtl est idéal pour les ressources drawables, ce qui vous permet de fournir graphiques orientés dans le sens correspondant au sens de lecture.

Diverses autres API sont disponibles dans le framework pour prendre en charge les mises en page de droite à gauche, par exemple dans la classe View afin que vous puissiez implémenter les comportements appropriés pour les vues personnalisées et dans Configuration pour interroger le sens de mise en page actuel.

Remarque : Si vous utilisez SQlite et que les noms de tables ou de colonnes sont "numéros uniquement", faites attention : l'utilisation de String.format(String, Object...) peut entraîner des erreurs si les nombres ont été convertis en leurs équivalents arabes si votre appareil est défini sur la langue arabe. Vous devez utiliser String.format(Locale,String,Object...) pour vous assurer que les numéros sont conservées au format ASCII. Utilisez également String.format("%d", int) au lieu d'String.valueOf(int) pour mettre en forme les nombres.

Fragments imbriqués

Vous pouvez désormais intégrer des fragments dans des fragments. Cela est utile dans diverses situations où vous souhaitez placer des composants d'UI dynamiques et réutilisables dans un composant d'UI qui est lui-même dynamique et réutilisable. Par exemple, si vous utilisez ViewPager pour créer des fragments qui balayent l'écran vers la gauche et la droite et occupent la majeure partie de l'espace de l'écran, vous pouvez désormais insérer des fragments dans chaque page de fragment.

Pour imbriquer un fragment, il vous suffit d'appeler getChildFragmentManager() sur la Fragment dans laquelle vous souhaitez ajouter un fragment. Cela renvoie un FragmentManager que vous pouvez utiliser comme d'habitude à partir de l'activité de premier niveau pour créer des transactions de fragment. Par exemple, voici du code qui ajoute un fragment à partir de Une classe Fragment existante:

Kotlin

val videoFragment = VideoPlayerFragment()
childFragmentManager.beginTransaction().apply {
    add(R.id.video_fragment, videoFragment)
    commit()
}

Java

Fragment videoFragment = new VideoPlayerFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.video_fragment, videoFragment).commit();

À partir d'un fragment imbriqué, vous pouvez obtenir une référence au fragment parent en appelant getParentFragment()

La bibliothèque Android Support prend désormais également en charge les fragments imbriqués, ce qui vous permet d'implémenter des sur Android 1.6 et versions ultérieures.

Remarque:Vous ne pouvez pas gonfler une mise en page en fragment lorsque cette mise en page inclut un <fragment>. Les fragments imbriqués ne sont acceptés que lorsqu'ils sont ajoutés à un de manière dynamique.

RenderScript

La fonctionnalité de calcul de Renderscript a été améliorée avec les fonctionnalités suivantes:

Fonctionnalités intrinsèques des scripts

Vous pouvez utiliser les intrinsèques de script intégrés de Renderscript qui implémentent des opérations courantes pour vous, par exemple :

Pour utiliser un script intrinsèque, appelez la méthode statique create() de chaque intrinsèque pour créer une instance du script. Vous appelez ensuite les méthodes set() disponibles de chaque script intrinsèque pour définir les entrées et les options nécessaires. Enfin, appelez la méthode forEach(). pour exécuter le script.

Groupes de scripts

Les ScriptGroup vous permettent d'associer des RenderScript associés des scripts et les exécuter en un seul appel.

Utiliser un ScriptGroup.Builder pour ajouter tous les scripts au groupe en appelant addKernel(). Une fois tous les scripts ajoutés, créez les connexions entre eux en appelant addConnection(). Lorsque vous avez terminé d'ajouter les connexions, appelez create() pour créer le groupe de scripts. Avant d'exécuter le groupe de scripts, spécifiez l'entrée Allocation et le script initial à exécuter avec setInput(Script.KernelID, Allocation) et fournir la sortie Allocation, où le résultat sera écrit et le script final dans avec setOutput(). Enfin, appelez execute() pour exécuter le groupe de scripts.

Script du filtre

Filterscript définit des contraintes sur les API Renderscript existantes qui permettent d'exécuter le code obtenu. sur une plus grande variété de processeurs (processeurs, GPU et DSP). Pour créer des fichiers Filterscript, créez des fichiers .fs au lieu de fichiers .rs, et spécifiez #pragma rs_fp_relaxed pour indiquer à l'environnement d'exécution Renderscript que vos scripts ne nécessitent pas une précision à virgule flottante stricte IEEE 754-2008. Cette précision permet le flush-to-zero pour les denorms et l'arrondi vers zéro. De plus, votre filterscript les scripts ne doivent pas utiliser de types intégrés 32 bits et doivent spécifier une fonction racine personnalisée à l'aide de la méthode __attribute__((kernel)), car FilterScript n'accepte pas les pointeurs, ce qui définie par la signature par défaut de la fonction root().

Remarque:Bien que la plate-forme soit compatible avec Filterscript, prise en charge sera disponible dans SDK Tools version 21.0.1.

Pour obtenir une vue détaillée de toutes les modifications apportées aux API sous Android 4.2, consultez la Rapport sur les différences de l'API