Autoriser les utilisateurs à configurer des widgets d'application

Les widgets d'application peuvent être configurés. Par exemple, un widget Horloge peut permettre aux utilisateurs de configurer le fuseau horaire à afficher.

Si vous souhaitez autoriser les utilisateurs à configurer les paramètres de votre widget, créez une configuration de widget Activity. Cette activité est automatiquement lancée par l'hôte du widget d'application lors de la création du widget ou ultérieurement, en fonction des options de configuration que vous spécifiez.

Déclarer l'activité de configuration

Déclarez l'activité de configuration comme une activité normale dans le fichier manifeste Android. L'hôte du widget d'application le lance avec l'action ACTION_APPWIDGET_CONFIGURE. L'activité doit donc accepter cet intent. Par exemple :

<activity android:name=".ExampleAppWidgetConfigurationActivity">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
    </intent-filter>
</activity>

Déclarez l'activité dans le fichier AppWidgetProviderInfo.xml avec l'attribut android:configure. Découvrez comment déclarer ce fichier. Voici un exemple de déclaration de l'activité de configuration:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:configure="com.example.android.ExampleAppWidgetConfigurationActivity"
    ... >
</appwidget-provider>

L'activité est déclarée avec un espace de noms complet, car le lanceur d'applications la référence en dehors du champ d'application de votre package.

C'est tout ce dont vous avez besoin pour démarrer une activité de configuration. Vous devez ensuite implémenter l'activité réelle.

Implémenter l'activité de configuration

Il y a deux points importants à retenir lorsque vous implémentez l'activité:

  • L'hôte du widget d'application appelle l'activité de configuration, qui doit toujours renvoyer un résultat. Le résultat doit inclure l'ID du widget d'application transmis par l'intent qui a lancé l'activité (enregistré dans les extras d'intent en tant que EXTRA_APPWIDGET_ID).
  • Le système n'envoie pas la diffusion ACTION_APPWIDGET_UPDATE lorsqu'une activité de configuration est lancée, ce qui signifie qu'il n'appelle pas la méthode onUpdate() lors de la création du widget. Il est de la responsabilité de l'activité de configuration de demander une mise à jour à partir de AppWidgetManager lors de la création du widget pour la première fois. Cependant, onUpdate() est appelé pour les mises à jour ultérieures. Il n'est ignoré que la première fois.

Consultez les extraits de code de la section suivante pour découvrir comment renvoyer un résultat de la configuration et mettre à jour le widget.

Mettre à jour le widget à partir de l'activité de configuration

Lorsqu'un widget utilise une activité de configuration, il lui incombe de mettre à jour le widget une fois la configuration terminée. Pour ce faire, demandez une mise à jour directement depuis le AppWidgetManager.

Voici un résumé de la procédure permettant de mettre à jour correctement le widget et de fermer l'activité de configuration:

  1. Obtenez l'ID de widget d'application à partir de l'intent qui a lancé l'activité:

    Kotlin

    val appWidgetId = intent?.extras?.getInt(
            AppWidgetManager.EXTRA_APPWIDGET_ID,
            AppWidgetManager.INVALID_APPWIDGET_ID
    ) ?: AppWidgetManager.INVALID_APPWIDGET_ID
    

    Java

    Intent intent = getIntent();
    Bundle extras = intent.getExtras();
    int appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
    if (extras != null) {
        appWidgetId = extras.getInt(
                AppWidgetManager.EXTRA_APPWIDGET_ID,
                AppWidgetManager.INVALID_APPWIDGET_ID);
    }
    
  2. Définissez le résultat de l'activité sur RESULT_CANCELED.

    De cette façon, si l'utilisateur quitte l'activité avant d'atteindre la fin, le système informe l'hôte du widget d'application que la configuration est annulée et qu'il n'ajoute pas le widget:

    Kotlin

    val resultValue = Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
    setResult(Activity.RESULT_CANCELED, resultValue)
    

    Java

    int resultValue = new Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    setResult(Activity.RESULT_CANCELED, resultValue);
    
  3. Configurez le widget en fonction des préférences de l'utilisateur.

  4. Une fois la configuration terminée, obtenez une instance de AppWidgetManager en appelant getInstance(Context):

    Kotlin

    val appWidgetManager = AppWidgetManager.getInstance(context)
    

    Java

    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    
  5. Mettez à jour le widget avec une mise en page RemoteViews en appelant updateAppWidget(int,RemoteViews):

    Kotlin

    val views = RemoteViews(context.packageName, R.layout.example_appwidget)
    appWidgetManager.updateAppWidget(appWidgetId, views)
    

    Java

    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget);
    appWidgetManager.updateAppWidget(appWidgetId, views);
    
  6. Créez l'intent de retour, définissez-le avec le résultat de l'activité, puis terminez l'activité:

    Kotlin

    val resultValue = Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
    setResult(Activity.RESULT_OK, resultValue)
    finish()
    

    Java

    Intent resultValue = new Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    setResult(RESULT_OK, resultValue);
    finish();
    

