Good point, the backend service is sending the wrong extras--fixing that now.
Another simple way to fix would be to override onReceive to handle
this special-case early before passing to AppWidgetProvider through
> Additionally (and I haven't investigated this yet) there appears to be a
> possible deficiency in the timeliness of ACTION_APPWIDGET_UPDATED
> broadcast cessation.
Hmm, that seems odd. It might be related to how updates are
scheduled; what interval are you using? Widget updates are handled
using the new AlarmManager.setInexactRepeating(), which can help save
battery, but can be a little unpredictable.
> The image is not requested again. What is causing
> this, over-aggressive optimization in the handling of RemoveViews by the
> widget framework, or something else?
It might be an optimization in ImageView, since it already has that
Uri loaded. It might be enough to have two RemoteView actions, one to
unset it and another to set it back.
> (Again the workaround is simple: decorate the Uri with something distinctive
> like a timestamp so that the Uri is unique on each request.)
That sounds like a good solution too.
It recycles entire layouts. If you send a RemoteViews with the same
layout, it just applies the new set of actions over the top of the
existing layout, including any current state. So to be safe you'll
want to cover all cases when pushing an update. For example, if you
hide a view in one special case, you'll want to explicitly set it
visible again for all other cases, because you can't know the current
state you're recycling against. (Or you can just use a different
layout for each case, possibly taking advantage of <include /> as
> I'm receiving a perpetual string
> of updates that include the id that should be delete,
Yes, that does look like a bug. It looks like the extras bundle in
that broadcast lagging behind because we're not resetting it on
delete. If you /add/ a widget, it should force a refresh of that
broadcast bundle and remove any deleted IDs.
> when my widget is added,
> the APPWIDGET_UPDATE broadcast is received _before_ the configuration
> activity is displayed.
Yes, that's correct. The configure activity is launched by the
AppWidgetHost (in this case Launcher), instead of by the
AppWidgetService. This allows a custom AppWidgetHost to have
pre-configuration placement on their home screen. Also, it forces
developers to push an explicit update when their configuration is
finished. (This makes sure they are ready for AppWidgetHosts that can
launch configure at any time, not just during first-insert.)
> If I cancel the activity (ie. return a
> RESULT_CANCELED as the result) I will continue to receive update events for
> this new phantom widget - it's not visible anywhere but continues to be
> included in update requests.
Are you passing back the appWidgetId in the result extras bundle when
sending back the RESULT_CANCELED? Launcher should try cleaning up any
"canceled" widgets like that, but only if the EXTRA_APPWIDGET_ID is
Oops, you're right, thanks for catching that. For the example widgets
I've been writing that use configuration steps, I've been keeping an
internal CONFIGURED flag which I use to skip updates. Because I was
skipping non-configured widget updates, I never noticed this myself.
(I also used this flag to skip the first update before the
configuration step has been completed.)
Also, a quick update on the fixes: most of them will be delayed until
the next platform release because the device-bound code is already
frozen. We could fix it for the SDK, but it would be bad to have
different behavior between the two. We definitely have bugs filed for
these, and they will be fixed.
Thanks for digging in and finding them. :)