48

10分ごとにサーバーからデータを取得して画面に表示するAndroidウィジェットがあります。
そのウィジェットに「更新」ボタンを追加したいのですが。
ユーザーがそのボタンをクリックしたときに、サーバーから情報を取得するメソッドを実行したいと思います。
アプリケーションのボタンにイベントハンドラーを追加するのは非常に簡単ですが、ウィジェットの例を見つけることができませんでした。
ウィジェットのボタンクリックに関数を追加するためのヘルプが必要です。

4

7 に答える 7

12

次の利点を持つ別の答えを次に示します。

  • すべてのアプリ ウィジェット インスタンスを処理します (ユーザーは、画面上にさまざまな構成/サイズでウィジェットの複数のインスタンスを持っている場合があります)。すべてのインスタンスのコーディングは、公式ドキュメントで規定されているものです。Guide > App Widgets > Using the AppWidgetProvider Class を参照して、「ExampleAppWidgetProvider」のコード例まで下にスクロールします。
  • onReceive効果的な呼び出しの主力コードonUpdate(したがって、コードの重複を減らします)。
  • のコードonUpdate(Context context)は一般化されているため、任意の AppWidgetProvider サブクラスにドロップできます。

コード:

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);
        }
    }

}

ウィジェットはこんな感じ

ウィジェット更新ボタンの例。 シンプルなカウント。

これはgetPendingSelfIntent、@Kels、@SharonHaimPour、および @Erti-ChrisEelmaa の作業に基づいています。

また、Android-er > 2010-10-19 > Update Widget in onReceive() メソッド(私ではありません) にも基づいて構築されており、App Widget インスタンス ベースで onReceive から onUpdate を呼び出す方法が示されています。私はそのコードを一般化し、callOnUpdate.

于 2014-07-22T02:48:26.603 に答える
10
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"));

URL も優先:

ウィジェットでクリック イベントを正しく処理する方法

別の方法で解決した場合は、これを回答として提供してください

于 2013-02-10T13:14:06.997 に答える
1

では、追加のpendingIntent属性appWidgetIdを追加して後で再利用しonReceive、クリックしたウィジェット インスタンスを更新することもできます。

class ExampleAppWidgetProvider : AppWidgetProvider() {

    override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray {

        appWidgetIds.forEach { appWidgetId ->
            Log.e("TAG", "onUpdate $appWidgetId")
            val pendingRefreshClickIntent: PendingIntent = Intent(context, javaClass).let {
                it.action = ACTION_REFRESH_CLICK
                it.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
                return@let PendingIntent.getBroadcast(
                    context,
                    appWidgetId, // click in all instances widget will work well (base on Alireza Mirian comment in the top answer)
                    it,
                    PendingIntent.FLAG_UPDATE_CURRENT
                )
            }

            val views = RemoteViews(
                context.packageName,
                R.layout.example_appwidget
            )
            views.setOnClickPendingIntent(R.id.button_refresh, pendingRefreshClickIntent)

            appWidgetManager.updateAppWidget(appWidgetId, views)
        }
    }

    override fun onReceive(context: Context?, intent: Intent?) {
        super.onReceive(context, intent)
        Log.i("TAG", "onReceive " + intent?.action)

        if (intent?.action == ACTION_REFRESH_CLICK) {
            val appWidgetId = intent.extras?.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID) ?: return
            Log.i("TAG", "onReceive appWidgetId $appWidgetId")

            val appWidgetManager = AppWidgetManager.getInstance(context)
            val views = RemoteViews(context!!.packageName, R.layout.example_appwidget)

            views.setTextViewText(R.id.text_data, "a " + (Math.random() * 9).roundToInt())
            appWidgetManager.updateAppWidget(appWidgetId, views)
        }
    }

    companion object {
        private const val ACTION_REFRESH_CLICK =  "com.example.androidwidgetbuttonclick.action.ACTION_REFRESH_CLICK"
    }
}

ウィジェットの初期レイアウト

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/text_data"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="AA"
        android:textSize="20sp" />

    <Button
        android:id="@+id/button_refresh"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Refresh" />
</LinearLayout>
于 2021-02-17T03:47:53.743 に答える