[英]Android Widget - update when a button is clicked
Good day.再会。 I'm trying to create a widget that will show the balance on the screen.我正在尝试创建一个将在屏幕上显示余额的小部件。 Created 2 buttons and set up the listener to determine which button was pressed.创建 2 个按钮并设置侦听器以确定按下了哪个按钮。
Difficulty: How to update data by clicking on the button or reload the widget so that the data is updated?难点:如何通过点击按钮更新数据或重新加载widget从而更新数据?
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);
}
}
By pressing button 1, I need to show the activity.通过按下按钮 1,我需要显示活动。 By pressing the second button, you need to update the widget so that the data is updated, that is, so that the request to the server goes again and the data is updated.通过按下第二个按钮,您需要更新小部件,以便更新数据,即再次向服务器发出请求并更新数据。
Any help would be appreciated.任何帮助,将不胜感激。
I don't get you idea with the Broadcast.我不明白你对广播的看法。
So when you do this, your receiver should be called after buttons are clicked.因此,当您这样做时,应在单击按钮后调用您的接收器。
But, you want something to wake up your Widget.但是,你想要一些东西来唤醒你的小部件。 And then Widget#onUpdate will fetch the updated data (that you download on widget click) and show them.然后 Widget#onUpdate 将获取更新的数据(您在小部件单击时下载的数据)并显示它们。 To request update of your widget, you can use something like this:要请求更新您的小部件,您可以使用以下内容:
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);
}
So to sum it up:所以总结一下:
I believe, this is a quite specific and complex topic unlike the rest of Android, so feel free to ask anything I might missed:)我相信,与 Android 的 rest 不同,这是一个非常具体和复杂的话题,所以请随时问我可能错过的任何问题:)
To call activity:调用活动:
remoteViews.setOnClickPendingIntent( R.id.button1, PendingIntent.getActivity(context, 0, new Intent( context, Main.class), 0) );
To update widgets from another class:要从另一个 class 更新小部件:
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance( context );
int ids[] = appWidgetManager.getAppWidgetIds( componentName );
for( int id : ids ){
//update textView here
appWidgetManager.updateAppWidget( id, views);
}
There is a very helpful must-read official guide titled "Build an App Widget": ( https://developer.android.com/guide/topics/appwidgets )有一个非常有用的必读官方指南,标题为“构建应用程序小部件”:( https://developer.android.com/guide/topics/appwidgets )
Please read this page carefully so you understand the concepts and focus on the AppWidgetProvider section for your problem.请仔细阅读此页面,以便您了解概念并针对您的问题关注AppWidgetProvider部分。 Although in this section, they use: PendingIntent.getActivity()
, you are supposed to use a Service as PendingIntent.getService()
to have your Service called on button click, and then have the Service update your Widget.尽管在本节中,他们使用: PendingIntent.getActivity()
,但您应该使用服务作为PendingIntent.getService()
以在单击按钮时调用您的服务,然后让服务更新您的小部件。
Basically you'll see that you need to:基本上你会看到你需要:
Create a Service创建服务
Create a PendingIntent:创建一个 PendingIntent:
Intent intent = new Intent(context, YourService.class); PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
Set the onClickPendingIntent
listener on your RemoteViews object like this:在 RemoteViews object 上设置onClickPendingIntent
侦听器,如下所示:
views.setOnClickPendingIntent(R.id.button, pendingIntent);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.