API Android 4.1

Niveau d'API: 16

Android 4.1 (JELLY_BEAN) est une évolution de la plate-forme qui offre de meilleures performances et une meilleure expérience utilisateur. Il ajoute de nouvelles fonctionnalités pour les utilisateurs et les développeurs d'applications. Ce document présente les nouvelles API les plus notables et utiles pour les développeurs d'applications.

En tant que développeur d'applications, Android 4.1 est disponible dans le SDK Manager sous la forme d'une image système que vous pouvez exécuter dans Android Emulator et d'une plate-forme de SDK sur laquelle vous pouvez compiler votre application. Vous devez télécharger l'image système et la plate-forme dès que possible pour compiler et tester votre application sur Android 4.1.

Pour optimiser davantage votre application pour les appareils exécutant Android 4.1, vous devez définir votre targetSdkVersion sur "16", l'installer sur une image système Android 4.1, la tester, puis publier une mise à jour avec ce changement.

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

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

Composants de l'appli

Services isolés

En spécifiant android:isolatedProcess="true" dans la balise <service>, votre Service s'exécutera sous son propre processus d'ID utilisateur isolé, qui ne dispose pas de ses propres autorisations.

Gestion de la mémoire

Les nouvelles constantes ComponentCallbacks2 telles que TRIM_MEMORY_RUNNING_LOW et TRIM_MEMORY_RUNNING_CRITICAL fournissent aux processus de premier plan plus d'informations sur l'état de la mémoire avant que le système n'appelle onLowMemory().

La nouvelle méthode getMyMemoryState(ActivityManager.RunningAppProcessInfo) vous permet de récupérer l'état général de la mémoire.

Fournisseurs de contenu

Une nouvelle méthode, acquireUnstableContentProviderClient(), vous permet d'accéder à un ContentProviderClient qui peut être "instable" de sorte que votre application ne plante pas si le fournisseur de contenu le fait. Il est utile lorsque vous interagissez avec des fournisseurs de contenu dans une application distincte.

Fonds d'écran animés

Nouveau protocole d'intent pour lancer directement l'activité d'aperçu du fond d'écran animé afin d'aider les utilisateurs à sélectionner facilement votre fond d'écran animé sans les forcer à quitter votre application et à parcourir le sélecteur de fond d'écran de l'écran d'accueil.

Pour lancer le sélecteur de fond d'écran animé, appelez startActivity() avec un Intent à l'aide de ACTION_CHANGE_LIVE_WALLPAPER et d'un élément supplémentaire qui spécifie votre ComponentName de fond d'écran animé en tant que chaîne dans EXTRA_LIVE_WALLPAPER_COMPONENT.

Navigation dans la pile d'applications

Android 4.1 facilite grandement l'implémentation des modèles de conception appropriés pour la navigation vers le haut. Il vous suffit d'ajouter android:parentActivityName à chaque élément <activity> de votre fichier manifeste. Le système utilise ces informations pour ouvrir l'activité appropriée lorsque l'utilisateur appuie sur le bouton "Haut" de la barre d'action (tout en terminant l'activité en cours). Par conséquent, si vous déclarez android:parentActivityName pour chaque activité, vous n'avez pas besoin de la méthode onOptionsItemSelected() pour gérer les événements de clic sur l'icône de l'application de la barre d'action. Le système gère désormais cet événement et reprend ou crée l'activité appropriée.

Cela est particulièrement utile dans les scénarios où l'utilisateur accède à l'une des activités de votre application via un intent "d'exploration approfondie", par exemple à partir d'une notification ou d'un intent d'une autre application (comme décrit dans le guide de conception sur la navigation entre les applications). Lorsque l'utilisateur accède à votre activité de cette manière, il est possible que votre application ne dispose pas naturellement d'une pile "Retour" d'activités pouvant être reprises lorsque l'utilisateur navigue vers le haut. Toutefois, lorsque vous fournissez l'attribut android:parentActivityName pour vos activités, le système détermine si votre application contient déjà une pile "Retour" d'activités parentes et, si ce n'est pas le cas, crée une pile "Retour" synthétique contenant toutes les activités parentes.

Remarque:Lorsque l'utilisateur saisit une activité profonde dans votre application et qu'il crée une tâche pour votre application, le système insère en fait la pile d'activités parentes dans la tâche. Par conséquent, le bouton "Retour" permet également de revenir à la pile d'activités parentes.

