Créer un widget de base

Essayer la méthode Compose
Jetpack Compose est le kit d'UI recommandé pour Android. Découvrez comment créer des widgets à l'aide d'API de style Compose.

Les widgets d'application sont des vues d'application miniatures que vous pouvez intégrer à d'autres applications (comme l'écran d'accueil) et qui reçoivent des mises à jour périodiques. Ces vues sont appelées widgets dans l'interface utilisateur. Vous pouvez en publier une avec un fournisseur de widgets d'application (ou fournisseur de widgets). Un composant d'application qui contient d'autres widgets est appelé hôte de widget d'application (ou hôte de widget). La figure 1 présente un exemple de widget musical :

Exemple de widget musical
Figure 1. Exemple de widget musical.

Ce document explique comment publier un widget à l'aide d'un fournisseur de widgets. Pour en savoir plus sur la création de votre propre AppWidgetHost pour héberger des widgets d'application, consultez Créer un hôte de widget.

Pour savoir comment concevoir votre widget, consultez Présentation des widgets d'application.

Composants du widget

Pour créer un widget, vous avez besoin des composants de base suivants :

AppWidgetProviderInfo objet
Décrit les métadonnées d'un widget, telles que sa mise en page, sa fréquence de mise à jour et sa classe AppWidgetProvider. AppWidgetProviderInfo est défini en XML, comme décrit dans ce document.
Classe AppWidgetProvider
Définit les méthodes de base qui vous permettent d'interagir de manière programmatique avec le widget. Grâce à lui, vous recevez des diffusions lorsque le widget est mis à jour, activé, désactivé ou supprimé. Vous déclarez AppWidgetProvider dans le fichier manifeste, puis vous l'implémentez, comme décrit dans ce document.
Afficher la mise en page
Définit la mise en page initiale du widget. La mise en page est définie en XML, comme décrit dans ce document.

La figure 2 montre comment ces composants s'intègrent dans le flux de traitement global des widgets d'application.

Flux de traitement des widgets d'application
Figure 2. Flux de traitement des widgets d'application.

Si votre widget nécessite une configuration utilisateur, implémentez l'activité de configuration du widget d'application. Cette activité permet aux utilisateurs de modifier les paramètres du widget, par exemple le fuseau horaire d'un widget d'horloge.

Nous vous recommandons également les améliorations suivantes : mises en page de widgets flexibles, améliorations diverses, widgets avancés, widgets de collection et création d'un hôte de widget.

Déclarer le fichier XML AppWidgetProviderInfo

La définition des paramètres de métadonnées (tels que les tailles de cellule par défaut, les contraintes de redimensionnement et les fréquences de mise à jour) est exactement identique pour les vues traditionnelles et les widgets basés sur Glance.

Pour savoir comment définir et configurer votre fichier XML de métadonnées, consultez la section Déclarer le fichier XML AppWidgetProviderInfo de la documentation Glance.

Utiliser la classe AppWidgetProvider pour gérer les diffusions de widgets

Les mécanismes de broadcast receiver, les filtres de déclaration de fichier manifeste et les boucles d'événements de cycle de vie de la plate-forme sont unifiés sous la plate-forme. Dans le développement Compose-first, ces diffusions sont orchestrées à l'aide du wrapper GlanceAppWidgetReceiver.

Pour savoir comment enregistrer votre récepteur dans le fichier manifeste et implémenter des remplacements de cycle de vie compatibles avec Hilt, consultez la section Utiliser la classe AppWidgetProvider pour gérer les diffusions de la documentation Glance.

Créer la mise en page du widget

Vous devez définir une mise en page initiale pour votre widget au format XML et l'enregistrer dans le répertoire res/layout/ du projet. Pour en savoir plus, consultez les consignes de conception.

La création de la mise en page du widget est simple si vous connaissez les mises en page. Toutefois, sachez que les mises en page des widgets sont basées sur RemoteViews, qui n'est pas compatible avec tous les types de widgets de mise en page ou de vue. Vous ne pouvez pas utiliser de vues personnalisées ni de sous-classes des vues compatibles avec RemoteViews.

RemoteViews est également compatible avec ViewStub, une View invisible de taille nulle que vous pouvez utiliser pour gonfler, de manière différée, des ressources de mise en page lors de l'exécution.

Prise en charge du comportement avec état

Android 12 est compatible avec le comportement avec état à l'aide des composants existants suivants :

Le widget est toujours sans état. Votre application doit stocker l'état et s'enregistrer pour les événements de changement d'état.

Exemple de widget de liste de courses affichant un comportement avec état
Figure 3. Exemple de comportement avec état.

L'exemple de code suivant montre comment implémenter ces composants.

// Check the view.
remoteView.setCompoundButtonChecked(R.id.my_checkbox, true)

// Check a radio group.
remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2)

// Listen for check changes. The intent has an extra with the key
// EXTRA_CHECKED that specifies the current checked state of the view.
remoteView.setOnCheckedChangeResponse(
    R.id.my_checkbox,
    RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent)
)

Fournissez deux mises en page : l'une ciblant les appareils équipés d'Android 12 ou version ultérieure dans res/layout-v31, et l'autre ciblant les appareils équipés d'Android 11 ou version antérieure dans le dossier res/layout par défaut.

Implémenter des angles arrondis

Le calcul de l'arrière-plan extérieur et des rayons proportionnels intérieurs est standard et partagé. Dans le développement Compose-first, cela peut être défini de manière dynamique en Kotlin, avec des ressources de thème personnalisées.

Pour implémenter des rayons d'angle ou configurer des styles dynamiques pour les appareils Android plus anciens, consultez la section Implémenter des angles arrondis de la documentation Glance.

Maintenir les images RemoteViews dans les limites de mémoire du système

Les widgets s'exécutent dans le processus du lanceur d'applications de l'écran d'accueil, et system_server applique un plafond de mémoire bitmap par widget (6 * width * height octets ; consultez la section Modification du comportement de la limite de mémoire des widgets dans Android 17). Lorsque vous créez des widgets AppWidgetProvider classiques avec RemoteViews, procédez comme suit :

  • Sous-échantillonner les bitmaps à l'aide de WindowMetrics : au niveau d'API 30 et supérieur, calculez votre budget maximal de bitmaps à partir de WindowManager.currentWindowMetrics.bounds plutôt que de resources.displayMetrics, et décodez les images opaques avec Bitmap.Config.RGB_565 et une puissance de deux inSampleSize.
  • Utilisez des appels updateAppWidget complets lors du remplacement d'images : évitez d'appeler partiallyUpdateAppWidget pour mettre à jour des bitmaps ImageView ou des URI Icon, car les mises à jour partielles ajoutent des actions à la hiérarchie RemoteViews mise en cache dans system_server sans libérer les allocations d'images précédentes.
  • Mettre en file d'attente les tâches en arrière-plan avec WorkManager : n'appelez pas Context.startForegroundService depuis AppWidgetProvider.onReceive ou onUpdate, qui génère ForegroundServiceStartNotAllowedException lorsqu'il est déclenché en arrière-plan. Mettez plutôt en file d'attente un WorkManager CoroutineWorker et transmettez context.applicationContext lors du gonflement ou de la mise à jour de RemoteViews à partir de nœuds de calcul en arrière-plan.