Issue
tl;dr question:
How to properly refresh widget e.g. every minute making network request in background, reliably working Android 5-13 and according to policy
I have an app widget which needs to be refreshed more often than forced updatePeriodMillis
and also should provide self-refresh button. Self interval refreshing is made with AlarmManager
and works pretty good and under button click I have same PendingIntent
:
Intent intent = new Intent(REPORT_WIDGET_RUN_UPDATE);
intent.setClass(context, ReportAppWidgetProvider.class);
return PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
On providers side onReceive
gets called in both cases and I should do some network now. I'm using Volley, so its trivial, but with context
passed to onReceive
I'm always getting timeouts...
Few year ago I've started to use Service
for this purpose, but starting Android 8 ForegroundService
must be used for such case (background work, not running any Activity
). I didn't wanted to show "auto-disappearing" notification to often, so I've switched to JobIntentService
. It has some nasty rare bug and it's deprecated now, so even if it works pretty good I've decided to move on to WorkManager
as suggesting last post under link, also official doc or some articles (e.g. this).
So now my JobIntentService
becomes Worker
followed by this article, Context
in workers contructor works with Volley, network connection is done, feedback-broadcast is sent to provider and... After whole operation I'm getting VERY unwanted system-called android.appwidget.action.APPWIDGET_UPDATE
. It's not mine action and it breaks my flow!
In Android 13 I see some suggestion in system logs why I'm getting this call
I/LauncherAppWidgetHostView: App widget created with id: 33
I/LauncherAppWidgetHostView: App widget with id: 33 loaded
So my widget after such refresh operation gets "recreated"... Behavior is exacly same on Android 10, but without above/any logs (different launcher)
My question is: how to properly refresh widget with network request in background, reliably working Android 5-13 and according to policy?
Maybe should I stick with sometimes-appearing ForegroundService
as starting 13 it will be hidden anyway? As far as I remember there is some few-sec-limit for NOT-showing notification? It would be sufficient for me to make network call and then broadcast response to appwidget provider (call made with 3-4 sec. timeout thrown). Any suggestion, preferably working example appreciated
Solution
My guess is that you're running into the known WorkManager
issue where it "restarts" your widget every time. I originally couldn't figure out what was causing this, but there are several issues reported on Google's Issue Tracker, including this one that I filed. And the workaround top fix this issue is
to create a one-time Worker set to 10 years out, (use setInitialDelay) and set at least one constraint on it
You can see the code in my answer here
Answered By - user496854
Answer Checked By - Dawn Plyler (JavaFixing Volunteer)