Lorsque le système crée une pile "Retour" synthétique pour votre application, il crée une Intent de base pour créer une instance de chaque activité parente. Il n'y a donc pas d'état enregistré pour les activités parentes comme vous le feriez si l'utilisateur avait navigué naturellement dans chaque activité. Si l'une des activités parentes affiche normalement une UI qui dépend du contexte de l'utilisateur, ces informations contextuelles sont manquantes et vous devez les fournir lorsque l'utilisateur revient dans la pile. Par exemple, si l'utilisateur consulte un album dans une application musicale, la navigation vers le haut peut l'amener à une activité qui liste tous les albums d'un genre musical choisi. Dans ce cas, si la pile doit être créée, vous devez informer l'activité parente du genre auquel appartient l'album actuel afin qu'elle puisse afficher la liste appropriée comme si l'utilisateur venait de cette activité. Pour transmettre ces informations à une activité parente synthétique, vous devez remplacer la méthode onPrepareNavigateUpTaskStack(). Vous obtenez ainsi un objet TaskStackBuilder que le système a créé pour synthétiser les activités parentes. TaskStackBuilder contient des objets Intent que le système utilise pour créer chaque activité parente. Dans votre implémentation de onPrepareNavigateUpTaskStack(), vous pouvez modifier le Intent approprié pour ajouter des données supplémentaires que l'activité parente peut utiliser pour déterminer le contexte approprié et afficher l'UI appropriée.

Lorsque le système crée le TaskStackBuilder, il ajoute les objets Intent qui sont utilisés pour créer les activités parentes dans leur ordre logique à partir du haut de l'arborescence des activités. Ainsi, le dernier Intent ajouté au tableau interne est le parent direct de l'activité actuelle. Si vous souhaitez modifier le Intent pour le parent de l'activité, déterminez d'abord la longueur du tableau avec getIntentCount() et transmettez cette valeur à editIntentAt().

Si la structure de votre application est plus complexe, plusieurs autres API sont disponibles pour vous permettre de gérer le comportement de la navigation vers le haut et de personnaliser entièrement la pile "Retour" synthétique. Voici quelques-unes des API qui vous offrent un contrôle supplémentaire:

onNavigateUp()
Ignorez cette valeur pour effectuer une action personnalisée lorsque l'utilisateur appuie sur le bouton "Haut".
navigateUpTo(Intent)
Appelez cette méthode pour terminer l'activité en cours et accéder à l'activité indiquée par l'Intent fournie. Si l'activité existe dans la pile "Retour", mais qu'elle n'est pas le parent le plus proche, toutes les autres activités entre l'activité actuelle et l'activité spécifiée avec l'intent sont également terminées.
getParentActivityIntent()
Appelez cette méthode pour obtenir l'Intent qui démarrera le parent logique de l'activité en cours.
shouldUpRecreateTask(Intent)
Appelez cette méthode pour déterminer si une pile "Retour" synthétique doit être créée afin de naviguer vers le haut. Renvoie la valeur "true" si une pile synthétique doit être créée, ou "false" si la pile appropriée existe déjà.
finishAffinity()
Appelez cette méthode pour terminer l'activité actuelle et toutes les activités parentes ayant la même affinité de tâche qui sont liées à l'activité actuelle. Si vous remplacez les comportements par défaut tels que onNavigateUp(), vous devez appeler cette méthode lorsque vous créez une pile "Retour" synthétique lors de la navigation vers le haut.
onCreateNavigateUpTaskStack
Ignorez cette valeur si vous devez contrôler entièrement la création de la pile de tâches synthétique. Si vous souhaitez simplement ajouter des données supplémentaires aux intents de votre pile "Retour", vous devez plutôt remplacer onPrepareNavigateUpTaskStack()
.

Toutefois, la plupart des applications n'ont pas besoin d'utiliser ces API ni d'implémenter onPrepareNavigateUpTaskStack(), mais peuvent obtenir le comportement correct simplement en ajoutant android:parentActivityName à chaque élément <activity>.

Multimédia

Codecs multimédias

