web-dev-qa-db-fra.com

Événement de clic sur le bouton pour Android

J'ai un widget Android qui récupère les données d'un serveur toutes les 10 minutes et les affiche à l'écran.
Je voudrais ajouter un bouton "Actualiser" à ce widget.
Lorsque l'utilisateur clique sur ce bouton, j'aimerais exécuter la méthode qui récupère les informations du serveur.
L'ajout d'un gestionnaire d'événements à un bouton dans une application est très facile, mais je n'ai pas pu trouver d'exemple pour un widget.
J'aimerais obtenir de l'aide pour ajouter une fonction à un clic de bouton dans un widget.

41
Sharon Haim Pour

J'ai découvert comment faire ça.
Ajoutez une action au fichier AndroidManifest.xml Dans la balise> <receiver><intent-filter>:

<action Android:name="MY_PACKAGE_NAME.WIDGET_BUTTON" />

Dans le fournisseur, ajoutez une constante qui correspond au nom de l'action:

public static String WIDGET_BUTTON = "MY_PACKAGE_NAME.WIDGET_BUTTON";

Dans la méthode onUpdate(), ajoutez une intention en attente qui correspond à l'action:

Intent intent = new Intent(WIDGET_BUTTON);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.MY_BUTTON_ID, pendingIntent );

Enfin, dans la méthode onRecieve (), vérifiez le nom de l'action:

 if (WIDGET_BUTTON.equals(intent.getAction())) {
//your code here

    }
44
Sharon Haim Pour

Voici un exemple de plus qui devrait vous aider:

package com.automatic.widget;

import Android.app.PendingIntent;
import Android.appwidget.AppWidgetManager;
import Android.appwidget.AppWidgetProvider;
import Android.content.ComponentName;
import Android.content.Context;
import Android.content.Intent;
import Android.widget.RemoteViews;

public class Widget extends AppWidgetProvider {

    private static final String SYNC_CLICKED    = "automaticWidgetSyncButtonClick";

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        RemoteViews remoteViews;
        ComponentName watchWidget;

        remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
        watchWidget = new ComponentName(context, Widget.class);

        remoteViews.setOnClickPendingIntent(R.id.sync_button, getPendingSelfIntent(context, SYNC_CLICKED));
        appWidgetManager.updateAppWidget(watchWidget, remoteViews);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        super.onReceive(context, intent);

        if (SYNC_CLICKED.equals(intent.getAction())) {

            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);

            RemoteViews remoteViews;
            ComponentName watchWidget;

            remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
            watchWidget = new ComponentName(context, Widget.class);

            remoteViews.setTextViewText(R.id.sync_button, "TESTING");

            appWidgetManager.updateAppWidget(watchWidget, remoteViews);

        }
    }

    protected PendingIntent getPendingSelfIntent(Context context, String action) {
        Intent intent = new Intent(context, getClass());
        intent.setAction(action);
        return PendingIntent.getBroadcast(context, 0, intent, 0);
    }
}
69

Voici une autre réponse avec les avantages suivants:

  • Il gère toutes les instances de widget d'application (un utilisateur peut avoir plusieurs instances de votre widget dans différentes configurations/tailles sur votre écran). Le codage pour toutes les instances est ce que la documentation officielle prescrit. Voir Guide> Widgets d'application> Utilisation de la classe AppWidgetProvider , faites défiler jusqu'à l'exemple de code pour "ExampleAppWidgetProvider".
  • Le code du cheval de bataille dans onReceive appelle en fait onUpdate (afin de réduire la duplication de code).
  • Le code dans onUpdate(Context context) est généralisé afin qu'il puisse être déposé dans n'importe quelle sous-classe AppWidgetProvider.

Le code:

public class MyWidget extends AppWidgetProvider {

    private static final String ACTION_UPDATE_CLICK = 
              "com.example.myapp.action.UPDATE_CLICK";

    private static int mCount = 0;

    private static String getMessage() {
        return String.valueOf(mCount++);
    }

    private PendingIntent getPendingSelfIntent(Context context, String action) {
        // An explicit intent directed at the current class (the "self").
        Intent intent = new Intent(context, getClass());
        intent.setAction(action);
        return PendingIntent.getBroadcast(context, 0, intent, 0);
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
                         int[] appWidgetIds) {
        super.onUpdate(context, appWidgetManager, appWidgetIds);

        String message = getMessage();

        // Loop for every App Widget instance that belongs to this provider.
        // Noting, that is, a user might have multiple instances of the same
        // widget on
        // their home screen.
        for (int appWidgetID : appWidgetIds) {
            RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
                                                      R.layout.my_widget);

            remoteViews.setTextViewText(R.id.textView_output, message);
            remoteViews.setOnClickPendingIntent(R.id.button_update,
                                                getPendingSelfIntent(context,
                                                           ACTION_UPDATE_CLICK)
            );

            appWidgetManager.updateAppWidget(appWidgetID, remoteViews);

        }
    }

    /**
     * A general technique for calling the onUpdate method,
     * requiring only the context parameter.
     *
     * @author John Bentley, based on Android-er code.
     * @see <a href="http://Android-er.blogspot.com
     * .au/2010/10/update-widget-in-onreceive-method.html">
     * Android-er > 2010-10-19 > Update Widget in onReceive() method</a>
     */
    private void onUpdate(Context context) {
        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance
                (context);

        // Uses getClass().getName() rather than MyWidget.class.getName() for
        // portability into any App Widget Provider Class
        ComponentName thisAppWidgetComponentName =
                new ComponentName(context.getPackageName(),getClass().getName()
        );
        int[] appWidgetIds = appWidgetManager.getAppWidgetIds(
                thisAppWidgetComponentName);
        onUpdate(context, appWidgetManager, appWidgetIds);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        super.onReceive(context, intent);

        if (ACTION_UPDATE_CLICK.equals(intent.getAction())) {
            onUpdate(context);
        }
    }

}

Le widget ressemble à ceci

Widget update button example. Simple counting.

Cela s'appuie sur le travail getPendingSelfIntent de @Kels, @SharonHaimPour et @ Erti-ChrisEelmaa.

Il s'appuie également sur Android-er> 2010-10-19> Mettre à jour le widget dans la méthode onReceive () (pas moi) où il est démontré comment appeler onUpdate depuis onReceive, sur la base d'une instance de widget d'application. Je fais ce code général et je l'enveloppe dans callOnUpdate.

11
John Bentley
protected PendingIntent getPendingSelfIntent(Context context, String action) {
    Intent intent = new Intent(context, getClass());
    intent.setAction(action);
    return PendingIntent.getBroadcast(context, 0, intent, 0);
}

views.setOnClickPendingIntent(R.id.Timm, getPendingSelfIntent(context,
                              "ham"));

Préférez également l'URL:

Comment gérer correctement les événements de clic sur le widget

Si vous l'avez résolu d'une manière différente, veuillez fournir ceci comme réponse

10
Kels