Créer un hôte de widget

L'écran d'accueil Android, disponible sur la plupart des appareils Android, permet à l'utilisateur d'intégrer des widgets (ou widgets) pour accéder rapidement au contenu. Si vous remplacez l'écran d'accueil ou une application similaire, vous pouvez également autoriser l'utilisateur à intégrer des widgets en implémentant AppWidgetHost. Ce n'est pas quelque chose que la plupart des applications doivent faire, mais si vous créez votre propre hôte, il est important de comprendre les obligations contractuelles auxquelles un hôte accepte implicitement.

Cette page se concentre sur les responsabilités liées à l'implémentation d'un AppWidgetHost personnalisé. Pour obtenir un exemple spécifique d'implémentation d'un AppWidgetHost, consultez le code source de l'écran d'accueil Android LauncherAppWidgetHost.

Voici un aperçu des classes et concepts clés impliqués dans l'implémentation d'un AppWidgetHost personnalisé:

  • Hôte du widget d'application: AppWidgetHost permet d'interagir avec le service AppWidget pour les applications qui intègrent des widgets dans leur interface utilisateur. Un AppWidgetHost doit avoir un ID unique dans le package de l'hôte. Cet ID persiste lors de toutes les utilisations de l'hôte. L'ID est généralement une valeur codée en dur que vous attribuez dans votre application.

  • ID du widget d'application: un ID unique est attribué à chaque instance de widget au moment de la liaison. Consultez bindAppWidgetIdIfAllowed() et, pour plus d'informations, la section Lier des widgets ci-dessous. L'hôte obtient l'identifiant unique à l'aide de allocateAppWidgetId(). Cet ID est conservé pendant la durée de vie du widget jusqu'à ce qu'il soit supprimé de l'hôte. Tout état spécifique à l'hôte, tel que la taille et l'emplacement du widget, doit être conservé par le package d'hébergement et associé à l'ID du widget d'application.

  • Vue hôte du widget d'application: considérez AppWidgetHostView comme un frame dans lequel le widget est encapsulé chaque fois qu'il doit être affiché. Un widget est associé à un AppWidgetHostView chaque fois qu'il est gonflé par l'hôte.

    • Par défaut, le système crée une AppWidgetHostView, mais l'hôte peut créer sa propre sous-classe de AppWidgetHostView en l'étendant.
    • À partir d'Android 12 (niveau d'API 31), AppWidgetHostView introduit les méthodes setColorResources() et resetColorResources() pour gérer les couleurs surchargées de manière dynamique. L'hôte est responsable de fournir les couleurs à ces méthodes.
  • Groupe d'options: AppWidgetHost utilise le bundle d'options pour communiquer des informations à AppWidgetProvider sur la façon dont le widget s'affiche (par exemple, la liste des plages de tailles) et sur son affichage sur un écran de verrouillage ou sur l'écran d'accueil. Ces informations permettent à AppWidgetProvider d'adapter le contenu et l'apparence du widget en fonction de la manière dont il s'affiche et de son emplacement. Vous pouvez utiliser updateAppWidgetOptions() et updateAppWidgetSize() pour modifier le bundle d'un widget. Ces deux méthodes déclenchent le rappel onAppWidgetOptionsChanged() de AppWidgetProvider.

Lier des widgets

Lorsqu'un utilisateur ajoute un widget à un hôte, un processus appelé liaison se produit. La liaison fait référence à l'association d'un ID de widget d'application spécifique à un hôte et à un AppWidgetProvider spécifiques.

Les API de liaison permettent également à un hôte de fournir une UI personnalisée pour la liaison. Pour utiliser ce processus, votre application doit déclarer l'autorisation BIND_APPWIDGET dans le fichier manifeste de l'hôte:

<uses-permission android:name="android.permission.BIND_APPWIDGET" />

