【发布时间】:2013-01-30 21:37:35
【问题描述】:
我有一个接收器正在监听android.net.conn.CONNECTIVITY_CHANGE,这样我就可以在连接恢复时更新我的 appwidget。这很好用,只是当我通过以下方式启用或禁用接收器时出现一些奇怪的行为:
ComponentName receiver = new ComponentName(this, NetworkStateReceiver.class);
PackageManager pm = getPackageManager();
pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
当状态改变时,我还会收到一个android.appwidget.action.APPWIDGET_UPDATE 广播到我的 appwidget 的接收器,导致我的 appwidget 在检测到连接丢失后再次更新,然后在返回连接时两次(一次是故意来自我的 NetworkStateReceiver,然后再次来自 @ 987654325@广播)。
另外,这似乎只发生在我的 4.04 设备上,而不是我的 2.1 设备上。
NetworkStateReceiver 和 AppWidgetProvider 的清单
<receiver
android:name=".AppWidgetProvider"
android:label="@string/widget_name" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/appwidget" />
</receiver>
<receiver
android:name=".NetworkStateReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
我尝试了几种方法来解决这个问题,但都不是很好的解决方案。
我可以忽略来自APPWIDGET_UPDATE 广播的任何更新。实际上,我已经这样做了,因为我的所有 appwidget 更新都是在首次创建时通过警报管理器或配置活动通过服务进行的。尽管出于某些原因(并且可能表明正在发生的事情),APPWIDGET_UPDATE 广播也会导致我的远程视图恢复到其 XML 状态,就像它第一次添加一样。我也可以通过保存额外的状态(包括位图)来解决这个问题。不理想。
我可以让 NetworkStateReceiver 一直监听而不是启用/禁用,但这违背了 Android 的建议,并且有充分的理由,因为这意味着不必要的广播。
其他想法?
编辑:进一步解释我目前的解决方法。
即使我使用警报来触发我的更新,我也不能忽略 APPWIDGET_UPDATE 广播。这是因为APPWIDGET_UPDATE 还将我的小部件重置为其初始状态,就像它第一次添加到主屏幕一样。在我有连接的情况下,我可以进行双重更新,因为所有信息都可以重新填充。我还必须自己进行更新,因为该错误似乎是特定于设备的,而未受影响的设备仍需要更新。
如果我没有连接,我会从之前保存的状态恢复小部件。这意味着每次我成功更新时,我都会将所有内容保存到 SharedPreferences 中,以便当互联网无法正确重新填充数据时,它可以在这些“强制更新”之一下恢复。
在我的AppWidgetProvider 我做(简化):
Intent intent = new Intent(context, WidgetUpdateService.class);
intent.putExtra("loadFromSaved", true); // this will be false when coming from AlarmManager
context.startService(intent);
WidgetUpdateService.onStartCommand()(也简化了):
if (intent.getExtras().getBoolean("loadFromSaved") {
widgetLoader.loadFromSavedData();
} else {
widgetLoader.load()
}
【问题讨论】:
-
保罗 - 我也有同样的问题。它让我发疯!.....
-
我还没有找到好的解决方案。我现在正在通过保存额外的状态来解决它。如果您发现了什么,请发布!我看到了这个bug report,它是不同的,但可能是相关的。
-
保罗 - 我仍然没有进一步前进。我很想听听你的解决方法,节省额外的状态。你介意分享一下吗? ta
-
Funkatron - 我实际上可能会切换回让 NetworkStateReceiver 一直在监听(而不是禁用它)。浪费资源,但似乎比我现在做的更干净。我将发布并编辑或回答以解释我的解决方法。
-
保罗 - 感谢您的快速响应。我觉得我可能只是不停地听,我不喜欢它,看到那个东西多久触发一次,很浪费,但是该怎么办?谢谢
标签: android broadcastreceiver android-appwidget