La classe MediaCodec fournit un accès aux codecs multimédias de bas niveau pour l'encodage et le décodage de vos contenus multimédias. Vous pouvez instancier un MediaCodec en appelant createEncoderByType() pour encoder des contenus multimédias ou createDecoderByType() pour les décoder. Chacune de ces méthodes accepte un type MIME pour le type de contenu multimédia que vous souhaitez encoder ou décoder, comme "video/3gpp" ou "audio/vorbis".

Une fois une instance de MediaCodec créée, vous pouvez appeler configure() pour spécifier des propriétés telles que le format multimédia ou si le contenu est chiffré ou non.

Que vous encodiez ou décodiez vos contenus multimédias, le reste du processus est identique après avoir créé le MediaCodec. Appelez d'abord getInputBuffers() pour obtenir un tableau d'objets ByteBuffer d'entrée et getOutputBuffers() pour obtenir un tableau d'objets ByteBuffer de sortie.

Lorsque vous êtes prêt à encoder ou à décoder, appelez dequeueInputBuffer() pour obtenir la position d'index du ByteBuffer (à partir du tableau de tampons d'entrée) que vous devez utiliser pour alimenter votre média source. Une fois que vous avez rempli ByteBuffer avec votre contenu multimédia source, libérez la propriété du tampon en appelant queueInputBuffer().

De même pour le tampon de sortie, appelez dequeueOutputBuffer() pour obtenir la position d'index de l'ByteBuffer où vous recevrez les résultats. Après avoir lu la sortie de ByteBuffer, libérez la propriété en appelant releaseOutputBuffer().

Vous pouvez gérer les données multimédias chiffrées dans les codecs en appelant queueSecureInputBuffer() avec les API MediaCrypto, au lieu de queueInputBuffer() normal.

Pour en savoir plus sur l'utilisation des codecs, consultez la documentation MediaCodec.

Enregistrer l'audio sur commande

La nouvelle méthode startRecording() vous permet de démarrer l'enregistrement audio en fonction d'un repère défini par un MediaSyncEvent. MediaSyncEvent spécifie une session audio (telle que celle définie par MediaPlayer), qui, une fois terminée, déclenche l'enregistrement de l'enregistreur audio. Par exemple, vous pouvez utiliser cette fonctionnalité pour lire une tonalité audio qui indique le début d'une session d'enregistrement. L'enregistrement commence automatiquement. Vous n'avez donc pas besoin de synchroniser manuellement la tonalité et le début de l'enregistrement.

Pistes de texte synchronisées

MediaPlayer gère désormais les pistes de texte en bande et hors bande. Les pistes de texte intégrées au bracelet sont une piste de texte au sein d'une source multimédia MP4 ou 3GPP. Les pistes de texte hors bande peuvent être ajoutées en tant que source de texte externe via la méthode addTimedTextSource(). Une fois toutes les sources de pistes de texte externes ajoutées, getTrackInfo() doit être appelé pour obtenir la liste actualisée de toutes les pistes disponibles dans une source de données.

Pour définir le canal à utiliser avec MediaPlayer, vous devez appeler selectTrack(), en utilisant la position d'index du canal que vous souhaitez utiliser.

Pour être averti lorsque la piste de texte est prête à être lue, implémentez l'interface MediaPlayer.OnTimedTextListener et transmettez-la à setOnTimedTextListener().

Effets audio

La classe AudioEffect est désormais compatible avec d'autres types de prétraitement audio lors de la capture d'audio:

  • L'annulation de l'écho acoustique (AEC) avec AcousticEchoCanceler supprime la contribution du signal reçu de la partie distante du signal audio capturé.
  • Le contrôle automatique du gain (CAG) avec AutomaticGainControl normalise automatiquement la sortie du signal capturé.
  • Le suppresseur de bruit (NS) avec NoiseSuppressor élimine le bruit de fond du signal capturé.

Vous pouvez appliquer ces effets de préprocesseur à l'audio capturé avec un AudioRecord à l'aide de l'une des sous-classes AudioEffect.

Remarque:Il n'est pas garanti que tous les appareils soient compatibles avec ces effets. Vous devez donc toujours vérifier la disponibilité en appelant isAvailable() sur la classe d'effets audio correspondante.

Lecture sans coupure

