Android窗口小部件-单击按钮时更新

时间:2019-11-01 12:26:27

标签: java android widget

美好的一天。 我正在尝试创建一个小部件,将在屏幕上显示余额。 创建了2个按钮,并设置了侦听器以确定按下了哪个按钮。

难度: 如何通过单击按钮来更新数据或重新加载小部件以更新数据?

import android.app.AlarmManager;
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.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.text.DateFormat;
import java.util.Date;

public class EthWidgetProvider extends AppWidgetProvider {
    private static final String SYNC_CLICKED    = "automaticWidgetSyncButtonClick";
    private static final String SYNC_CLICKED2    = "automaticWidgetSyncButtonClick2";


    static void updateAppWidget(final Context context, final AppWidgetManager appWidgetManager, final int appWidgetId) {
        RequestSingleton.getInstance(context).fetchData(new VolleyCallback() {
            @Override
            public void onSuccessRequest(JSONArray result) {
                Log.i("Response", result.toString());
                String price = "";
                try {
                    JSONObject etherObject = result.getJSONObject(0);
                    price = etherObject.getString("price_usd");
                } catch (JSONException e) {
                    Log.e("JSONException", e.toString());
                }
                Log.i("Price", price);
                RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_widget);
                views.setTextViewText(R.id.gprs, "$" + price);

                String currentDateTimeString = DateFormat.getDateTimeInstance().format(new Date());
                views.setTextViewText(R.id.timeofday, currentDateTimeString);

                appWidgetManager.updateAppWidget(appWidgetId, views);
            }
        });
    }
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {


        RemoteViews remoteViews;
        ComponentName watchWidget;

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

        remoteViews.setOnClickPendingIntent(R.id.refresh, getPendingSelfIntent(context, SYNC_CLICKED));
        remoteViews.setOnClickPendingIntent(R.id.example_widget_button, getPendingSelfIntent(context, SYNC_CLICKED2));
        appWidgetManager.updateAppWidget(watchWidget, remoteViews);

        for(int appId : appWidgetIds) {
            updateAppWidget(context, appWidgetManager, appId);
        }
    }

    @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.example_widget);
            watchWidget = new ComponentName(context, EthWidgetProvider.class);

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

            appWidgetManager.updateAppWidget(watchWidget, remoteViews);

        }

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

            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);

            RemoteViews remoteViews;
            ComponentName watchWidget;

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

            remoteViews.setTextViewText(R.id.timeofday, "TESTING2");

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

按按钮1,我需要显示活动。通过按下第二个按钮,您需要更新窗口小部件,以便更新数据,即,再次发送到服务器的请求并更新数据。

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:0)

我对广播没有任何想法。

  1. 广播不应是内部类
  2. 广播应扩展BroadcastReceiver类
  3. 广播应在清单中定义

因此,执行此操作时,应在单击按钮后调用接收器。

但是,您想要唤醒小部件的功能。然后Widget#onUpdate将获取更新的数据(您在Widget点击时下载的数据)并显示它们。 要请求更新小部件,您可以使用以下内容:

public static void updateAppWidget(@NonNull Context applicationContext,
        @NonNull Class<? extends AppWidgetProvider> widgetProviderClass) {
    final ComponentName component = new ComponentName(applicationContext, widgetProviderClass);
    final int[] widgetIds;
    try {
        widgetIds = AppWidgetManager.getInstance(applicationContext).getAppWidgetIds(component);
    } catch (RuntimeException re) {
        Log.d(re, "Unable to obtain widget IDs.");
        return;
    }

    if (widgetIds.length == 0) {
        Log.d("There is no widget to be updated.");
        return;
    }

    final Intent intent = new Intent(applicationContext, widgetProviderClass);
    intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, widgetIds);

    applicationContext.sendBroadcast(intent);
}

所以总结一下:

  • 在小部件设置视图中,侦听器并使用最新已知数据填充。
  • 在监听器中广播打开“活动”或运行一些下载
  • 别忘了BroadcastReceivers正在UI线程上运行;采用 goAsync()方法。
  • 下载的数据应存储在小部件可以放置的位置 获得它们
  • 调用提到的函数来触发小部件更新。

我相信,这是一个非常具体且复杂的主题,与其他Android设备不同,请随时提出任何我可能会错过的问题:)

答案 1 :(得分:0)

呼叫活动:

remoteViews.setOnClickPendingIntent( R.id.button1, PendingIntent.getActivity(context, 0, new Intent( context, Main.class), 0) );

要更新另一个类中的小部件:

AppWidgetManager appWidgetManager = AppWidgetManager.getInstance( context );
int ids[] = appWidgetManager.getAppWidgetIds( componentName );
for( int id : ids ){
    //update textView here
    appWidgetManager.updateAppWidget( id, views);
}

答案 2 :(得分:0)

有一本非常有用的必读官方指南,标题为“构建应用程序小部件”: (https://developer.android.com/guide/topics/appwidgets

请仔细阅读此页,以便您理解概念并集中精力解决问题的AppWidgetProvider部分。尽管在本节中,它们使用:PendingIntent.getActivity(),但您应该将服务用作PendingIntent.getService(),以使单击按钮时调用服务,然后让服务更新您的小部件。

基本上,您会看到需要:

  1. 创建服务

  2. 创建待定意图:

    Intent intent = new Intent(context, YourService.class);
    PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
    
  3. 像这样在您的RemoteViews对象上设置onClickPendingIntent侦听器:

    views.setOnClickPendingIntent(R.id.button, pendingIntent);