You are on page 1of 12

how to write app Widgets - Home screen widgets ?

How to implement different


sized home screen widgets?
Recently i gave a presentation in google office singapore for gtug-ph-sg android community
about Layouts and Home screen widgets.
http://gtug-ph-sg.blogspot.com/2011/11/android-talk-update.html
So i wished to share more details about how to write home screen widgets.
Also when i attended a google dev talk here happened on nov27th, the key steps to keep a
user engaged in keeping your application is
1 - Write home screen widget and keep the user bsy in refreshing the data on widget
2 - Push notifications then and there so that user has not forgotten your application.
So we home screen widget is one way you can keep user bsy with your application. Lets go
into the details.
* What is an AppWidget ?
* AppWidget framework
* Steps for creating an AppWidget
* Example demonstrating widget showing google static map of location as home screen
widget.
AppWidget:
- AppWidget is a android techinical terminology for "Home screen widgets". What is said
in developers guide is "App Widgets are miniature application views that can be embedded
in other applications (such as the Home screen) and receive periodic updates."
-AppWidget is a representation of an Android application on the home screen. The
application can decide, what representative information it publishes on the home screen

- Home screen widgets are quick glimpse of the fully functional apps like
calendar,music,weather applicaiton. Users can quickly get live data from an application.Live
data i mean, widgets can keep refreshing the data based on location,time basis, or per
schedule input from user.
- Widgets let users interact with the widgets like slide the images like in gallery, scroll the
weather data, play,pause songs..etc.

RemoteViews and Launcher:


Before diving into how to implement app widgets, we should be aware of how
the appWidgets mechanism works and what are remoteviews ?
How does Launcher (i.e Home screen provider) able to show a view created by another
application in its UI ? Functionality and design of the widget is defined by one application

but UI of the widget is hosted in another application (Launcher). What would help us
achieving this ? Basically we need an IPC mechanism here. Inter process
communication. One process sending the UI data to another process Launcher to display in
it.
Remoteviews helps in solving this and is the key behind appwidget framework.
Remoteviews are parcelable data strucutre that holds information about a view hierarchy
and can be transferred from one process to another. Any process can recieve this
RemoteView instance via IPC and get a "View" instance from it and add to its Layout and be
part of receving process. The creator of remoteview can define actions for the elements in
remoteview like what should happen when a button is pressed. Receiving process cannot
change these properties, they can only get a view instance and host it.
So who sends remoteviews and how does Launcher communicates with creator.
- AppWidgets framework includes implementing AppWidgetProvider class which is a
broadcast receiver which would receive events of when an AppWidget is added to
homescreen or deleted from homescreen.
- Launcher is the guy who sends these broadcasts when the appWidgets are added to the
home screen with an AppWidgetID
- AppWidgetProvider then sends an RemoteView with the AppWidgetId, which would be
then be received by Launcher and Launcher updates the corresponding appWidget with
that remoteView.

AppWidget FrameWork
Now lets see the four necessary things involved in creating appWidgets.
* App Widget Provider Metadata XML file
* AppWidgetProvider class
* View layout
* App Widget configuration Activity (Optional)
App Widget Provider Metadata XML file
* Describes the metadata for an App Widget, such as minimum width, minimum height,
update frequency, the AppWidgetProvider class.
* It also references App widget's layout file
* This should be defined in res/xml folder.
AppWidgetProvider class
* Defines the basic methods that allow you to programmatically interface with the App
Widget, based on broadcast events. (AppWidgetProvider class is a child class of
BroadcastReceiver class.)
* Through it, you will receive broadcasts when the ApWidget is updated, enabled, disabled
and deleted
View layout
* Intial layout to be displayed when the appWidget is added to the homescreen. It is defined
in metadata XML file.
App Widget configuration Activity
* This is an optional activity which users can define to show to the users before adding the
appWidget to homescreen.Usually useful in collecting some values required for your
appWidget settings.
Building an AppWidget
* Declare an AppWidgetProvider in the Manifestfile
* Create the App Widget Provider Info Metadata XML file
* Create the App Widget Layout XML file

* Write the AppWidgetProvider Class


1 - Declare AppWidgetProvider in Manifest
view plainprint?

1.

<receiver android:name="ExampleAppWidgetProvider">

2.

<intent-filter>

3.

<action android:name="android.appwidget.action.APPWIDGET_UPDATE">

4.

</action></intent-filter>

5.
<meta-data android:name="android.appwidget.provider" <b
rbr="">android:resource="@xml/example_appwidget_info"/>
6.

</meta-data></receiver>

2 - Create App Widget Provider Info Metadata XML file


view plainprint?

1.

<appwidget-provider>

2.

xmlns:android="http://schemas.android.com/apk/res/android"

3.

android:minWidth="294dp"

4.

android:minHeight="72dp"

5.

android:updatePeriodMillis="86400000" --> Every one day

6.

android:initialLayout="@layout/example_appwidget"

7.

android:configure="com.example.android.ExampleAppWidgetConfigure" >

8.

</appwidget-provider>

Some of the attributes are added newly in android 3.0