Vous pouvez désormais effectuer une lecture sans coupure entre deux objets MediaPlayer distincts. À tout moment avant la fin de votre premier MediaPlayer, appelez setNextMediaPlayer() et Android tente de démarrer le deuxième lecteur au moment où le premier s'arrête.

Routeur multimédia Les nouvelles API MediaRouter, MediaRouteActionProvider et MediaRouteButton fournissent des mécanismes standards et une interface utilisateur permettant de choisir où lire des contenus multimédias.

Appareil photo

Mise au point automatique en mouvement

La nouvelle interface Camera.AutoFocusMoveCallback vous permet d'écouter les modifications apportées au mouvement de mise au point automatique. Vous pouvez enregistrer votre interface auprès de setAutoFocusMoveCallback(). Ensuite, lorsque la caméra est en mode autofocus continu (FOCUS_MODE_CONTINUOUS_VIDEO ou FOCUS_MODE_CONTINUOUS_PICTURE), vous recevez un appel à onAutoFocusMoving(), qui vous indique si l'autofocus a commencé à bouger ou s'il a cessé de bouger.

Sons appareil photo

La classe MediaActionSound fournit un ensemble simple d'API pour produire les sons standards émis par l'appareil photo ou d'autres actions multimédias. Vous devez utiliser ces API pour diffuser le son approprié lorsque vous créez une image fixe ou une caméra vidéo personnalisée.

Pour lire un son, il vous suffit d'instancier un objet MediaActionSound, d'appeler load() pour précharger le son souhaité, puis d'appeler play() au moment opportun.

Connectivité

Android Beam

Android BeamTM est désormais compatible avec les transferts de charges utiles volumineuses via Bluetooth. Lorsque vous définissez les données à transférer avec la nouvelle méthode setBeamPushUris() ou la nouvelle interface de rappel NfcAdapter.CreateBeamUrisCallback, Android transmet le transfert de données au Bluetooth ou à un autre transport pour obtenir des vitesses de transfert plus rapides. Cela est particulièrement utile pour les charges utiles volumineuses, telles que les fichiers image et audio, et ne nécessite aucune association visible entre les appareils. Aucune action supplémentaire n'est requise de la part de votre application pour tirer parti des transferts via Bluetooth.

La méthode setBeamPushUris() utilise un tableau d'objets Uri qui spécifient les données que vous souhaitez transférer à partir de votre application. Vous pouvez également implémenter l'interface NfcAdapter.CreateBeamUrisCallback, que vous pouvez spécifier pour votre activité en appelant setBeamPushUrisCallback().

Lorsque vous utilisez l'interface de rappel, le système appelle la méthode createBeamUris() de l'interface lorsque l'utilisateur effectue un partage avec Android Beam afin que vous puissiez définir les URI à partager au moment du partage. Cela est utile si les URI à partager peuvent varier en fonction du contexte utilisateur dans l'activité, tandis que l'appel de setBeamPushUris() est utile lorsque les URI à partager ne changent pas et que vous pouvez les définir à l'avance en toute sécurité.

Identification du service réseau

Android 4.1 est compatible avec la découverte de services basée sur le DNS multicast, qui vous permet de rechercher et de vous connecter aux services proposés par des appareils homologues via le Wi-Fi, tels que les appareils mobiles, les imprimantes, les appareils photo, les lecteurs multimédias et d'autres appareils enregistrés sur le réseau local.

Le nouveau package android.net.nsd contient les nouvelles API qui vous permettent de diffuser vos services sur le réseau local, de détecter les appareils locaux sur le réseau et de vous y connecter.

Pour enregistrer votre service, vous devez d'abord créer un objet NsdServiceInfo et définir les différentes propriétés de votre service à l'aide de méthodes telles que setServiceName(), setServiceType() et setPort().

Vous devez ensuite implémenter NsdManager.RegistrationListener et le transmettre à registerService() avec votre NsdServiceInfo.

Pour découvrir des services sur le réseau, implémentez NsdManager.DiscoveryListener et transmettez-le à discoverServices().

Lorsque votre NsdManager.DiscoveryListener reçoit des rappels sur les services détectés, vous devez résoudre le service en appelant resolveService(), en lui transmettant une implémentation de NsdManager.ResolveListener qui reçoit un objet NsdServiceInfo contenant des informations sur le service détecté, ce qui vous permet d'établir la connexion.

Découverte de services Wi-Fi P2P