Consultez l'exemple de classe ListWidgetConfigureActivity.kt sur GitHub.

Options de configuration du widget

Par défaut, l'hôte du widget d'application ne lance l'activité de configuration qu'une seule fois, immédiatement après que l'utilisateur a ajouté le widget à son écran d'accueil. Toutefois, vous pouvez spécifier des options qui permettent aux utilisateurs de reconfigurer les widgets existants ou d'ignorer la configuration initiale des widgets en fournissant une configuration de widget par défaut.

Autoriser les utilisateurs à reconfigurer les widgets placés

Pour permettre aux utilisateurs de reconfigurer des widgets existants, spécifiez l'option reconfigurable dans l'attribut widgetFeatures de appwidget-provider. Pour en savoir plus, consultez le guide sur la déclaration du fichier AppWidgetProviderInfo.xml. Par exemple :

<appwidget-provider
    android:configure="com.myapp.ExampleAppWidgetConfigurationActivity"
    android:widgetFeatures="reconfigurable">
</appwidget-provider>

Les utilisateurs peuvent reconfigurer leur widget en appuyant dessus de manière prolongée, puis en appuyant sur le bouton Reconfigure (Reconfigurer), étiqueté 1 sur la figure 1.

Le bouton s&#39;affiche en bas à droite.
Figure 1 Bouton Reconfigure (Reconfigurer) du widget.

Utiliser la configuration par défaut du widget

Vous pouvez offrir une expérience de widget plus fluide en permettant aux utilisateurs d'ignorer l'étape de configuration initiale. Pour ce faire, spécifiez les options configuration_optional et reconfigurable dans le champ widgetFeatures. Cela permet de contourner le lancement de l'activité de configuration après qu'un utilisateur a ajouté le widget. Comme indiqué précédemment, l'utilisateur peut toujours reconfigurer le widget par la suite. Par exemple, un widget d'horloge peut contourner la configuration initiale et afficher le fuseau horaire de l'appareil par défaut.

Voici un exemple montrant comment marquer votre activité de configuration comme à la fois reconfigurable et facultative:

<appwidget-provider
    android:configure="com.myapp.ExampleAppWidgetConfigurationActivity"
    android:widgetFeatures="reconfigurable|configuration_optional">
</appwidget-provider>

Autoriser les utilisateurs à épingler un widget

Sur les appareils équipés d'Android 8.0 (niveau d'API 26) ou version ultérieure, les lanceurs d'applications permettant aux utilisateurs de créer des raccourcis épinglés leur permettent également d'épingler des widgets sur leur écran d'accueil. Comme les raccourcis épinglés, ces widgets épinglés permettent aux utilisateurs d'accéder à des tâches spécifiques dans votre application. Ils peuvent être ajoutés à l'écran d'accueil directement depuis l'application, comme illustré dans la vidéo suivante.

Exemple de mise en page responsive
Figure 2 Exemple d'épinglage d'un widget.

Dans votre application, vous pouvez demander au système d'épingler un widget à un lanceur compatible en procédant comme suit:

  1. Assurez-vous de déclarer un widget dans le fichier manifeste de votre application.

  2. Appelez la méthode requestPinAppWidget(), comme indiqué dans l'extrait de code suivant:

Kotlin

val appWidgetManager = AppWidgetManager.getInstance(context)
val myProvider = ComponentName(context, ExampleAppWidgetProvider::class.java)

if (appWidgetManager.isRequestPinAppWidgetSupported()) {
    // Create the PendingIntent object only if your app needs to be notified
    // when the user chooses to pin the widget. Note that if the pinning
    // operation fails, your app isn't notified. This callback receives the ID
    // of the newly pinned widget (EXTRA_APPWIDGET_ID).
    val successCallback = PendingIntent.getBroadcast(
            /* context = */ context,
            /* requestCode = */ 0,
            /* intent = */ Intent(...),
            /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT)

    appWidgetManager.requestPinAppWidget(myProvider, null, successCallback)
}

Java

AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
ComponentName myProvider = new ComponentName(context, ExampleAppWidgetProvider.class);

if (appWidgetManager.isRequestPinAppWidgetSupported()) {
    // Create the PendingIntent object only if your app needs to be notified
    // when the user chooses to pin the widget. Note that if the pinning
    // operation fails, your app isn't notified. This callback receives the ID
    // of the newly pinned widget (EXTRA_APPWIDGET_ID).
    PendingIntent successCallback = PendingIntent.getBroadcast(
            /* context = */ context,
            /* requestCode = */ 0,
            /* intent = */ new Intent(...),
            /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT);

    appWidgetManager.requestPinAppWidget(myProvider, null, successCallback);
}