Niveau d'API: 18
Android 4.3 (JELLY_BEAN_MR2
)
est une mise à jour de Jelly Bean qui offre de nouvelles fonctionnalités aux utilisateurs
développeurs. Ce document présente les principaux
de nouvelles API.
En tant que développeur d'applications, nous vous conseillons de télécharger l'image système d'Android 4.3. et la plate-forme SDK de SDK Manager, dès que possible. Si vous ne disposez pas d'un appareil équipé d'Android 4.3 tester votre application, utiliser le système Android 4.3 pour tester votre application sur l'émulateur Android. Créez ensuite vos applications sur la plate-forme Android 4.3 pour commencer à utiliser la API les plus récentes.
Mettre à jour votre niveau d'API cible
Afin d'optimiser votre application pour les appareils équipés d'Android 4.3,
vous devez définir votre targetSdkVersion
sur
"18"
, installez-le sur une image système Android 4.3,
la tester, puis publier une mise à jour avec cette modification.
Vous pouvez utiliser des API dans Android 4.3 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 la gestion de la rétrocompatibilité, consultez la section Compatibilité avec différents
Versions de la plate-forme.
Diverses API sont également disponibles dans la bibliothèque Android Support pour vous permettre d'implémenter de nouvelles fonctionnalités sur les anciennes versions de la plateforme.
Pour plus d'informations sur le fonctionnement des niveaux d'API, consultez la page Qu'est-ce que l'API ? Niveau ?
Changements de comportement importants
Si vous avez déjà publié une application pour Android, sachez qu'elle peut par les modifications apportées à Android 4.3.
Si votre application utilise des intents implicites...
Il est possible que votre application ne fonctionne pas dans un environnement de profil limité.
Il est possible que les utilisateurs d'un environnement utilisant un profil limité
disposent de toutes les applications Android standards. Par exemple, un profil limité peut être associé au
navigateur Web et appli d'appareil photo désactivés. Votre application ne doit donc pas faire de suppositions
disponible, car si vous appelez startActivity()
sans passer par
vérifier si une application est disponible pour gérer Intent
;
votre application peut planter dans un profil limité.
Lorsque vous utilisez un intent implicite, vous devez toujours vérifier qu'une application est disponible pour gérer l'intent en appelant resolveActivity()
ou queryIntentActivities()
. Exemple :
Kotlin
val intent = Intent(Intent.ACTION_SEND) ... if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } else { Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show() }
Java
Intent intent = new Intent(Intent.ACTION_SEND); ... if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } else { Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show(); }
Si votre application dépend de comptes...
Il est possible que votre application ne fonctionne pas dans un environnement de profil limité.
Par défaut, les utilisateurs d'un environnement de profil restreint n'ont pas accès aux comptes utilisateur.
Si votre application dépend d'une Account
, elle peut planter ou se comporter
de manière inattendue lorsqu'elle est
utilisée dans un profil limité.
Si vous voulez empêcher les profils dont l'accès est limité d'utiliser votre application parce que votre
dépend d'informations de compte sensibles, spécifiez l'attribut android:requiredAccountType
dans le fichier <application>
de votre fichier manifeste
.
Pour autoriser les profils dont l'accès est limité à continuer à utiliser votre application alors qu'ils ne peuvent pas créer leurs propres comptes, vous pouvez soit désactiver les fonctionnalités de votre application qui nécessitent un compte ou autoriser les profils dont l'accès est limité à accéder aux comptes créés par l'utilisateur principal. Pour plus consultez la section ci-dessous pour savoir comment gérer les comptes d'assistance dans un profil limité.
Si votre application utilise VideoView...
Votre vidéo peut sembler plus petite sur Android 4.3.
Dans les versions précédentes d'Android, le widget VideoView
ne s'affiche pas correctement
a calculé que la valeur de "wrap_content"
pour layout_height
et layout_width
est identique à "match_parent"
Ainsi, bien que l'utilisation de "wrap_content"
pour la hauteur ou la largeur ait déjà fourni la mise en page vidéo souhaitée,
la taille de la vidéo risque d'être beaucoup plus petite sur Android 4.3 ou version ultérieure. Pour résoudre le problème, remplacez
"wrap_content"
avec "match_parent"
et vérifiez que votre vidéo s'affiche comme prévu sur
Android 4.3 et sur les versions antérieures.
Profils restreints
Sur les tablettes Android, les utilisateurs peuvent désormais créer des profils limités en fonction de l'utilisateur principal. Lorsque les utilisateurs créent un profil limité, ils peuvent activer des restrictions concernant, par exemple, les applications disponibles pour le profil. Un nouvel ensemble d'API dans Android 4.3 vous permet également de créer des applications des paramètres de restriction applicables aux applications que vous développez. Par exemple, avec les nouvelles API, vous pouvez permettent aux utilisateurs de contrôler le type de contenu disponible dans votre application lorsqu'elle s'exécute dans un un environnement de profil limité.
L'interface utilisateur permettant aux utilisateurs de contrôler les restrictions que vous avez créées est gérée par le
Application Paramètres. Pour que les paramètres de restriction
de votre appli soient visibles par l'utilisateur,
vous devez déclarer les restrictions fournies par votre application en créant un BroadcastReceiver
qui reçoit l'intent ACTION_GET_RESTRICTION_ENTRIES
. Le système appelle cet intent pour interroger
toutes les applications pour les restrictions disponibles, puis crée l'interface utilisateur pour permettre à l'utilisateur principal de
gérer les restrictions pour chaque fiche limitée.
Dans la méthode onReceive()
de
votre BroadcastReceiver
, vous devez créer un RestrictionEntry
pour chaque restriction fournie par votre application. Chaque RestrictionEntry
définit un titre et une description de restriction, ainsi que l'une des
types de données suivants:
TYPE_BOOLEAN
pour une restriction vrai ou faux.TYPE_CHOICE
pour une restriction comportant Plusieurs choix qui s'excluent mutuellement (cases d'option)TYPE_MULTI_SELECT
pour une restriction qui comporte plusieurs options qui ne s'excluent pas mutuellement (cases à cocher).
Vous placez ensuite tous les objets RestrictionEntry
dans un ArrayList
, puis vous le placez dans le résultat du broadcast receiver en tant que valeur du paramètre
Supplément de EXTRA_RESTRICTIONS_LIST
.
Le système crée l'interface utilisateur pour les restrictions de votre appli dans l'appli Paramètres et enregistre chacune d'elles
avec la clé unique que vous avez fournie pour chaque RestrictionEntry
. Lorsque l'utilisateur ouvre votre application, vous pouvez interroger les restrictions actuelles :
Appel de getApplicationRestrictions()
en cours.
Cela renvoie un Bundle
contenant les paires clé/valeur pour chaque restriction.
que vous avez défini avec les objets RestrictionEntry
.
Si vous souhaitez fournir des restrictions plus spécifiques qui ne peuvent pas être gérées par une valeur booléenne, un seul
choix et choix multiples, vous pouvez créer une activité dans laquelle l'utilisateur peut spécifier
des restrictions et autoriser les utilisateurs à ouvrir cette activité à partir des paramètres de restriction. Dans votre
broadcast receiver, incluez l'extra EXTRA_RESTRICTIONS_INTENT
dans le résultat Bundle
. Cet extra doit spécifier un Intent
indiquant la classe Activity
à lancer (utilisez
putParcelable()
pour transmettre EXTRA_RESTRICTIONS_INTENT
avec l'intent).
Lorsque l'utilisateur principal entre dans votre activité pour définir des restrictions personnalisées, votre
activité doit ensuite renvoyer un résultat contenant les valeurs de restriction dans un extra en utilisant soit
la clé EXTRA_RESTRICTIONS_LIST
ou EXTRA_RESTRICTIONS_BUNDLE
, selon que vous spécifiez ou non
des objets RestrictionEntry
ou des paires clé/valeur, respectivement.
Assurer la compatibilité avec les comptes d'un profil limité
Tous les comptes ajoutés à l'utilisateur principal sont disponibles dans un profil restreint, mais
comptes ne sont pas accessibles par défaut depuis les API AccountManager
.
Si vous tentez d'ajouter un compte avec AccountManager
alors que vous êtes dans un
vous n'obtiendrez pas un résultat. En raison de ces restrictions, vous disposez des éléments suivants :
trois options:
Pour accéder à un compte à partir d'un profil limité, vous devez ajouter l'attribut android:restrictedAccountType
à la balise <application>:
<application ... android:restrictedAccountType="com.example.account.type" >
Attention:L'activation de cet attribut l'accès de l'application aux comptes de l'utilisateur principal à partir de profils restreints ; Vous devez donc autoriser Uniquement si les informations affichées par votre application ne révèlent pas d'informations permettant d'identifier personnellement l'utilisateur d'informations personnelles considérées comme sensibles. Les paramètres système informent que votre application accorde des profils limités à son compte, ce qui doit être clair pour l'utilisateur. cet accès au compte est important pour le fonctionnement de votre application. Si possible, vous devez également fournir à l'utilisateur principal des contrôles de restriction adéquats qui définissent le niveau d'accès au compte ; est autorisé dans votre application.
Si vous souhaitez utiliser des comptes, mais que vous n'en avez pas réellement besoin pour l'accès
, vous pouvez vérifier la disponibilité d'un compte et désactiver certaines fonctionnalités lorsqu'elles ne le sont pas.
Vous devez d'abord vérifier si un compte existant est disponible. Sinon, demandez si
Vous pouvez créer un compte en appelant getUserRestrictions()
et en vérifiant l'extra DISALLOW_MODIFY_ACCOUNTS
dans le résultat. Si la valeur est true
,
vous devez désactiver toute fonctionnalité
de votre application qui nécessite l'accès aux comptes.
Exemple :
Kotlin
val um = context.getSystemService(Context.USER_SERVICE) as UserManager val restrictions: Bundle = um.userRestrictions if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) { // cannot add accounts, disable some functionality }
Java
UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); Bundle restrictions = um.getUserRestrictions(); if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) { // cannot add accounts, disable some functionality }
Remarque:Dans ce scénario, vous ne devez pas déclarer tout nouvel attribut dans votre fichier manifeste.
S'il est important que votre application ne soit pas disponible pour les profils dont l'accès est limité,
votre application dépend d'informations personnelles sensibles dans un compte (et étant donné que les profils
ne pouvez pas ajouter de nouveaux comptes pour le moment), ajoutez
l'attribut android:requiredAccountType
à la balise <application>:
<application ... android:requiredAccountType="com.example.account.type" >
Par exemple, l'application Gmail utilise cet attribut pour se désactiver pour les profils dont l'accès est limité. car l'adresse e-mail personnelle du propriétaire ne doit pas être disponible pour les profils dont l'accès est limité.
Sans fil et connectivité
Bluetooth à basse consommation (modèle intelligent)
Android est désormais compatible avec le Bluetooth à basse consommation (LE) avec de nouvelles API dans android.bluetooth
.
Grâce aux nouvelles API, vous pouvez créer des applications Android qui communiquent avec la technologie Bluetooth Low Energy.
les périphériques tels que les cardiofréquencemètres et les podomètres.
La technologie Bluetooth LE étant une fonctionnalité matérielle qui n'est pas
Les appareils Android, vous devez déclarer un <uses-feature>
dans le fichier manifeste
pour "android.hardware.bluetooth_le"
:
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
Si vous connaissez déjà les API Bluetooth Classic d'Android, notez que l'utilisation du
Les API Bluetooth LE présentent quelques différences. Plus important encore, vous disposez désormais d'une classe BluetoothManager
que vous devez utiliser pour certaines opérations de haut niveau.
comme l'acquisition d'un BluetoothAdapter
, l'obtention d'une liste
appareils et vérifier l'état d'un appareil. Par exemple, voici comment obtenir
BluetoothAdapter
:
Kotlin
val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager bluetoothAdapter = bluetoothManager.adapter
Java
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); bluetoothAdapter = bluetoothManager.getAdapter();
Pour détecter les périphériques Bluetooth LE, appelez startLeScan()
sur le BluetoothAdapter
, en lui transmettant une implémentation
de l'interface BluetoothAdapter.LeScanCallback
. Lorsque le Bluetooth
détecte un périphérique Bluetooth LE, votre implémentation BluetoothAdapter.LeScanCallback
reçoit un appel vers
onLeScan()
. Ce
fournit un objet BluetoothDevice
représentant
appareil détecté, la valeur RSSI de l'appareil et un tableau d'octets contenant le nom de l'appareil
l'enregistrement publicitaire.
Si vous ne souhaitez rechercher que des types de périphériques spécifiques, vous pouvez appeler startLeScan()
et inclure un tableau d'objets UUID
spécifiant les services GATT compatibles avec votre application.
Remarque:Vous ne pouvez rechercher que des appareils Bluetooth LE ou rechercher les appareils Bluetooth classiques à l'aide des API précédentes. Vous ne pouvez pas rechercher à la fois LE et Classic plusieurs appareils Bluetooth en même temps.
Pour vous connecter ensuite à un périphérique Bluetooth LE, appelez connectGatt()
sur le
BluetoothDevice
, en lui transmettant une implémentation de
BluetoothGattCallback
Votre implémentation de BluetoothGattCallback
reçoit des rappels concernant la connectivité.
avec l'appareil et d'autres événements. Cet événement a lieu pendant le onConnectionStateChange()
rappel indiquant que vous pouvez commencer à communiquer avec l'appareil si la méthode transmet STATE_CONNECTED
comme nouvel état.
L'accès aux fonctionnalités Bluetooth sur un appareil nécessite également que votre application demande certaines Autorisations de l'utilisateur Bluetooth. Pour en savoir plus, consultez le guide de l'API Bluetooth à basse consommation.
Mode Recherche Wi-Fi uniquement
Lors d'une tentative d'identification de la position de l'utilisateur, Android peut utiliser le Wi-Fi pour déterminer l'emplacement en scannant les points d'accès à proximité. Toutefois, les utilisateurs laissent souvent le Wi-Fi désactivé préserver l'autonomie de la batterie, ce qui nuit à la précision des données de localisation. Android inclut désormais mode recherche uniquement qui permet au Wi-Fi de l'appareil de rechercher les points d'accès pour obtenir la position sans point d'accès, ce qui réduit considérablement l'utilisation de la batterie.
Si vous souhaitez connaître la position de l'utilisateur, mais que le Wi-Fi est actuellement désactivé, vous pouvez demander à
d'activer le mode recherche Wi-Fi uniquement en appelant startActivity()
avec l'action ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE
.
Configuration Wi-Fi
Les nouvelles API WifiEnterpriseConfig
permettent aux services d'entreprise de
d'automatiser la configuration Wi-Fi pour les appareils gérés.
Réponse rapide pour les appels entrants
Depuis Android 4.0, une fonction
appelée « Réponse rapide » permet aux utilisateurs de répondre
vous recevez immédiatement un SMS sans avoir à répondre à l'appel ni à déverrouiller l'appareil.
Jusqu'à présent, ces messages rapides étaient toujours gérés par l'application de chat par défaut. Désormais toutes les applis
peut déclarer sa capacité à gérer ces messages en créant un Service
.
avec un filtre d'intent pour ACTION_RESPOND_VIA_MESSAGE
.
Lorsque l'utilisateur répond à un appel entrant avec une réponse rapide, l'application Téléphone envoie
l'intent ACTION_RESPOND_VIA_MESSAGE
par un URI ;
en décrivant le destinataire (l'appelant) et l'extra EXTRA_TEXT
avec le message que l'utilisateur
souhaite envoyer. Lorsque votre service reçoit l'intent, il doit le transmettre
le message et s'arrête immédiatement (votre application ne doit afficher aucune activité).
Pour recevoir cet intent, vous devez déclarer l'autorisation SEND_RESPOND_VIA_MESSAGE
.
Multimédia
Améliorations apportées à MediaExtractor et MediaCodec
Android vous permet désormais de créer plus facilement vos propres créations
Lecteurs de streaming sur HTTP (DASH) conformes à la norme ISO/IEC 23009-1
à l'aide des API existantes dans MediaCodec
et MediaExtractor
. Le framework sur lequel reposent ces API a été mis à jour pour prendre en charge
l'analyse des fichiers MP4 fragmentés, mais votre application est toujours responsable de l'analyse des métadonnées de la description de la présentation du média.
et transmettre les flux individuels à MediaExtractor
.
Si vous souhaitez utiliser DASH avec du contenu chiffré, notez que la méthode getSampleCryptoInfo()
renvoie les métadonnées MediaCodec.CryptoInfo
décrivant la structure de chaque contenu multimédia chiffré.
échantillon. De plus, la méthode getPsshInfo()
a été ajoutée à
MediaExtractor
afin d'accéder aux métadonnées PSSH de votre contenu multimédia DASH.
Cette méthode renvoie un mappage d'objets UUID
en octets, avec les
UUID
spécifiant le schéma de chiffrement et les octets correspondant aux données
à ce schéma.
Media DRM
La nouvelle classe MediaDrm
fournit une solution modulaire pour les droits numériques.
(DRM) à votre contenu multimédia en séparant les problèmes DRM de la lecture du contenu multimédia. Pour
cette séparation des API vous permet de lire du contenu chiffré Widevine sans avoir
pour utiliser le format multimédia Widevine. Cette solution DRM est aussi compatible
avec le chiffrement commun DASH,
vous pouvez utiliser différents schémas DRM
pour votre contenu en streaming.
Vous pouvez utiliser MediaDrm
pour obtenir des messages de requête de clé opaques et traiter
des messages de réponse clé du serveur
pour l'acquisition et le provisionnement des licences. Votre application est
responsable de la gestion de la communication
réseau avec les serveurs ; La classe MediaDrm
permet uniquement de générer et de traiter les messages.
Les API MediaDrm
sont destinées à être utilisées avec les
API MediaCodec
introduites dans Android 4.1 (niveau d'API 16)
y compris MediaCodec
pour encoder et décoder votre contenu, MediaCrypto
pour gérer le contenu chiffré et MediaExtractor
pour extraire et démuxer votre contenu.
Vous devez d'abord construire MediaExtractor
et
Objets MediaCodec
. Vous pouvez ensuite accéder à l'outil d'identification
UUID
, généralement à partir des métadonnées du contenu, et l'utiliser pour créer une
une instance d'un objet MediaDrm
avec son constructeur.
Encodage vidéo depuis une surface
Android 4.1 (niveau d'API 16) a ajouté la classe MediaCodec
pour les applications de bas niveau
l'encodage et le décodage de contenus multimédias. Lors de l'encodage vidéo, sous Android 4.1, vous devez fournir
les contenus multimédias avec un tableau ByteBuffer
, mais Android 4.3 vous permet désormais d'utiliser un Surface
comme entrée d'un encodeur. Par exemple, cela vous permet d'encoder les entrées
à partir d'un fichier vidéo existant ou à l'aide d'images générées à partir d'OpenGL ES.
Pour utiliser un Surface
comme entrée de votre encodeur, appelez d'abord configure()
pour votre MediaCodec
.
Appelez ensuite createInputSurface()
pour recevoir le Surface
sur lequel vous pouvez diffuser votre contenu multimédia.
Par exemple, vous pouvez utiliser le Surface
donné comme fenêtre pour un OpenGL
le contexte en le transmettant à eglCreateWindowSurface()
. Ensuite, lors du rendu de la surface, appelez eglSwapBuffers()
pour transmettre le cadre à MediaCodec
.
Pour commencer l'encodage, appelez start()
au niveau de MediaCodec
. Lorsque vous avez terminé, appelez signalEndOfInputStream()
pour terminer l'encodage et appeler release()
sur la
Surface
Multimédia
La nouvelle classe MediaMuxer
permet le multiplexage entre un flux audio.
et un flux vidéo. Ces API servent d'équivalents à MediaExtractor
ajoutée dans Android 4.2 pour le démultiplexage des contenus multimédias.
Les formats de sortie compatibles sont définis dans MediaMuxer.OutputFormat
. Actuellement,
Le format de sortie MP4 est le seul compatible, et MediaMuxer
le prend actuellement en charge
un seul flux audio et/ou un seul flux vidéo à la fois.
MediaMuxer
est principalement conçu pour fonctionner avec MediaCodec
Vous pouvez donc traiter la vidéo via MediaCodec
, puis enregistrer
dans un fichier MP4 via MediaMuxer
. Vous pouvez également utiliser MediaMuxer
en combinaison avec MediaExtractor
pour effectuer
sans code ni décodage.
Progression de la lecture et barre de lecture pour RemoteControlClient
Dans Android 4.0 (niveau d'API 14), RemoteControlClient
a été ajouté à
activer les commandes de lecture multimédia des clients de la télécommande, telles que les commandes disponibles sur la
l'écran de verrouillage. Android 4.3 permet désormais à ces manettes d'afficher la lecture
et les commandes de lecture. Si vous avez activé la télécommande pour votre
application multimédia avec les API RemoteControlClient
, vous pouvez autoriser la lecture
en utilisant deux nouvelles interfaces.
Tout d'abord, vous devez activer l'option FLAG_KEY_MEDIA_POSITION_UPDATE
en la transmettant à
setTransportControlsFlags()
Implémentez ensuite les deux nouvelles interfaces suivantes:
RemoteControlClient.OnGetPlaybackPositionListener
- Cela inclut le rappel
onGetPlaybackPosition()
, qui demande la position actuelle. de vos contenus multimédias lorsque la télécommande doit mettre à jour la progression dans son interface utilisateur. RemoteControlClient.OnPlaybackPositionUpdateListener
- Cela inclut le rappel
onPlaybackPositionUpdate()
, qui indique à votre application le nouveau code temporel de votre contenu multimédia lorsque l'utilisateur lance la lecture à l'aide de la méthode de la télécommande.Une fois la lecture mise à jour avec la nouvelle position, appelez
setPlaybackState()
pour indiquer la l'état, la position et la vitesse de lecture.
Une fois ces interfaces définies, vous pouvez les définir pour votre RemoteControlClient
en appelant setOnGetPlaybackPositionListener()
et
setPlaybackPositionUpdateListener()
, respectivement.
Graphiques
Compatibilité avec OpenGL ES 3.0
Android 4.3 ajoute des interfaces Java et est compatible en natif avec OpenGL ES 3.0. Nouvelles fonctionnalités clés fournies dans OpenGL ES 3.0 incluent:
- Accélération des effets visuels avancés
- Compression de texture ETC2/EAC de haute qualité en tant que fonctionnalité standard
- Nouvelle version du langage d'ombrage GLSL ES compatible avec les entiers et la virgule flottante 32 bits
- Rendu de texture avancé
- Standardisation plus large de la taille des textures et des formats de tampon de rendu
L'interface Java d'OpenGL ES 3.0 sur Android est fournie avec GLES30
.
Lorsque vous utilisez OpenGL ES 3.0, veillez à le déclarer dans votre fichier manifeste avec la
<uses-feature>
et l'attribut android:glEsVersion
. Exemple :
<manifest> <uses-feature android:glEsVersion="0x00030000" /> ... </manifest>
Et n'oubliez pas de spécifier le contexte OpenGL ES en appelant setEGLContextClientVersion()
,
en transmettant 3
comme version.
Pour en savoir plus sur l'utilisation d'OpenGL ES, y compris sur la façon de vérifier la compatibilité de l'appareil Version d'OpenGL ES au moment de l'exécution. Consultez le guide de l'API OpenGL ES.
Mappage de mip pour les drawables
L'utilisation d'un mipmap comme source pour votre bitmap ou drawable est un moyen simple de fournir un de qualité et différentes échelles d'affichage, ce qui peut s'avérer particulièrement utile mise à l'échelle pendant une animation.
Android 4.2 (niveau d'API 17) prend en charge les mipmaps dans Bitmap
.
Android remplace les images Mip dans votre Bitmap
lorsque vous
a fourni une source de mipmap et ont activé setHasMipMap()
. Désormais, dans Android 4.3, vous pouvez également activer les mipmaps pour un objet BitmapDrawable
en fournissant un élément mipmap et
en définissant l'attribut android:mipMap
dans un fichier de ressources bitmap ou en appelant hasMipMap()
.
Interface utilisateur
Afficher les superpositions
La nouvelle classe ViewOverlay
fournit une couche transparente au-dessus de
une View
sur laquelle vous pouvez ajouter du contenu visuel et qui n'affecte pas
la hiérarchie de mise en page. Vous pouvez obtenir un ViewOverlay
pour n'importe quel View
en appelant getOverlay()
. La superposition
a toujours la même taille et la même position que la vue hôte (la vue à partir de laquelle la création a été créée) ;
vous permettant d'ajouter du contenu qui apparaît devant la vue de l'hôte, mais qui ne peut pas s'étendre
les limites de cette vue hôte.
L'utilisation d'un ViewOverlay
est particulièrement utile lorsque vous souhaitez créer
Animations telles que le déplacement d'une vue en dehors de son conteneur ou le déplacement d'éléments sur l'écran
sans affecter la hiérarchie des vues. Toutefois, comme la zone utilisable d'une superposition est
à la même zone que la vue hôte, si vous souhaitez animer une vue en se déplaçant à l'extérieur
sa position dans la mise en page, vous devez utiliser une superposition d'une vue parent dont
les limites de la mise en page.
Lorsque vous créez une superposition pour une vue de widget telle qu'une Button
, vous
vous pouvez ajouter des objets Drawable
à la superposition en appelant
add(Drawable)
Si vous appelez getOverlay()
pour une vue de mise en page, telle que RelativeLayout
,
l'objet renvoyé est ViewGroupOverlay
. La
La classe ViewGroupOverlay
est une sous-classe
de ViewOverlay
, qui vous permet aussi d'ajouter View
en appelant add(View)
.
Remarque:Tous les drawables et les vues que vous ajoutez à une superposition ne sont que visuels. Ils ne peuvent pas recevoir d'événements de sélection ni d'entrée.
Par exemple, le code suivant anime une vue glissant vers la droite en la plaçant dans la superposition de la vue parent, puis exécuter une animation de traduction sur cette vue:
Kotlin
val view: View? = findViewById(R.id.view_to_remove) val container: ViewGroup? = view?.parent as ViewGroup container?.apply { overlay.add(view) ObjectAnimator.ofFloat(view, "translationX", right.toFloat()) .start() }
Java
View view = findViewById(R.id.view_to_remove); ViewGroup container = (ViewGroup) view.getParent(); container.getOverlay().add(view); ObjectAnimator anim = ObjectAnimator.ofFloat(view, "translationX", container.getRight()); anim.start();
Mise en page avec contours optiques
Pour les vues contenant des images de fond neuf-patch, vous pouvez désormais indiquer qu'elles doivent être alignées sur les vues voisines en fonction de la règle les limites de l'image de fond plutôt que que le "clip" les limites de la vue.
Par exemple, les figures 1 et 2 montrent chacune la même mise en page, mais la version de la figure 1 est à l'aide des limites de rognage (comportement par défaut), tandis que la figure 2 utilise les contours optiques. En effet, les images Nine-Patch utilisés pour le bouton et le cadre photo incluent une marge intérieure autour des bords, elles ne semblent pas alignées les unes avec les autres ni avec le texte lorsque vous utilisez des limites de rognage.
Remarque:Sur les captures d'écran des figures 1 et 2, de la mise en page. paramètre pour les développeurs activé. Pour chaque vue, les lignes rouges indiquent le côté optique les limites, les lignes bleues indiquent les limites du clip et le rose indique les marges.
Pour aligner les vues en fonction de leurs limites optiques, définissez l'attribut android:layoutMode
sur "opticalBounds"
dans l'une des mises en page parentes. Exemple :
<LinearLayout android:layoutMode="opticalBounds" ... >
Pour que cela fonctionne, les images neuf-patch appliquées à l'arrière-plan de vos vues doivent spécifier les limites optiques à l'aide de lignes rouges en bas et à droite du fichier Nine-Patch (comme comme illustré dans la figure 3). Les lignes rouges indiquent la région à soustraire de les limites du clip, en conservant les limites optiques de l'image.
Lorsque vous activez les limites optiques pour une ViewGroup
dans votre mise en page, toutes
Les vues descendantes héritent du mode de mise en page "Contours optiques", sauf si vous le remplacez par un élément "Grouper par"
en définissant android:layoutMode
sur "clipBounds"
. Tous les éléments de mise en page respectent également les
les limites optiques des vues de leur enfant, en adaptant leurs propres limites sur la base des limites optiques de
les vues qu'ils contiennent. Toutefois, les éléments de mise en page (sous-classes de ViewGroup
)
ne sont actuellement pas compatibles avec les limites optiques des images Nine-Patch appliquées à leur propre arrière-plan.
Si vous créez une vue personnalisée en sous-classant View
, ViewGroup
ou l'une de ses sous-classes, votre vue héritera de ces comportements de liaison optique.
Remarque:Tous les widgets compatibles avec le thème Holo ont été mis à jour.
avec des limites optiques, y compris Button
, Spinner
,
EditText
et d'autres sources. Vous pouvez donc immédiatement bénéficier du paramètre
Attribut android:layoutMode
à "opticalBounds"
si votre application applique un thème Holo
(Theme.Holo
, Theme.Holo.Light
, etc.).
Pour spécifier des limites optiques pour vos propres images Nine-Patch à l'aide de l'outil Draw 9-patch, maintenez la touche Ctrl enfoncée lorsque je clique sur les pixels de bordure.
Animation pour les valeurs Rect
Vous pouvez désormais créer une animation entre deux valeurs Rect
avec le nouveau RectEvaluator
. Cette nouvelle classe est une implémentation de TypeEvaluator
que vous pouvez transmettre à ValueAnimator.setEvaluator()
.
Écouteur d'attachement de fenêtre et de focus
Auparavant, si vous vouliez savoir à quel moment votre vue était associée/dissociée à la fenêtre ou
lorsque son objectif changeait, vous deviez remplacer la classe View
par
implémenter onAttachedToWindow()
et onDetachedFromWindow()
, ou onWindowFocusChanged()
, respectivement.
Pour recevoir des événements d'association et de dissociation, vous pouvez maintenant implémenter ViewTreeObserver.OnWindowAttachListener
et le définir sur une vue avec
addOnWindowAttachListener()
Pour recevoir des événements de sélection, vous pouvez implémenter ViewTreeObserver.OnWindowFocusChangeListener
et le définir sur une vue avec
addOnWindowFocusChangeListener()
Compatibilité avec le surbalayage TV
Pour vous assurer que votre application occupe tout l'écran sur chaque téléviseur, vous pouvez désormais activer le surbalayage
pour la mise en page de votre application. Le mode surbalayage est déterminé par l'indicateur FLAG_LAYOUT_IN_OVERSCAN
, que vous pouvez activer avec les thèmes de plate-forme tels que
Theme_DeviceDefault_NoActionBar_Overscan
ou en activant
Style windowOverscan
dans un thème personnalisé.
Orientation de l'écran
<activity>
screenOrientation
de la balise
prend désormais en charge des valeurs supplémentaires pour respecter les préférences de l'utilisateur pour la rotation automatique:
"userLandscape"
- se comporte de la même manière que
"sensorLandscape"
, sauf si l'utilisateur désactive la rotation automatique ; elle se verrouille en mode paysage normal et ne se retourne pas. "userPortrait"
- Comportement identique à celui de
"sensorPortrait"
, sauf si l'utilisateur désactive la rotation automatique elle se verrouille en mode portrait normal et ne se retourne pas. "fullUser"
- se comporte comme
"fullSensor"
et permet une rotation dans les quatre sens, sauf Si l'utilisateur désactive la rotation automatique, l'orientation se verrouille dans l'orientation préférée de l'utilisateur.
De plus, vous pouvez désormais déclarer "locked"
pour verrouiller l'orientation de votre application
l'orientation actuelle de l'écran.
Animations de rotation
Le nouveau champ rotationAnimation
dans
WindowManager
vous permet de choisir entre l'une des trois animations que vous
à utiliser lorsque le système
change d'orientation d'écran. Les trois animations sont les suivantes:
Remarque:Ces animations ne sont disponibles que si vous avez configuré votre activité pour utiliser le mode plein écran. que vous pouvez activer avec des thèmes tels que Theme.Holo.NoActionBar.Fullscreen
.
Par exemple, voici comment activer le fondu enchaîné Animation:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val params: WindowManager.LayoutParams = window.attributes params.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE window.attributes = params ... }
Java
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); WindowManager.LayoutParams params = getWindow().getAttributes(); params.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE; getWindow().setAttributes(params); ... }
Entrée utilisateur
Nouveaux types de capteurs
Le nouveau capteur TYPE_GAME_ROTATION_VECTOR
vous permet de détecter les rotations de l'appareil sans vous soucier des interférences magnétiques. Contrairement au capteur TYPE_ROTATION_VECTOR
, le TYPE_GAME_ROTATION_VECTOR
n'est pas basé sur le nord magnétique.
Les nouveaux capteurs TYPE_GYROSCOPE_UNCALIBRATED
et TYPE_MAGNETIC_FIELD_UNCALIBRATED
fournissent des données brutes
des estimations de biais. Autrement dit, les éléments TYPE_GYROSCOPE
et TYPE_MAGNETIC_FIELD
existants
les capteurs fournissent des données qui prennent en compte le biais estimé dû à la dérive gyroscopique et au fer dur
sur l'appareil, respectivement. Au contraire, la nouvelle métrique "non calibrée" de ces capteurs fournissent
les données brutes du capteur et
les valeurs de biais estimées séparément. Ces capteurs permettent
vous pouvez effectuer un étalonnage personnalisé des données du capteur en améliorant l'estimation du biais avec
des données externes.
Écouteur des notifications
Android 4.3 ajoute une nouvelle classe de service, NotificationListenerService
, qui permet à votre application de recevoir des informations sur les nouvelles notifications au fur et à mesure qu'elles sont publiées par le système.
Si votre application utilise actuellement les API des services d'accessibilité pour accéder aux notifications système, vous devez la mettre à jour pour qu'elle utilise ces API à la place.
Contacts Provider
Requête pour "contactables"
La nouvelle requête du fournisseur de contacts, Contactables.CONTENT_URI
, est un moyen efficace d'obtenir un Cursor
contenant toutes les adresses e-mail et numéros de téléphone appartenant à tous les contacts correspondant à la requête spécifiée.
Requête pour les deltas de contacts
De nouvelles API ont été ajoutées à Contacts Provider. Elles vous permettent d'interroger efficacement les dernières modifications apportées aux données des contacts. Auparavant, votre application pouvait être avertie en cas de modification dans les données des contacts, mais vous ne sachiez pas exactement ce qui a changé et devez récupérer tous les contacts, puis les parcourir pour découvrir la modification.
Pour suivre les modifications apportées aux insertions et aux mises à jour, vous pouvez désormais inclure le paramètre CONTACT_LAST_UPDATED_TIMESTAMP
dans votre sélection afin d'interroger uniquement les contacts qui ont changé depuis votre dernière requête auprès du fournisseur.
Pour savoir quels contacts ont été supprimés, le nouveau tableau ContactsContract.DeletedContacts
fournit un journal des contacts qui ont été supprimés (mais chaque contact supprimé est conservé dans ce tableau pendant une durée limitée). Comme pour CONTACT_LAST_UPDATED_TIMESTAMP
, vous pouvez utiliser le nouveau paramètre de sélection CONTACT_DELETED_TIMESTAMP
pour vérifier quels contacts ont été supprimés depuis la dernière fois que vous avez interrogé le fournisseur. La table contient également la constante DAYS_KEPT_MILLISECONDS
, qui indique le nombre de jours (en millisecondes) pendant lesquels le journal sera conservé.
De plus, le fournisseur de contacts diffuse désormais l'action CONTACTS_DATABASE_CREATED
lorsque l'utilisateur
efface le stockage des contacts via le menu des paramètres système, recréant ainsi
Base de données des fournisseurs de contacts. Elle sert à signaler aux applis qu'elles doivent supprimer tous les contacts
des informations stockées et l'actualiser
avec une nouvelle requête.
Pour obtenir un exemple de code utilisant ces API afin de vérifier les modifications apportées aux contacts, consultez exemple disponible dans le téléchargement de SDK Samples.
Localisation
Meilleure compatibilité avec le texte bidirectionnel
Les versions précédentes d'Android prennent en charge les langues et la mise en page qui se lisent de droite à gauche.
mais parfois, ne gèrent pas correctement
le texte à sens mixte. C'est pourquoi Android 4.3 ajoute les API BidiFormatter
qui vous aident à mettre en forme correctement du texte dans le sens opposé.
sans en brouiller une partie.
Par exemple, lorsque vous souhaitez créer une phrase avec une variable de chaîne, telle que "Essayez avec
15 Bay Street, Laurel, CA?", vous transmettez normalement une ressource de chaîne localisée et la variable à
String.format()
:
Kotlin
val suggestion = String.format(resources.getString(R.string.did_you_mean), address)
Java
Resources res = getResources(); String suggestion = String.format(res.getString(R.string.did_you_mean), address);
Cependant, si les paramètres régionaux sont l'hébreu, la chaîne mise en forme se présente comme suit:
Continuer à faire le 15 Bay Street, Laurel, CA ?
C'est faux parce que le « 15 » doit se trouver à gauche de "Bay Street". La solution consiste à utiliser BidiFormatter
et sa méthode unicodeWrap()
. Par exemple, le code ci-dessus devient:
Kotlin
val bidiFormatter = BidiFormatter.getInstance() val suggestion = String.format( resources.getString(R.string.did_you_mean), bidiFormatter.unicodeWrap(address) )
Java
Resources res = getResources(); BidiFormatter bidiFormatter = BidiFormatter.getInstance(); String suggestion = String.format(res.getString(R.string.did_you_mean), bidiFormatter.unicodeWrap(address));
Par défaut, unicodeWrap()
utilise le
l'heuristique d'estimation de l'orientation du premier fort, qui peut être inexacte si la première
l'orientation du texte ne représente pas l'orientation appropriée du contenu dans son ensemble.
Si nécessaire, vous pouvez spécifier une autre heuristique en transmettant l'une des constantes TextDirectionHeuristic
de TextDirectionHeuristics
.
à unicodeWrap()
.
Remarque:Ces nouvelles API sont également disponibles pour les versions précédentes.
d'Android grâce au support Android
bibliothèque, avec la classe BidiFormatter
et les API associées.
Services d'accessibilité
Gérer les événements clés
Un AccessibilityService
peut désormais recevoir un rappel pour
les événements d'entrée de touche avec la méthode de rappel onKeyEvent()
. Cela permet à votre service d'accessibilité de gérer les entrées
des périphériques d'entrée basés sur des touches, comme un clavier, et traduisent ces événements en actions spéciales qui
n'étaient auparavant possibles qu'avec la saisie tactile ou avec la croix directionnelle de l'appareil.
Sélectionner du texte et le copier/coller
AccessibilityNodeInfo
fournit désormais des API qui permettent
Un élément AccessibilityService
pour sélectionner, couper, copier et coller
dans un nœud.
Pour spécifier la sélection de texte à couper ou copier, votre service d'accessibilité peut utiliser la nouvelle
action, ACTION_SET_SELECTION
, en transmettant
avec la sélection des positions de début et de fin avec ACTION_ARGUMENT_SELECTION_START_INT
et ACTION_ARGUMENT_SELECTION_END_INT
.
Vous pouvez également sélectionner du texte en manipulant la position du curseur à l'aide de la
action, ACTION_NEXT_AT_MOVEMENT_GRANULARITY
(auparavant uniquement pour déplacer la position du curseur) et ajouter l'argument ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
.
Vous pouvez ensuite couper ou copier avec ACTION_CUT
,
ACTION_COPY
, puis collez-le avec
ACTION_PASTE
Remarque:Ces nouvelles API sont également disponibles pour les versions précédentes.
d'Android grâce au support Android
bibliothèque, avec le AccessibilityNodeInfoCompat
.
Déclarer les fonctionnalités d'accessibilité
À partir d'Android 4.3, un service d'accessibilité doit déclarer les fonctionnalités d'accessibilité
dans son fichier de métadonnées afin d'utiliser certaines fonctionnalités d'accessibilité. Si la capacité n'est pas
demandée dans le fichier de métadonnées, il s'agit d'une opération no-op. Pour déclarer le paramètre
fonctionnalités d'accessibilité, vous devez utiliser des attributs XML correspondant aux différents
"capacité" constantes dans AccessibilityServiceInfo
.
Par exemple, si un service ne demande pas la capacité flagRequestFilterKeyEvents
,
il ne recevra pas d'événements clés.
Tests et débogage
Tests automatisés de l'interface utilisateur
La nouvelle classe UiAutomation
fournit des API qui vous permettent de simuler des utilisateurs
pour l'automatisation des tests. À l'aide des API AccessibilityService
de la plate-forme, UiAutomation
Les API vous permettent d'inspecter le contenu de l'écran et d'injecter des événements de clavier et des événements tactiles arbitraires.
Pour obtenir une instance de UiAutomation
, appelez Instrumentation.getUiAutomation()
. Dans la commande
pour que cela fonctionne, vous devez fournir l'option -w
avec la commande instrument
lorsque vous exécutez votre InstrumentationTestCase
à partir de adb shell
.
Avec l'instance UiAutomation
, vous pouvez exécuter des événements arbitraires pour tester
votre application en appelant executeAndWaitForEvent()
, en lui transmettant un Runnable
à effectuer, un délai avant expiration
durée de l'opération et une implémentation de l'interface UiAutomation.AccessibilityEventFilter
. C'est dans votre implémentation UiAutomation.AccessibilityEventFilter
que vous recevrez un appel
qui vous permet de filtrer les événements qui vous intéressent pour déterminer
l'échec d'un scénario de test donné.
Pour observer tous les événements pendant un test, créez une implémentation de UiAutomation.OnAccessibilityEventListener
et transmettez-la à setOnAccessibilityEventListener()
.
Votre interface d'écouteur reçoit ensuite un appel à onAccessibilityEvent()
.
chaque fois qu'un événement se produit, la réception d'un objet AccessibilityEvent
décrivant l'événement.
Les API UiAutomation
exposent plusieurs autres opérations.
à un niveau très bas pour encourager le développement d'outils de test de l'interface utilisateur tels que uiautomator. Par exemple,
UiAutomation
peut également:
- Injecter des événements d'entrée
- Modifier l'orientation de l'écran
- Réaliser des captures d'écran
Et surtout, pour les outils de test de l'interface utilisateur, les API UiAutomation
fonctionnent
au-delà des limites de l'application, contrairement à Instrumentation
.
Événements Systrace pour les applis
Android 4.3 ajoute la classe Trace
avec deux méthodes statiques :
beginSection()
et endSection()
,
qui vous permettent de définir des blocs de code
à inclure dans le rapport Systrace. En créant
de code traçable dans votre application, les journaux Systrace vous fournissent
une analyse des endroits où le ralentissement
se produit dans votre application.
Pour en savoir plus sur l'utilisation de l'outil Systrace, consultez Analyser l'affichage et les performances avec Systrace.
Sécurité
Magasin de clés Android pour les clés privées d'application
Android propose désormais un fournisseur de sécurité Java personnalisé dans KeyStore
Android Key Store, qui vous permet de générer et d'enregistrer des clés privées
peuvent être vues et utilisées
uniquement par votre application. Pour charger Android Key Store, transmettez
"AndroidKeyStore"
à KeyStore.getInstance()
.
Pour gérer les identifiants privés de votre application dans Android Key Store, générez une nouvelle clé avec
KeyPairGenerator
avec KeyPairGeneratorSpec
. Tout d'abord
Obtenez une instance de KeyPairGenerator
en appelant getInstance()
. Appelez ensuite
initialize()
, en lui transmettant une instance de
KeyPairGeneratorSpec
, que vous pouvez obtenir en utilisant
KeyPairGeneratorSpec.Builder
Enfin, obtenez votre KeyPair
en appelant generateKeyPair()
.
Stockage des identifiants matériels
Android prend aussi désormais en charge le stockage intégré au matériel pour votre KeyChain
les identifiants, ce qui renforce la sécurité en rendant les clés indisponibles pour l'extraction. Autrement dit, une fois
se trouvent dans un magasin de clés intégré au matériel (élément sécurisé, TPM ou TrustZone), elles peuvent être utilisées
des opérations cryptographiques, mais le matériel
de clé privée ne peut pas être exporté. Même le noyau du système d’exploitation
ne peuvent pas accéder à ce matériel de clé. Tous les appareils Android ne prennent pas en charge le stockage
vous pouvez vérifier, au moment de l'exécution, si le stockage intégré au matériel est disponible en appelant
KeyChain.IsBoundKeyAlgorithm()
Déclarations dans le fichier manifeste
Fonctionnalités obligatoires pouvant être déclarées
Les valeurs suivantes sont désormais acceptées dans <uses-feature>
pour vous assurer que votre application n'est installée que sur les appareils qui offrent les fonctionnalités
dont votre application a besoin.
FEATURE_APP_WIDGETS
- Déclare que votre application fournit un widget et ne doit être installée que sur les appareils qui
inclure un écran d'accueil ou un emplacement similaire où les utilisateurs peuvent intégrer des widgets d'application.
Exemple :
<uses-feature android:name="android.software.app_widgets" android:required="true" />
FEATURE_HOME_SCREEN
- Déclare que votre application se comporte comme un écran d'accueil de remplacement et ne doit être installée que sur
les appareils compatibles avec les applications tierces sur l'écran d'accueil.
Exemple :
<uses-feature android:name="android.software.home_screen" android:required="true" />
FEATURE_INPUT_METHODS
- Déclare que votre application fournit un mode de saisie personnalisé (un clavier créé avec
InputMethodService
) et qu'elle ne doit être installée que sur les appareils qui sont compatibles avec des modes de saisie tiers. Exemple :<uses-feature android:name="android.software.input_methods" android:required="true" />
FEATURE_BLUETOOTH_LE
- Déclare que votre application utilise les API Bluetooth à basse consommation et ne doit être installée que sur les appareils
capables de communiquer avec d'autres appareils
via la technologie Bluetooth Low Energy.
Exemple :
<uses-feature android:name="android.software.bluetooth_le" android:required="true" />
Autorisations utilisateur
Les valeurs suivantes sont désormais acceptées dans <uses-permission>
pour déclarer
les autorisations dont votre application a besoin pour accéder à certaines API.
BIND_NOTIFICATION_LISTENER_SERVICE
- Requis pour utiliser les nouvelles API
NotificationListenerService
. SEND_RESPOND_VIA_MESSAGE
- Obligatoire pour recevoir la
ACTION_RESPOND_VIA_MESSAGE
l'intention.
Pour obtenir une vue détaillée de toutes les modifications apportées aux API sous Android 4.3, consultez la Rapport sur les différences de l'API.