I noticed strange behavior of the widget in my app. Sometimes the onDataSetChanged() method from RemoteViewsFactory class is not called (of course when the app is in the background and widget is visible) even though the notifyAppWidgetViewDataChanged() from AppWidgetManager class works correctly. I don't see any specific situation where this is happening - just sometimes it works, sometimes it doesn't. I spent a lot of time on debugging - everything looks like it's working fine.
val ids: IntArray = appWidgetManager.getAppWidgetIds(ComponentName(context, MyWidgetProvider::class.java))
appWidgetManager.notifyAppWidgetViewDataChanged(ids, R.id.appwidget_list_view)
I noticed that when I change it to:
ids.forEach { id ->
appWidgetManager.notifyAppWidgetViewDataChanged(id, R.id.appwidget_my_access_list_view)
}
the problem occurs less frequently, but maybe it's coincidence. Significant code snippets:
MyWidgetProvider: AppWidgetProvider()
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
super.onUpdate(context, appWidgetManager, appWidgetIds)
appWidgetIds.forEach { id ->
/* *** */
val intent = Intent(context, MyWidgetRemoteViewsService::class.java).apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id)
data = Uri.parse(toUri(Intent.URI_INTENT_SCHEME))
}
val remoteViews = RemoteViews(context.packageName, R.layout.my_widget).apply {
setRemoteAdapter(R.id.my_widget_list_view, intent)
/* *** */
}
appWidgetManager.apply {
updateAppWidget(id, remoteViews)
}
}
}
MyWidgetRemoteViewsService: RemoteViewsService()
@AndroidEntryPoint
class MyWidgetRemoteViewsService : RemoteViewsService() {
@Inject lateinit var itemStore: LockStore
override fun onGetViewFactory(intent: Intent) = MyAccessRemoteViewsFactory(applicationContext, itemStore)
}
AndroidManifest
<receiver
android:name=".MyWidgetProvider"
android:label="My app">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/appwidget_info"/>
</receiver>
<service
android:name=".MyWidgetRemoteViewsService"
android:permission="android.permission.BIND_REMOTEVIEWS"/>