previewImage --> Added in android 3.0
android:previewImage="@drawable/preview"
More details take look
athttp://developer.android.com/reference/android/appwidget/AppWidgetProviderInfo.html
3 - Create App Widget Layout
* App Widget layouts are based on RemoteViews,which do not support every kind of layout
or view widget.
* A RemoteViews object (and, consequently, an App Widget) can support the following

layouts and Widget classes


FrameLayout, LinearLayout, RelativeLayoyt
AnalogClock, Button, Chronometer, ImageButton,
ImageView, ProgressBar, TextView
* Android 3.0 supports additional widgets
ListView
GridView
StackView
AdapterViewFlipper
4 - Write AppWidgetProvider Class
* The AppWidgetProvider class extends BroadcastReceiver to handle the App Widget
broadcasts. The AppWidgetProvider receives only the event broadcasts that are relevant to
this App Widget, such as when the App Widget is updated, deleted, enabled, and disabled.
Methods to override
onUpdate(Context, AppWidgetManager, int[]) - called
when each App Widget is added to a host (unless you use a configuration Activity), Typically
the onlymethod that needs to be present
onDeleted(Context, int[])
onEnabled(Context)
onDisabled(Context)
onReceive(Context, Intent)
Screenshot showing demo of adding Digital and analog clock in Home screen:

AppWidget provider - onUpdate

There are certain few points about AppWidget Provider behaviour we need to know.
* First is , android:updatePeriodMillis="86400000" which defines the frequency when the
appWidget will be updates. Meaning on this schedule, onUpdate on AppWidget Provider
class will be called. The restriction with this timing is the minimum period is 30mins. You
cannot give 10000 and except the onUpdate() to be called every 10 secs. Minimum time
period is 30 mins.
* Because AppWidgetProvider is an extension of BroadcastReceiver, your process is not
guaranteed to keep running after the callback methods returns i.e onUpdate,onEnabled.
So in case, you need to perform some network communication to fetch some data
* Consider starting a Service in the onUpdate() method. And delegate the network
communication work to a asynchronous task and update the widget with the result.
* To update an appWidget all you need to know is AppWidgetId and
have AppWidgetManager instance. So ideally pass all the appWidgetIds to "service" i.e
whenever onUpdate() is triggered call startService() with appWidgetIds as intent data and
ask the service to update the widgets with data fetched from network.
appWidgetManager.updateAppWidget(appWidgetId, views);
Now how to do we change the updatePeriodMillis to trigger onUpdate before 30mins.
* Use AlarmManager to update.In onUpdate() when the first time appWidget is added, set
a setRepeating alarm for the schedule you wish and pass an pendingIndent to launch the
service. In service you can update the appWidgets with appWidgetids and remoteview.
view plainprint?

1.
;

final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE)

2.

final Intent intent = new Intent(context, MyService.class);

3.

if (service == null)

4.

5.
;

service = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)

6.

7.

m.setRepeating(AlarmManager.RTC, System.currentTimeMillis(), 1000 * 60, service);

More details take a look at this post


http://www.parallelrealities.co.uk/2011/09/using-alarmmanager-for-updating-android.html

Multiple sized widgets :


- How do we support multiple sized widgets ? 4x1,4x2,2x1 there are maximum of 4 rows
and 4 columns. 4x4 in handsets and tablets support upto 8x7.
Here is one of the way you can achieve this.
- Declare as many AppWidgetProviderInfo metafiles required
2x2 :
android:minWidth="147dp"
android:minHeight="142dp"
4x2 :
android:minWidth="294dp"
android:minHeight="142dp"
- Define corresponding Appwidget classes.
- Declare corresponding AppWidget Broadcast receivers in AndroidManifest.xml
For more details on the cells calculation, minWidth,minHeight please chk in this link.
http://developer.android.com/guide/practices/ui_guidelines/widget_design.html
Snapshot showing four types of appWidgets for the demo application

Things to keep in mind

* Frequency of update should not be high. ex. every 5 mins.It will reduce the battery life of
the phone.
* Handled badly your widget could end up making the phone completely
unresponsive. Pushing updates to onscreen widgets is a somewhat costly process.
* Avoid nesting of layouts within a layout.
* Give proper padding. As it might collide with adjacent widget. No boundary seperation
would be seen.
* Use a nine patch image as background to support multiple sized widgets
* Offload any webrequest through a service to avoid ANRs.
Demo example of widget showing google static map of location as home screen widget.
Quick points of implementation.
* onEnabled() -> Start a service
* onUpdate() -> Get the appWidgetId and appWidgetType and pass to the service.
* onDeleted() -> Get the appWidgetId and pass to the service.
* Service -> Listens for movement change using PhoneStateListener and fetches current
location using GPS or Wifi and downloads the static map as Bitmap and updates the
widgets 2x2 and 4x2.
I am not giving in detail explanation of the code. Please go through this block diagram which
will give you high level overview. You can go through the code for more details Any queries
u can drop me a comment..!!
Implementation overview:

http://code.google.com/apis/maps/documentation/staticmaps/
Demo code:
The entire source code for the demo can be downloaded from the below link.
http://www.4shared.com/get/_FeDVgpD/HomescreenWidget.html

You might also like