I'm creating a fairly common use case of AppWidget on Android.
- AppWidgetProvider calls
onAppWidgetOptionsChanged()
(stretchable widget) andonUpdate()
(timed) - From those methods I start an
IntentService
. Case coming from options changed I pass the new size in the Intent. - The service contacts a web-service, builds the RemoteViews and calls
updateAppWidget()
my main test device is a Nexus 7 (2012) running stock 4.3 (stock Launcher)
The widget does not use RemoteViewFactory and does not user AlarmManager. It's a static view with a constant time defined in XML.
It works most of the times, but sometimes the call to updateAppWidget()
is completely ignored by the Launcher and no update happens on the screen. If I force close the launcher, clear it caches and re-size the widget (forcing an update) then it updates.
I believe there's something to do with frequency of update because I tricked up some stuff in the IntentService to, whenever it's resizing, only call to the last intent (when the user stops messing with the widget) and it soften a bit the issue.
Let's show some simplified code (it's very standard, i believe):
public class AlbumWidgetService extends WidgetUpdateIntentService {
@Override
protected void onHandleIntent(Intent intent) {
// get's widgetID or array of IDs and pass to 'doTheJob'
}
private void doTheJob(int appWidgetId, int heightInDp, int widthInDp) {
// ...
// here goes code with pre calculations and get data
// ...
// create Intent and PendingIntent with some extras
Intent intent = ... etc
PendingIntent pi = PendingIntent.getActivity( ... etc
// get url for some images
List<String> imageFilenames = getImagesFilename(albumId, totalImages);
// Create the remote view
RemoteViews views = new RemoteViews(getPackageName(), R.layout.album_widget);
// ...
// here goes a bunch of code that load bitmaps from the URLs
// set text and colors in the remote view
// put ImageViews into the remote view, etc
// ...
try {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
appWidgetManager.updateAppWidget(appWidgetId, views);
Log.d(this, "Updating the widget id " + appWidgetId);
} catch (Exception e) {
// this exception happens if the RemoteView is too big, have too many bitmaps.
// I'm already minizing this to happen with the pre calculations, but better safe than sorry
Log.e(this, "Failed to update the widget id " + appWidgetId, e);
}
}
as I said, the thing mostly works (I can see the Log and I can see the on-screen result. But every once in a while it does not update after a resize, even thou I can see the Log and it did not crashes or anything.
ideas?