Two bug reports that turned out to be the same release.
The first: someone kept two widgets on their home screen, one for where they live and one for where they work. Changing the location on one changed both.
The second: pulling to refresh in the app updated the app and left the widget showing the old reading, sometimes for hours.
Widgets are instances, and their configuration is per instance
When a widget is placed, the system assigns it an id. That id is how everything about that particular widget is addressed — its layout, its configuration, its updates. Two widgets from the same app are two ids and two independent configurations.
Our configuration screen saved the selected location to a preference. One preference. Every widget read the same value, so there was only ever one location no matter how many widgets you had.
This is an easy bug to write and a hard one to notice, because it is invisible with one widget and every developer tests with one widget. The moment there are two, it is the only thing you can see.
The correct storage is keyed by widget id, and the configuration activity has to know which id it was launched for — the system passes it in the intent that starts the configuration screen. Getting an id and then writing to a global key is precisely the mistake, and it is the sort of thing that looks fine in review because the id is right there in the code, being used for something else.
The migration was the awkward part. Existing users had one stored location and an unknown number of widgets. We assign that location to all existing widgets, which preserves what they were seeing, and their configurations diverge from the next edit onwards.
Widget ids are also not stable across a backup and restore. A restored home screen produces new ids, and configuration stored against the old ones is orphaned. We detect a widget id with no configuration and prompt rather than silently showing a default location, because a weather widget confidently showing the wrong city is worse than one asking a question.
A widget cannot refresh whenever it wants
The second bug is about a constraint people find surprising: a widget is not a live view of your app's data. It is a set of instructions the system renders on your behalf, and it only changes when you push a new set.
The periodic update mechanism built into the widget system has a floor of half an hour, and it does not wake a sleeping device — updates land when the device is next awake. Background work scheduling has its own floor and its own deferral behaviour under Doze. None of these are things you can opt out of, and they exist for good reasons: a home screen full of widgets each polling on its own schedule is a phone with no battery.
So a widget's data is periodically stale by design, and the question is only how the app handles the moments when the user has explicitly asked for something.
Our failure was that a manual refresh in the app updated the app's own state and did not push new content to the widgets. The data was fresh. The rendering on the home screen was not, because nothing had told it to change.
Now anything that changes what a widget should display — a manual refresh, a configuration change, a location update — pushes to the affected widgets immediately. The periodic schedule handles the background case; explicit user actions are handled explicitly rather than waiting for it.
Each widget also shows how old its reading is. This is the part we would put in first if we were starting again. A weather widget with no timestamp invites you to believe it is current, and given everything above, sometimes it is not. A small "updated at" removes an entire category of confusion at almost no cost in space.
Air quality is not on the same clock as temperature
A wrinkle that made the staleness question worse.
Temperature, forecast, air quality, and UV do not come from the same place or update at the same rate. Air quality readings come from monitoring stations with their own reporting cadence and their own coverage — a location can have a perfectly good forecast and no nearby station at all. UV is modelled and has its own update pattern.
The original widget rendered them together as though they were one observation. A fresh temperature next to an air quality figure from several hours earlier looked like one current reading and was not.
Each measurement now carries its own age, and a measurement that is unavailable for a location is shown as unavailable rather than omitted. An absent value that simply is not drawn looks like a widget that is broken; one that says there is no nearby station is information.
The RemoteViews budget
One more constraint worth knowing, since it shapes what a widget can be.
Widget content is sent to the system as a structure that has a size limit, and exceeding it does not degrade gracefully — you get an exception or a blank widget. Images are the usual cause: a large weather icon, or several of them in an hourly strip, can push a widget over.
This is why widget icons are small, simple, and drawn rather than photographic, and why an hourly forecast strip in a widget has a limit on how many hours it shows. Not a design preference; a budget.
Setting up a widget that helps
One widget, one decision. Widgets are best when they answer a single question at a glance: umbrella or not, jacket or not, run outside or not. A widget showing eleven values answers none of them, because you have to read it.
Choose the location you decide about, not where you are. For most people that is home in the morning and possibly work later. If you make decisions about two places, that is two widgets — which now actually works.
Match density to where you look. A compact widget on a busy home screen you glance at is different from a large one on a secondary screen you visit deliberately.
Check the timestamp before acting on it. Especially first thing in the morning, when a widget may be showing the last update from before the device settled overnight.
Open the app for anything that is not a glance. The widget is for a decision you make in one second. Timing rain, or looking at a forecast in detail, is what the app is for.
What we cannot fix
None of this makes a forecast more accurate. A widget is a display of data from a weather service, and its confidence is that service's confidence. Everything above is about not making it worse — not showing stale data as current, not showing the wrong city, not conflating measurements with different update cycles.
That is a small ambition and it is where the actual complaints were.