我有一个接收器正在监听,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,然后再次从APPWIDGET_UPDATE
广播)。
此外,这似乎只发生在我的 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()
}