How To Make an Android Home Screen Widget Update Only When Visible
Depending on the nature of your home screen widget, you may want it to stay closely synched to real-time data. It would be nice if Android fired a system event that you could register for whenever your widget is visible on the screen. However, Android does not do this, and could not be counted upon to do so in any case because some users may be using a 3rd party alternative to the default home screen.
You’d like to update your widget early and often, at times when the user might be looking at it. But you want to prevent it from updating (and wasting resources) when the user is not engaged. There is a way to achieve this. This technique isn’t perfect, because it will cause your widget to update even when hidden behind another running app, but that much is unavoidable. (Note to Google: an isWidgetVisible() method would be great!)
I’m going to describe how I used a Service to update my web community widget only when the screen is on. The java classes involved are:
- MRPWidget (extends AppWidgetProvider)
- WidgetUpdate (extends IntentService)
- MRPAlarmReceiver (extends BroadcastReceiver)
I described the MRPWidget class here: creating an Android home screen widget. Now I will describe how the Service is used to update the widget.
Android Home Screen Widget: Creating the AppWidgetProvider
Extending AppWidgetProvider is a simple way to encapsulate your app’s management of your home screen widget. It provides several widget life cycle methods you can override to handle such events as a user adding or removing the widget from their home screen. It also provides an onUpdate method that ties into the periodic updates the Android system will trigger for your widget. For my purposes, I disabled this periodic updating because I wanted to control it myself via a Service.
Your AppWidgetProvider interacts with the widget via the RemoteViews class. The widget is itself hosted in a separate process from the one in which your app runs, and RemoteViews provides methods to cross that gap, update the views and add click listeners. Note that RemoteViews methods provide only a limited subset of view functionality, and this may restrict what you’d like to do with your widget. For example, animations are not supported.
I’m going to describe how I created my web community widget. The java classes involved are:
- MRPWidget (extends AppWidgetProvider)
- WidgetUpdate (extends IntentService)
- MRPAlarmReceiver (extends BroadcastReceiver)
My widget class is named MRPWidget, and it extends AppWidgetProvider. All visual updates to the widget are handled by this class, as well as starting the service that will perform the updates. For example, when the widget is enabled it should start the service: Read more
Creating an Android Home Screen Widget
The home screen of a smartphone is precious real estate. As users interact with their phone throughout the day, the icons and widgets on the home screen are constantly seen and ready to be interacted with at a moment’s notice. Offering a widget for your app, service or web site is therefore a uniquely compelling way to to boost its visibility and “stickiness.”
One site that I’ve built is a small online community where people interact mainly via message boards and private messages. I had already built a simple Android app that users could install to notify them whenever there is a new reply or message. But to take this app to the next level, I needed to add a home screen widget.
This widget would stay updated with the most recent post made on the site as well as show the names of the users currently active. In this way, the widget would effectively be a small window into what was going on at the site at any given moment. Clicking the widget should take you directly to that latest post, logging you in automatically. Finally, the widget should also visually alert you to any pending unread messages. It should do all this while taking up as small a footprint as possible, as smartphone users are reluctant to give up too much of their screen to a single widget.
So there are a number of challenges, each of which must be resolved. Which specific data must be displayed on the widget (we want as much as possible without forcing a larger footprint)? How to retrieve that data from the web site? How to keep the data fresh while minimizing battery and data usage? How to take the user to the correct page when the widget is clicked? How to make the widget visually appealing? This last one is difficult, speaking as someone who is not a graphic designer, but I gave it a solid try. 🙂
So in the next few posts I’ll go into how I created an Android widget. But first please have a look at it:
The footprint is 2×1 cells on the home screen. The top half displays the latest post on the site, alongside the user’s icon, with the user’s name (“Example User”) followed by the message board it was posted to. The bottom half lists the names of currently-active users. Had there been more than can fit on one line, the text here would scroll as a marquee. Not shown is a hidden middle section that expands to notify of unread post replies and private messages. All of this is displayed atop a semi-transparent 9-patch image that stretches to encompass the content.
More details on crafting this widget to follow.