Hi all… Note, I am going to assume that there are at least a few people who have wandered off, gotten lost, and somehow ended up here. Hopefully, a few of you meant to be here too…
Yesterday, I was perusing the forums over at www.androidandme.com (as I often do) and one of the members had posted a question related to development. Of course, I hunt these down and pounce whenever I see them. So, on to the question, which I am going to strip down to the scope of this post… How does one write a custom Analog Clock Home Screen Widget for Android.
So, as I am sure you have already guessed, I have decided to write a tutorial (with code) to explain in detail how to do just that.
Before we continue, I should point out that as I am writing this I am going to assume that you have obtained, installed, and know how to use the software tools for Android Development. For the purpose of this tutorial, these tools are: JDK 1.5 or higher, Android 1.5 SDK, Eclipse 3.4 or higher, and the Android Development Tools Plugin for Eclipse.
Now that that is all out of the way, let’s move on to the tutorial…
First off, we are going to create a new Android Project in Eclipse. For my own code for the tutorial (which can be downloaded here), I will call the Project AnalogClockWidget, I will choose Android 1.5 as the build target (required for Widgets), I will set the Application Name to Analog Clock Widget, the package name to nEx.Software.Tutorials.Widgets.AnalogClock, and create an Activity called Info (this will be explained later).
During the course of this tutorial we will be creating several files that implement various aspects of the widget. These files we will be creating are:
- Java Source Files
- Resource Files
We will also be working with AndroidManifest.xml within the root directory of our project.
The most logical place to start in creating a widget such as this is creating the layout files and the xml file declaring the app-widgetprovider (in our case, res/xml/widget.xml).
res/xml/widget.xml: This file contains the definition of our Analog Clock widget. It is an xml file with only one element: appwidget-provider, which has the following attributes: xmlns:android (standard in Android resource files, defines the android namespace), android:minWidth (defines the minimum width of our Widget, translates to number of cells in the horizontal space), android:minHeight (defines the minimum height of our Widget, translates to number of cells in the vertical space), android:updatePeriodMillis (defines the update frequency, a value of 0 means no updates), android:initialLayout (a pointer to the layout file to display during loading of the widget).
the graphics I am using for this custom version of the Analog Clock will be a nEx.software themed version of the original Analog Clock. As such, I am going to use the same size parameters as the original. That that is, my Clock Dial will be 146ppx by 146 px. Ecah hand will be 14px by 146px. This size will fit nicely into a 2 cell by 2 cell space on the home screen (in both landscape and portrait modes), just like the original clock. Note that we refer to res/layout/widget.xml here as our android:initialLayout.
Click the link at the beginning of this section to see what our widget definition should look like.
res/layout/info.xml: This file simply provides the layout for an information screen to tell the user about your widget, and provide instructions on how to use it. In our case, we have a very simple widget which requires no configuration, and no special instructions so it will be a very simple layout containing only a LinearLayout and TextView. More complex widgets will usually require more complex information screens.
Click the link at the beginning of this section to see what our info screen should look like.
res/layout/widget.xml: This file provides the layout which we will use for our widget. Again, because this is a simple widget this will be a simple file. In fact, the only elements we will include here are RelativeLayout and AnalogClock. This could also be done without the RelativeLayout, but I usually prefer to have a container in my layout.
Click the link at the beginning of this section to see what our widget should look like.
The remainder of the Resource files listed above are just the graphics we will use for the clock, and need not be specifically mentioned here.
Java Source Files
Info.java: This class extends Activity, and only serves to provide an informational screen to the user. Technically, this is not required for a Widget project, but I recommend it for the following reason:
If you plan to release to the Android Market, it will mitigate those useless and uninformed comments such as “It doesn’t launch.” or “Please remove from the app drawer.” and help you to achieve and retain a better ranking in the Android Market. So, I know you are thinking now “Spill the beans already!” so here it goes… Provide an Info activity which opens from the Android Market when the user presses the Open button, but does not add itself to the app drawer (Launcher). Sounds simple enough, so how do we do it? All you need to do is open the AndroidManifest.xml file,
It’s amazing how a simple change like this can easily amount to a full star or more in your Android Market rankings.
While we are in the AndroidManifest.xml file, we might as well make our other required changes too. Because this is a widget project, we must define our widget in the manifest. To do this, you must define a receiver tag with an intent-filter for
android.appwidget.action.APPWIDGET_UPDATE and including a meta-data tag which defines the resource file for the widget.
Widget.java: This is where the magic happens, and is where we will spend the rest of this tutorial. In order to create and use a widget we must extend AppWidgetProvider. Remember, we already added the reference to this class in the AndroidManifest.xml file.
Because this is a very simple widget that relies on nothing but itself (no calls to the web, no background updates, etc…) our Widget class will be very simple. We will only handle the onReceive event that gets called by the AppWidget framework whenever a Widget is Added, Deleted, Updated, etc…
In this onReceive method we will only look watch for the “update” event, so that we can reapply our Widget when appropriate. For some reason, I decided on a blog format that doesn’t not work exceptionally well for including code within a post (layout is not really wide enough). Until I find a better layout for this sort of thing, please click here to view the code sample for our onReceive method.
At this point, we actually have a working Analog Clock Widget, and could compile and use it as is. But that wouldn’t be any fun. What we also want to do is handle when the user clicks on the Clock, and take the user to the Alarm Clock application. to do that, we must create a PendingIntent, and assign it to the click event for the widget. Do do that we will add to the onReceive method three lines. Please click here for the updated code.
At this point, all that is left is to replace the widgetdial.png, widgethour.png, and widgetminute.png in the res/drawable/folder with your own graphics, compile, and install.
You can download my Eclipse project for this widget here.
Regrettably, I somewhat rushed this tutorial, since I had promised to get it out as soon as possible, and I am aware that there are things that could be done better (formatting, maybe more verbose, maybe simpler terminology, possibly different writing style). I intend to update this tutorial in the coming days to be fix some of these issues. Please let me know what I can do better, and offer any suggestions for improvements for this and future tutorials.