Mais ce n'est que la première étape. Au moment de l'exécution, l'utilisateur doit accorder explicitement l'autorisation à votre application pour lui permettre d'ajouter un widget à l'hôte. Pour tester si votre application est autorisée à ajouter le widget, utilisez la méthode bindAppWidgetIdIfAllowed(). Si bindAppWidgetIdIfAllowed() renvoie false, votre application doit afficher une boîte de dialogue invitant l'utilisateur à accorder l'autorisation suivante: "Autoriser" pour l'ajout actuel du widget ou "Toujours autoriser" pour couvrir tous les futurs ajouts de widget.

Cet extrait donne un exemple d'affichage de la boîte de dialogue:

Kotlin

val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_BIND).apply {
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName)
    // This is the options bundle described in the preceding section.
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options)
}
startActivityForResult(intent, REQUEST_BIND_APPWIDGET)

Java

Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);
// This is the options bundle described in the preceding section.
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);
startActivityForResult(intent, REQUEST_BIND_APPWIDGET);

L'hôte doit vérifier si le widget ajouté par un utilisateur nécessite une configuration. Pour en savoir plus, consultez Permettre aux utilisateurs de configurer des widgets d'application.

Responsabilités de l'organisateur

Vous pouvez spécifier un certain nombre de paramètres de configuration pour les widgets à l'aide des métadonnées AppWidgetProviderInfo. Vous pouvez récupérer ces options de configuration, détaillées plus en détail dans les sections suivantes, à partir de l'objet AppWidgetProviderInfo associé à un fournisseur de widgets.

Quelle que soit la version d'Android que vous ciblez, tous les hôtes ont les responsabilités suivantes:

  • Lorsque vous ajoutez un widget, attribuez son ID comme décrit précédemment. Lorsqu'un widget est supprimé de l'hôte, appelez deleteAppWidgetId() pour libérer l'ID de widget.

  • Lorsque vous ajoutez un widget, vérifiez si l'activité de configuration doit être lancée. En règle générale, l'hôte doit lancer l'activité de configuration du widget si elle existe et n'est pas marquée comme facultative en spécifiant les options configuration_optional et reconfigurable. Pour en savoir plus, consultez Mettre à jour le widget à partir de l'activité de configuration. Cette étape est nécessaire pour que de nombreux widgets puissent s'afficher.

  • Les widgets spécifient une largeur et une hauteur par défaut dans les métadonnées AppWidgetProviderInfo. Ces valeurs sont définies dans des cellules (à partir d'Android 12, si targetCellWidth et targetCellHeight sont spécifiés) ou dans dps si seuls minWidth et minHeight sont spécifiés. Consultez la section Attributs de dimensionnement des widgets.

    Assurez-vous que le widget est positionné avec au moins ce nombre de dp. Par exemple, de nombreux hôtes alignent les icônes et les widgets dans une grille. Dans ce scénario, l'hôte ajoute par défaut le widget en utilisant le nombre minimal de cellules qui satisfont aux contraintes minWidth et minHeight.

Outre les exigences listées dans la section précédente, des versions de plate-forme spécifiques introduisent des fonctionnalités qui confèrent de nouvelles responsabilités à l'hôte.

Déterminez votre approche en fonction de la version d'Android ciblée

Android 12

Android 12 (niveau d'API 31) inclut un List<SizeF> supplémentaire contenant la liste des tailles possibles en dps qu'une instance de widget peut accepter dans le bundle d'options. Le nombre de tailles fournies dépend de l'implémentation de l'hôte. Les hôtes proposent généralement deux tailles pour les téléphones (portrait et paysage) et quatre tailles pour les appareils pliables.

Le nombre de RemoteViews différents qu'un AppWidgetProvider peut fournir à RemoteViews est limité à MAX_INIT_VIEW_COUNT (16). Étant donné que les objets AppWidgetProvider mappent un objet RemoteViews à chaque taille de List<SizeF>, ne fournissez pas plus de MAX_INIT_VIEW_COUNT tailles.

Android 12 introduit également les attributs maxResizeWidth et maxResizeHeight dans dps. Nous vous recommandons de ne pas dépasser la taille spécifiée par les attributs d'un widget qui utilise au moins l'un de ces attributs.

Ressources supplémentaires

  • Consultez la documentation de référence sur Glance.