传递RESULT_CANCELED作为configuration活动的结果时,Widget不会被删除

我的部件有一些问题。 这里是描述:

语境:

我有一个家庭小部件。

当我添加它时,它popup一个configuration活动,为小部件设置一些参数。

如果我调用setResult(RESULT_OK,resultValue); 在完成configuration活动之前,小部件被添加到主页。

如果我通过拖动它到垃圾箱删除小部件,我的AppWidgetProvider类中的public void onDeleted(Context context,int [] appWidgetIds)被调用。 到现在为止还挺好。

问题:如果configurationActivity以结果代码RESULT_CANCELED( setResult(RESULT_CANCELED); )退出,则不会调用AppWidgetProvider类中的public void onDeleted(Context context,int [] appWidgetIds) ,并且该小部件保留在活动小部件列表中。 当我重新启动手机,从我的AppWidgetProvider类的onUpdate(上下文上下文,AppWidgetManager的appWidgetManager,int [] appWidgetIds)被调用,并在int [] appWidgetIds我有所有应该被取消的部件(ids) +活动的(主页上实际显示的)。 通过拖到垃圾箱删除的小部件不会显示在此列表中。 随着时间的推移,如果用户从configuration活动中取消,这个小部件ID列表会越来越大。

这个API的引用是这样的:“如果你使用Activity.setResult()返回RESULT_OK,AppWidget将会被添加,并且你会收到一个ACTION_APPWIDGET_UPDATE广播给你的AppWidget,如果你返回RESULT_CANCELED,主机将取消添加而不是显示这个AppWidget,你将收到一个ACTION_APPWIDGET_DELETED广播。“

任何人都可以给我一些提示吗? 谢谢。

这是我的清单:

<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true"> <receiver android:name=".MytWidget" android:label="@string/app_name"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/my_widget_provider" /> </receiver> <activity android:name=".ConfigurationActivity"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" /> </intent-filter> </activity> </application> 

其余的代码是不相关的,因为它是上面解释(我没有权限发布)。

Solutions Collecting From Web of "传递RESULT_CANCELED作为configuration活动的结果时,Widget不会被删除"

我有这个相同的问题,我在onPause事件做了这个

 public void removeWidget(int appWidgetId) { AppWidgetHost host = new AppWidgetHost(Config.this, 1); host.deleteAppWidgetId(appWidgetId); } 

检查了窗口小部件ID,窗口小部件被移除。 如果您只有一个应用部件主机,则主机ID不重要。

 private boolean canceled = true; @Override protected void onPause() { if(canceled) { removeWidget(appWidgetId); } super.onPause(); } 

在确定点击,我设置canceled

你确定你的代码不相关? 你的清单中的所有东西都不在书里,看起来不错。 你的代码看起来应该和这个非常相似:

  public void configCancelOnClick(View v) { MyLog.d(TAG, "configCancelOnClick"); Intent intent = new Intent(); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); setResult(RESULT_CANCELED, intent); finish(); } 

putExtra需要告诉操作系统哪个小部件你没有创build…完成需要正确closures。 如果你没有它,你将无法正确地传递给操作系统,并失去setResult。

最后,当configuration没有正确退出(返回键,主键或错误代码)时,会创build一个ghost小部件。 即使使用完美的代码,如果用户在configuration时点击home键,您将有一个小部件排队到系统,并不存在于任何主屏幕上。 这就是为什么我叫他们的鬼。 一旦一个小部件成功完成configuration,它将调用onDeleted从主屏幕中删除。 你留下的问题是,如果鬼魂已经创build,onDisabled将永远不会运行。

最后一张支票。 由于configuration运行,你有你的信息XML文件中的以下内容。 但为了以防万一,它看起来像这样:

  android:configure=your.package.name.ConfigurationActivity" 

我解决了这个问题,

在小部件提供程序的onUpdate()方法中,我检查是否configuration了小部件,如果不是,我什么都不做,所以没有ghost小部件。 在configuration结束时,我把它设置为true,我很好。 删除小部件时,不要忘记从sharedpreference中删除它。

 @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); for(final int appWidgetId : appWidgetIds) { final StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(appWidgetId); stringBuilder.append("_conf"); if(context.getSharedPreferences("settings",0).getBoolean(stringBuilder.toString(),false)) updateAppWidget(context,appWidgetId,appWidgetManager); } } 

自从年纪以来,小部件似乎有很多问题。 这就是说,当寻找一个解决scheme,其中之一,我偶然发现这个post: https : //code.google.com/p/android/issues/detail?id=2539#c15

基本上,这个想法是从清单中删除应用程序configuration活动,并在onUpdate期间检查是否configuration了小部件,如果没有打开configuration活动。

这是完全透明的用户,据说解决“添加/僵尸部件”的问题。 现在就试试。


但是,它并不能解决重新启动时删除的小部件被更新的问题,即使它在最近的Android版本(4.4+不知道哪一个版本?)中似乎已经被修复了。

在老版本的Android上,我观察到,我手动从启动程序中移除的所有小部件在重新启动时转换为僵尸,操作系统有效地为每个小部件调用onUpdate,因此我必须保留已删除小部件的列表。

现在被删除的小部件ID实际上被重新用于新的小部件,所以我必须停止跟踪已删除的小部件。 可悲的是,我不知道什么时候(哪个Android版本)这个问题已经解决,ID开始重新使用。