Saturday, September 5, 2009

Simple home screen widget

Overview

One of the great improvements in Android 1.5 is the capability of adding custom home screen widgets to you desktop. Prior to 1.5, only the standard widgets that came with the OS were available. Android 1.5 provides a simple way to create your own home screen widgets that allow functionality of your application to bleed out into other areas of the system and provide a more integrated user experience. In this tutorial however, we are going to just get something on the home screen. Once you have that, you can go ahead and add some more functionality which will be discussed in later posts. This is intended to just get you started.

Limitations

Before we begin with this brief tutorial however, you should be aware that there are some limitations to the home screen widgets. The limitation that disappointed me the most was the slim list of allowable UI widgets to choose from in building the widgets. I had hoped to build a custom search widget that would provide quick access to some information in my application, but alas, and EditText widget is not available in custom home screen widgets. With this limitation in mind, here is a complete list of compatible UI widgets that you can use:
Also note that descendants of these classes are also not allowed.

Getting Started

There are really only a few things you have to have in order to get a widget up on the home screen.
Now keep in mind that these are the bare bones minimum  requirements just to get something on the home screen. More options and functionality will be explored later.

AppWidgetProvider
First create a class that extends AppWidgetProvider. If you are using eclipse, once you have created the class you can right click in the window and select "Override/Implement methods". Go ahead and select all of the methods from AppWidgetProvider and click OK. You should have all the method stubs that you need to add any functionality you want to your widget. The main method in this class is onUpdate(). This method gets called whenever your application issues an update to the widget based on a timing definition set in you AppWidgetProviderInfo class. For now, just leave this class as it is since we won't be defining any real functionality for the widget just yet.

AppWidgetProviderInfo
This class is to be purely defined in xml. Example code is as follows:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="318px"
    android:minHeight="72px"
    android:updatePeriodMillis="86400000"
    android:initialLayout="@layout/searchwidget_layout"
    >
</appwidget-provider>

As you can see the provider info class sets up the container size and also defines the update interval for the widget. the value displayed is the millis for a whole day. Put this file into your res/xml folder.

XML Layout
This file simply defines the UI elements you are going to use and their organization. If you are not familiar with setting up layouts in XML, I would suggest you see the android developers site and learn how. The following example code uses are relative layout with 2 child, a text view and a button. Yes, unimaginative I know.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_height="wrap_content"
 android:layout_width="fill_parent"
 android:background="@drawable/widget_frame"
 android:focusable="true"
 android:textColor="#000">
 <TextView 
  android:layout_width="wrap_content"
  android:layout_height="fill_parent"
  android:layout_alignParentLeft="true"
  android:text="Click the button"
  android:layout_centerVertical="true"
  android:gravity="center"
  android:layout_marginLeft="20px"
  />
 
 <Button
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_alignParentRight="true"
  android:text="Click Me!"
  android:layout_centerVertical="true"
  android:layout_marginRight="20px"/>

</RelativeLayout>

Manifest Entry
In order for the home screen, which is the WidgetHost, to see your application's widget, you must define it in your Android Manifest file. Place the following node inside your Application tag.
<application
     ......
      .......>
<receiver android:name=".MyWidgetProviderClass" label="Name of my widget">
 <intent-filter>
  <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
 </intent-filter>
 <meta-data android:name="android.appwidget.provider"
      android:resource="@xml/widget_provider_info_file" />
</receiver>
 .....
 .....
 </application>

Wrap up
That's it. Run your application and long press on the home screen. Click on widgets and you should see your application's widget in the list. Click on it and admire it sitting there on your home screen doing . . . nothing. Yes the widget is worthless, and next time we'll actually give it some functionality, but for now, you should have a foundational knowledge of how to actually get your widget on the screen.

3 comments:

  1. Thanks for the nice post. I was really surprised to learn that EditText isn't one of the supported views. So how did Google do the search widget? There has to be a way to capture keyboard input. Maybe the problem is how the on-screen keyboard interacts with the widget UI? I look forward to part 2.

    ReplyDelete
  2. i require an edittext control to be placed inside a widget.. any updates now?... i tried making the textview as editable but that too did not work...

    ReplyDelete
  3. I haven't actually tried the search widget (I'm on an HTC Sense phone and haven't ever used it on the Android emulator either), however...

    I believe the way Google do it is to simply have a drawable on the widget, and then when the user clicks it, they overlay a transparent Activity on top of it, which contains the actual EditText.

    AppWidgets are a world of hacks.

    ReplyDelete