【发布时间】:2014-01-12 05:13:47
【问题描述】:
我正在向一个旧应用程序添加一个小部件,该小部件正在从我用来在后台(警报)轮询数据的服务中更新。每次服务获得结果时,我都会更新小部件。这目前工作正常。
// Called from inside my service when it has results
private void updateWidget(List<Earthquake> earthquakes) {
AppWidgetManager manager = AppWidgetManager.getInstance(this);
int[] appWidgetIds = manager.getAppWidgetIds(new ComponentName(this, WhatsShakingWidgetProvider.class));
if (appWidgetIds == null || appWidgetIds.length == 0)
return;
Earthquake earthquake = earthquakes.get(0);
RemoteViews views = new RemoteViews(getPackageName(), R.layout.widget_detail);
// Update views
views.setTextViewText(R.id.widget_detail_latest_magnitude, earthquake.getFormattedMagnitude());
// etc...
// Update each widget
for(int appWidgetId : appWidgetIds) {
manager.updateAppWidget(appWidgetId, views);
}
}
此轮询服务是可选的;它可以在应用程序的设置中打开或关闭。
如果服务关闭当用户添加小部件时,widget_error 布局将按预期显示。用户可以点击小部件以输入设置并打开后台更新。当他们这样做(打开或关闭设置)时,我广播ACTION_APPWIDGET_UPDATE。小部件正确输入onUpdate,并在下次运行时由服务正确更新(我已对其进行设置,以便小部件在onUpdate 中触发服务调用 - 见下文)。
当服务在启用后被禁用时,小部件不正确显示 widget_error 布局 - 即使所有禁用案例代码都已运行,它仍保留旧布局。
这是用户切换设置时调用的代码 (Source):
// If our user has widgets, we should update those - let the widget do the updating depending on the prefs, though.
Intent intent = new Intent(this, WhatsShakingWidgetProvider.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
// Use an array and EXTRA_APPWIDGET_IDS instead of AppWidgetManager.EXTRA_APPWIDGET_ID,
// since it seems the onUpdate() is only fired on that:
int[] ids = { R.xml.widget_info };
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
sendBroadcast(intent);
这是onUpdate 中的代码,它应该更新小部件,但不是:
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean backgroundUpdatesEnabled = prefs.getBoolean(PreferenceActivity.KEY_PREF_ALLOW_BG_NOTIFICATIONS,
DefaultPrefs.BG_NOTIFICATIONS_ENABLED);
if (!backgroundUpdatesEnabled) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_error);
// Update click to take to preferences
Intent intent = new Intent(context, PreferenceActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.widget_error_parent_container, pendingIntent);
// Update each widget
appWidgetManager.updateAppWidget(appWidgetIds, views);
} else {
// Let's get some data for the user! Service does the work of updating the views.
WakefulIntentService.sendWakefulWork(context, GeonetService.class);
}
}
Logcat 中没有记录错误。通过这个,我在预期的时候正确输入了if的每个部分(也就是说,如果用户关闭了设置,那么我将RemoteViews views创建为widget_error,否则我启动服务)。
为什么widget_error 布局第一次通过onUpdate 正确显示,但当用户启用然后禁用后台更新设置时却没有?
我尝试将其包装在 RelativeLayout 中并设置错误消息/内容的可见性,但这表现出相同的行为 - 在最初隐藏错误消息后,我无法将其显示出来。
【问题讨论】: