使用appWidgetId检查主屏幕上是否存在小部件

我正在使用AlarmManager更新我的小部件。 如果主屏幕上没有小部件,我想停止它。 但是我在检测主屏幕上是否有小部件时遇到问题。

正如每当我尝试使用这种方式获取AppWidgetIds:

 AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); int[] appWidgetIDs = appWidgetManager .getAppWidgetIds(new ComponentName(context, Widget.class)); 

我得到了一段appWidgetIDs而实际上在主屏幕上没有任何部件。 为什么?

因此,我想知道是否有一种方法来检测到主屏幕上存在一个小部件ID。

谢谢你。

Solutions Collecting From Web of "使用appWidgetId检查主屏幕上是否存在小部件"

恭喜,你遇到了幽灵appwidgets。 它似乎logging在Android问题跟踪器上 。 它们通常在appwidget的configuration活动被取消时发生,尽pipe似乎是通过不正确的configuration活动来实现的。 在将活动结果设置为RESULT_CANCELED时,开发人员忽略了将appwidget ID作为额外值。 (即使Google的ApiDemos示例应用程序忽略了这一点!)

正确的实现是这样的:

 public class AppWidgetConfigActivity extends Activity { private int appWidgetId; private Intent resultValue; protected void onCreate(bundle saved) { super.onCreate(saved); // get the appwidget id from the intent Intent intent = getIntent(); appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); // make the result intent and set the result to canceled resultValue = new Intent(); resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); setResult(RESULT_CANCELED, resultValue); // if we weren't started properly, finish here if (appwidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) { finish(); } /* ... */ } /* ... */ private void finishConfigure() { /* finish configuring appwidget ... */ setResult(RESULT_OK, resultValue); } } 

到目前为止,我知道没有办法在没有自己的簿记的情况下检测幻影appwidget的存在。 我build议存储一个SharedPreferences值,指出configuration活动没有被取消,然后在你的其他代码中查询这个值。 如果遇到幻像小部件,也可以使用这些信息来“删除”幻影小部件。 在您的appwidgetconfiguration活动中:

 private void finishConfigure() { /* finish configuring appwidget ... */ setResult(RESULT_OK, resultValue); String key = String.format("appwidget%d_configured", appwidgetId); SharedPreferences prefs = getSharedPreferences("widget_prefs", 0); prefs.edit().putBoolean(key, true).commit; } 

然后你可以检查你至less有一个非幻影appwidget是这样的:

 AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); AppWidgetHost appWidgetHost = new AppWidgetHost(context, 1); // for removing phantoms SharedPreferences prefs = getSharedPreferences("widget_prefs", 0); boolean hasWidget = false; int[] appWidgetIDs = appWidgetManager.getAppWidgetIds(new ComponentName(context, Widget.class)); for (int i = 0; i < appWidgetIDs.length; i++) { int id = appWidgetIDs[i]; String key = String.format("appwidget%d_configured", id); if (prefs.getBoolean(key, false)) { hasWidget = true; } else { // delete the phantom appwidget appWidgetHost.deleteAppWidgetId(id); } } if (hasWidget) { // proceed } else { // turn off alarms }