Les API Wi-Fi P2P sont améliorées dans Android 4.1 pour prendre en charge la découverte de services avant l'association dans WifiP2pManager. Cela vous permet de détecter et de filtrer les appareils à proximité par services à l'aide du Wi-Fi P2P avant de vous y connecter, tandis que la détection de services réseau vous permet de détecter un service sur un réseau connecté existant (tel qu'un réseau Wi-Fi local).

Pour diffuser votre application en tant que service sur Wi-Fi afin que d'autres appareils puissent la détecter et s'y connecter, appelez addLocalService() avec un objet WifiP2pServiceInfo qui décrit les services de votre application.

Pour lancer la découverte des appareils à proximité via le Wi-Fi, vous devez d'abord décider si vous allez communiquer à l'aide de Bonjour ou d'Upnp. Pour utiliser Bonjour, configurez d'abord des écouteurs de rappel avec setDnsSdResponseListeners(), qui accepte à la fois un WifiP2pManager.DnsSdServiceResponseListener et un WifiP2pManager.DnsSdTxtRecordListener. Pour utiliser Upnp, appelez setUpnpServiceResponseListener(), qui nécessite un WifiP2pManager.UpnpServiceResponseListener.

Avant de pouvoir découvrir des services sur des appareils locaux, vous devez également appeler addServiceRequest(). Lorsque le WifiP2pManager.ActionListener que vous transmettez à cette méthode reçoit un rappel réussi, vous pouvez commencer à découvrir des services sur les appareils locaux en appelant discoverServices().

Lorsque des services locaux sont détectés, vous recevez un rappel sur WifiP2pManager.DnsSdServiceResponseListener ou WifiP2pManager.UpnpServiceResponseListener, selon que vous vous êtes inscrit pour utiliser Bonjour ou Upnp. Dans les deux cas, le rappel reçu contient un objet WifiP2pDevice représentant l'appareil homologue.

Utilisation du réseau

La nouvelle méthode isActiveNetworkMetered() vous permet de vérifier si l'appareil est actuellement connecté à un réseau limité. En vérifiant cet état avant d'effectuer des transactions réseau intensives, vous pouvez gérer la consommation de données qui peut coûter de l'argent à vos utilisateurs et prendre des décisions éclairées sur l'exécution des transactions maintenant ou plus tard (par exemple, lorsque l'appareil se connecte au Wi-Fi).

Accessibilité

API de service d'accessibilité

La couverture des API de service d'accessibilité a été considérablement améliorée dans Android 4.1. Il vous permet désormais de créer des services qui surveillent et répondent à davantage d'événements d'entrée, tels que des gestes complexes à l'aide de onGesture() et d'autres événements d'entrée grâce à des ajouts aux classes AccessibilityEvent, AccessibilityNodeInfo et AccessibilityRecord.

Les services d'accessibilité peuvent également effectuer des actions pour le compte de l'utilisateur, y compris cliquer, faire défiler l'écran et parcourir le texte à l'aide de performAction et setMovementGranularities. La méthode performGlobalAction() permet également aux services d'effectuer des actions telles que Retour, Accueil, et d'ouvrir les applications récentes et les notifications.

Navigation dans l'application personnalisable

Lorsque vous créez une application Android, vous pouvez désormais personnaliser les schémas de navigation en recherchant des éléments et des widgets de saisie pouvant être sélectionnés à l'aide de findFocus() et focusSearch(), et en définissant la sélection à l'aide de setAccessibilityFocused().

Widgets plus accessibles

La nouvelle classe android.view.accessibility.AccessibilityNodeProvider vous permet de présenter des vues personnalisées complexes aux services d'accessibilité afin qu'ils puissent présenter les informations de manière plus accessible. android.view.accessibility.AccessibilityNodeProvider permet à un widget utilisateur avec du contenu avancé, tel qu'une grille de calendrier, de présenter une structure sémantique logique pour les services d'accessibilité, qui est complètement distincte de la structure de mise en page du widget. Cette structure sémantique permet aux services d'accessibilité de présenter un modèle d'interaction plus utile pour les utilisateurs malvoyants.

Copy and Paste

Copier et coller avec des intents

Vous pouvez désormais associer un objet ClipData à un Intent à l'aide de la méthode setClipData(). Cela est particulièrement utile lorsque vous utilisez un intent pour transférer plusieurs URI content: vers une autre application, par exemple lors du partage de plusieurs documents. Les URI content: fournis de cette manière respecteront également les indicateurs de l'intent pour offrir un accès en lecture ou en écriture, ce qui vous permettra d'accorder l'accès à plusieurs URI dans l'intent. Lorsque vous démarrez un intent ACTION_SEND ou ACTION_SEND_MULTIPLE, les URI fournis dans l'intent sont désormais propagés automatiquement vers le ClipData afin que le destinataire puisse y accéder.

Compatibilité avec les styles HTML et de chaîne

La classe ClipData est désormais compatible avec le texte stylisé (au format HTML ou chaînes stylisées Android). Vous pouvez ajouter du texte stylisé en HTML à ClipData avec newHtmlText().

RenderScript

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

  • Prise en charge de plusieurs noyaux dans un même script.
  • Prise en charge de la lecture à partir de l'allocation avec des échantillons filtrés à partir du calcul dans une nouvelle API de script rsSample.
  • Compatibilité avec différents niveaux de précision de FP dans #pragma.
  • Possibilité d'interroger des informations supplémentaires à partir d'objets RS à partir d'un script de calcul.
  • Nombreuses améliorations des performances.

De nouveaux pragmas sont également disponibles pour définir la précision à virgule flottante requise par vos Renderscripts de calcul. Cela vous permet d'activer des opérations NEON telles que des opérations de calcul vectoriel rapide sur le chemin du processeur qui ne seraient pas possibles avec la norme IEEE 754-2008 complète.

Remarque:Le moteur graphique Renderscript expérimental est désormais obsolète.

Animation

Animations de lancement d'activité

Vous pouvez désormais lancer une Activity à l'aide d'animations de zoom ou de vos propres animations personnalisées. Pour spécifier l'animation souhaitée, utilisez les API ActivityOptions pour créer un Bundle que vous pouvez ensuite transmettre à l'une des méthodes qui lancent une activité, comme startActivity().

La classe ActivityOptions inclut une méthode différente pour chaque type d'animation que vous souhaitez afficher lorsque votre activité s'ouvre:

makeScaleUpAnimation()
Crée une animation qui augmente la taille de la fenêtre d'activité à partir d'une position de départ spécifiée à l'écran et d'une taille de départ spécifiée. Par exemple, l'écran d'accueil d'Android 4.1 l'utilise lorsque vous ouvrez une application.
makeThumbnailScaleUpAnimation()
Crée une animation qui met à l'échelle la fenêtre d'activité à partir d'une position spécifiée et d'une image miniature fournie. Par exemple, la fenêtre "Applications récentes" d'Android 4.1 l'utilise lorsque vous revenez à une application.
makeCustomAnimation()
Crée une animation définie par vos propres ressources, une qui définit l'animation pour l'ouverture de l'activité et une autre pour l'activité en cours d'arrêt.

Animateur de temps

La nouvelle TimeAnimator fournit un mécanisme de rappel simple avec TimeAnimator.TimeListener, qui vous avertit à chaque frame de l'animation. Il n'y a pas de durée, d'interpolation ni de valeur d'objet définie avec cet animateur. Le rappel de l'écouteur reçoit des informations pour chaque frame, y compris le temps écoulé total et le temps écoulé depuis le frame d'animation précédent.

Interface utilisateur

Notifications

Sous Android 4.1, vous pouvez créer des notifications avec des zones de contenu plus grandes, de grands aperçus d'images, plusieurs boutons d'action et une priorité configurable.

Styles de notifications

La nouvelle méthode setStyle() vous permet de spécifier l'un des trois nouveaux styles de votre notification, chacun offrant une zone de contenu plus grande. Pour spécifier le style de votre grande région de contenu, transmettez à setStyle() l'un des objets suivants:

Notification.BigPictureStyle
Pour les notifications incluant une grande image en pièce jointe.
Notification.BigTextStyle
 : pour les notifications contenant beaucoup de texte, comme un seul e-mail.
Notification.InboxStyle
Pour les notifications qui incluent une liste de chaînes, comme des extraits de plusieurs e-mails.
Actions de notification

Vous pouvez désormais afficher jusqu'à deux boutons d'action en bas du message de notification, que votre notification utilise le style normal ou le style plus grand.

Pour ajouter un bouton d'action, appelez addAction(). Cette méthode accepte trois arguments: une ressource drawable pour une icône, un texte pour le bouton et un PendingIntent qui définit l'action à effectuer.

Priorités

Vous pouvez maintenant indiquer au système à quel point votre notification est importante pour l'ordre de votre notification dans la liste en définissant la priorité avec setPriority(). Vous pouvez transmettre l'un des cinq niveaux de priorité différents définis par les constantes PRIORITY_* dans la classe Notification. La valeur par défaut est PRIORITY_DEFAULT. Il y a deux niveaux supérieurs et deux niveaux inférieurs.

Les notifications à priorité élevée sont des éléments auxquels les utilisateurs souhaitent généralement répondre rapidement, comme un nouveau message instantané, un SMS ou un rappel d'événement imminent. Les notifications de faible priorité incluent les événements d'agenda expirés ou les promotions d'applications.

Commandes de l'UI du système

Android 4.0 (Ice Cream Sandwich) a ajouté de nouveaux indicateurs pour contrôler la visibilité des éléments de l'interface utilisateur du système, par exemple pour atténuer l'apparence de la barre système ou la faire disparaître complètement sur les téléphones. Android 4.1 ajoute quelques indicateurs supplémentaires qui vous permettent de contrôler davantage l'apparence des éléments d'UI du système et de la mise en page de votre activité par rapport à ceux-ci en appelant setSystemUiVisibility() et en transmettant les indicateurs suivants:

SYSTEM_UI_FLAG_FULLSCREEN
Masque l'interface utilisateur système non critique (telle que la barre d'état). Si votre activité utilise la barre d'action en mode superposition (en activant android:windowActionBarOverlay), cet indicateur masque également la barre d'action et le fait avec une animation coordonnée lorsqu'il masque et affiche les deux.
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
Définit la mise en page de votre activité pour qu'elle utilise la même zone d'écran disponible lorsque vous avez activé SYSTEM_UI_FLAG_FULLSCREEN, même si les éléments d'interface utilisateur du système sont toujours visibles. Bien que certaines parties de votre mise en page soient superposées à l'UI du système, cela est utile si votre application masque et affiche souvent l'UI du système avec SYSTEM_UI_FLAG_FULLSCREEN, car cela évite que votre mise en page ne s'ajuste aux nouvelles limites de mise en page chaque fois que l'UI du système se masque ou s'affiche.
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
Définit la mise en page de votre activité pour qu'elle utilise la même zone d'écran disponible lorsque vous avez activé SYSTEM_UI_FLAG_HIDE_NAVIGATION (ajouté dans Android 4.0), même si les éléments de l'interface utilisateur du système sont toujours visibles. Bien que certaines parties de votre mise en page soient superposées à la barre de navigation, cela est utile si votre application masque et affiche souvent la barre de navigation avec SYSTEM_UI_FLAG_HIDE_NAVIGATION, car cela évite que votre mise en page ne s'ajuste aux nouvelles limites de mise en page chaque fois que la barre de navigation se masque ou s'affiche.
SYSTEM_UI_FLAG_LAYOUT_STABLE
Vous pouvez ajouter cet indicateur si vous utilisez SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN et/ou SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION pour vous assurer que lorsque vous appelez fitSystemWindows() sur une vue, les limites définies restent cohérentes par rapport à l'espace disponible à l'écran. Autrement dit, lorsque cet indicateur est défini, fitSystemWindows() se comporte comme si la visibilité des éléments d'UI du système restait inchangée, même après avoir masqué toute l'UI du système.

Pour en savoir plus sur les autres options d'interface utilisateur système associées, consultez celles ajoutées dans Android 4.0.

Vues à distance

GridLayout et ViewStub sont désormais des vues télécommandables. Vous pouvez donc les utiliser dans les mises en page de vos widgets d'application et de vos mises en page personnalisées de notifications.

Familles de polices

Android 4.1 ajoute plusieurs variantes du style de police Roboto pour un total de 10 variantes, toutes utilisables par les applications. Vos applications ont désormais accès à l'ensemble des variantes claires et condensées.

L'ensemble complet des variantes de polices Roboto disponibles est le suivant:

  • Standard
  • Italique
  • Gras
  • Gras-italique
  • Léger
  • Italique clair
  • Condensed regular
  • Italique condensé
  • Gras condensé
  • Gras italique condensé

Vous pouvez appliquer l'un de ces interpolateurs avec le nouvel attribut fontFamily associé à l'attribut textStyle.

Les valeurs acceptées pour fontFamily sont les suivantes:

  • "sans-serif" pour Roboto normal
  • "sans-serif-light" pour Roboto Light
  • "sans-serif-condensed" pour Roboto Condensed

Vous pouvez ensuite appliquer le gras et/ou l'italique avec les valeurs textStyle "bold" et "italic". Vous pouvez appliquer les deux comme suit: android:textStyle="bold|italic".

Vous pouvez également utiliser Typeface.create(). Par exemple, Typeface.create("sans-serif-light", Typeface.NORMAL).

Framework d'entrée

Plusieurs périphériques d'entrée

La nouvelle classe InputManager vous permet d'interroger l'ensemble des périphériques d'entrée actuellement connectés et d'enregistrer une notification lorsqu'un appareil est ajouté, modifié ou supprimé. Cela est particulièrement utile si vous créez un jeu compatible avec plusieurs joueurs et que vous souhaitez détecter le nombre de manettes connectées et quand le nombre de manettes change.

Vous pouvez interroger tous les périphériques d'entrée connectés en appelant getInputDeviceIds(). Cette méthode renvoie un tableau d'entiers, chacun étant un ID d'un autre appareil d'entrée. Vous pouvez ensuite appeler getInputDevice() pour acquérir un InputDevice pour un ID d'appareil d'entrée spécifié.

Si vous souhaitez être informé lorsque de nouveaux appareils d'entrée sont connectés, modifiés ou déconnectés, implémentez l'interface InputManager.InputDeviceListener et enregistrez-la avec registerInputDeviceListener().

Vibreur pour les contrôleurs d'entrée

Si les périphériques d'entrée connectés disposent de leurs propres fonctionnalités de vibration, vous pouvez désormais contrôler la vibration de ces appareils à l'aide des API Vibrator existantes en appelant simplement getVibrator() sur InputDevice.

Autorisations

Voici les nouvelles autorisations:

READ_EXTERNAL_STORAGE
Fournit un accès en lecture protégé au stockage externe. Dans Android 4.1, toutes les applications disposent toujours d'un accès en lecture par défaut. Cette modification sera apportée dans une prochaine version pour exiger que les applications demandent explicitement l'accès en lecture à l'aide de cette autorisation. Si votre application demande déjà un accès en écriture, elle obtient également automatiquement un accès en lecture. Il existe une nouvelle option pour les développeurs qui permet d'activer la restriction d'accès en lecture. Elle leur permet de tester leurs applications par rapport au comportement futur d'Android.
android.Manifest.permission.READ_USER_DICTIONARY
Permet à une application de lire le dictionnaire personnel. Cela ne doit être requis que par un IME ou un éditeur de dictionnaire tel que l'application Paramètres.
READ_CALL_LOG
Permet à une application de lire le journal d'appels du système, qui contient des informations sur les appels entrants et sortants.
WRITE_CALL_LOG
Permet à une application de modifier le journal d'appels du système stocké sur votre téléphone
android.Manifest.permission.WRITE_USER_DICTIONARY
Permet à une application d'écrire dans le dictionnaire de mots de l'utilisateur.

Fonctionnalités de l'appareil

Android 4.1 inclut une nouvelle déclaration de fonctionnalité pour les appareils dédiés à l'affichage de l'interface utilisateur sur un écran de télévision: FEATURE_TELEVISION. Pour déclarer que votre application nécessite une interface pour téléviseur, déclarez cette fonctionnalité dans votre fichier manifeste avec l'élément <uses-feature>:

<manifest ... >
    <uses-feature android:name="android.hardware.type.television"
                  android:required="true" />
    ...
</manifest>

Cette fonctionnalité définit le concept de "télévision" en tant qu'expérience TV classique : elle s'affiche sur un grand écran auquel l'utilisateur fait face, assis à une certaine distance, et où la forme d'entrée principale est semblable à un pavé directionnel (et rarement une souris, un pointeur ou un appareil tactile).