我正在将一个小部件添加到一个旧应用程序中,我正在使用的服务进行更新,以便在后台轮询数据(在警报上)。每次服务获得结果时我都会更新小部件。这目前正常。
// 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
并设置错误消息/内容的可见性,但显示相同的行为 - 我无法在最初隐藏后显示错误消息它
答案 0 :(得分:1)
我最终在两个地方复制代码(首选项活动和小部件提供程序)并且它工作正常。唯一的变量似乎是Context
对象。
出现由于某种原因,您在Context
(即AppWidgetProvider
)中获得的onUpdate
个实例仅在第一次运行时 - 或者,我自己发送广播时不起作用。我不确定为什么。
我将重复的代码提取到一个单独的类中,然后传入我可用的Context
实例,无论是Service
,Activity
还是{{1} }(这是AppWidgetProvider
)。这正确地更新了小部件,我可以从任何有BroadcastReceiver
的地方调用它。