API Android 4.3

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:

  • Autoriser l'accès aux comptes du propriétaire à partir d'une fiche limitée

    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.

  • Désactiver certaines fonctionnalités lorsque vous ne pouvez pas modifier les comptes.

    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.

  • Désactivez votre application lorsque vous ne pouvez pas accéder à des comptes privés.

    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.

    Figure 1 : Mise en page utilisant des limites de découpage (par défaut).

    Figure 2. Mise en page utilisant des limites optiques.

    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" ... >
    

    Figure 3. Vue zoomée du bouton Holo 9-patch avec les limites optiques.

    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.