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 explicitementandroid:exported="true"
.Cette modification ne s'applique que si vous définissez
android:targetSdkVersion
ouandroid: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'autorisationACCESS_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 dansSettings.System
qui ont été déplacés versSettings.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
etandroid:minSdkVersion
est inférieure à 17, votre application ne pourra pas modifier les paramètres qui ont ont été déplacés versSettings.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 votretargetSdkVersion
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 votreWebView
sous Android 4.2 ou version ultérieure. Si vous définissez le paramètretargetSdkVersion
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 appelerfinish()
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:
- Pour accéder au stockage interne, utilisez
getFilesDir()
,getCacheDir()
ouopenFileOutput()
. - Pour accéder au stockage externe, utilisez
getExternalFilesDir()
ougetExternalStoragePublicDirectory()
.
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 :
- 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 deandroid:layout_marginLeft
etandroid:layout_marginEnd
au lieu deandroid:layout_marginRight
.La classe
RelativeLayout
fournit également la mise en page correspondante. pour remplacer les positions gauche/droite, tels queandroid:layout_alignParentStart
par remplacezandroid:layout_alignParentLeft
etandroid:layout_toStartOf
au lieu deandroid:layout_toLeftOf
- 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 dansres/layout/
et vos mises en page optimisées pour le RTL dansres/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 :
Blends
Blur
Color matrix
3x3 convolve
5x5 convolve
Per-channel lookup table
Converting an Android YUV buffer to RGB
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éthodesset()
disponibles de chaque script intrinsèque pour définir les entrées et les options nécessaires. Enfin, appelez la méthodeforEach()
. 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 appelantaddKernel()
. Une fois tous les scripts ajoutés, créez les connexions entre eux en appelantaddConnection()
. Lorsque vous avez terminé d'ajouter les connexions, appelezcreate()
pour créer le groupe de scripts. Avant d'exécuter le groupe de scripts, spécifiez l'entréeAllocation
et le script initial à exécuter avecsetInput(Script.KernelID, Allocation)
et fournir la sortieAllocation
, où le résultat sera écrit et le script final dans avecsetOutput()
. Enfin, appelezexecute()
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 fonctionroot()
.
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