Advertisement

Tutorial – Creating a Custom Analog Clock Widget

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.

AnalogClockSo, 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
    • Info.java
    • Widget.java
  • Resource Files
    • res/xml/widget.xml
    • res/layout/info.xml
    • res/layout/widget.xml
    • res/drawable/widgetdial.png
    • res/drawable/widgethour.png
    • res/drawable/widgetminute.png

We will also be working with AndroidManifest.xml within the root directory of our project.

Resource Files

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,

and replace

android.intent.category.LAUNCHER

with

android.intent.category.INFO.

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.

Click here to see what your AndroidManifest.xml file should now look like.

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.

72 Responses to “Tutorial – Creating a Custom Analog Clock Widget”

  • Tommy says:

    I admint I couldnt program my tail out of a cave….
    I travel alot and could use a clock with an alarm set to a specific time zone.
    Any ideas or has anyone seen something like this?

  • Adrian says:

    Thanks for the great tutorial. I started to play around with the code, and after I cleared out the whole widget.java and info.java files (actually I just put /*…*/ on the whole code 🙂 ) The app still installed and ran (on a fresh new emulator phone as well) WTF?! Does the manifest file have anything to do with this? Or are the xml files displayed without any code. And the clock is updated…it keeps time.

  • vl says:

    Analog Clock Collection is a useful collection of clock widgets for Android. The clocks size: 2×2.

    http://bstdownload.com/reviews/analog-clock-collection-2/

  • Faraz Azhar says:

    Great tutorial. Although I’ve been trying to make a simple amendment. Instead of opening the clock application on clicking the widget, I want to open a new activity. Lets say the Info.java which is already there in your project. I would like the Info layout to popup when I click the clock. I tried to code for it, but it doesn’t work. I click on the widget and nothing happens at all ! Please help me correct my code:

    1) all the files are kept the same. I’ve changed the Category (intent-filter) of .Info activity to “android.intent.category.DEFAULT”.
    2) My amended code for onReceive is:

    String action = intent.getAction();
    if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action))
    {
    Intent myIntent = new Intent(context, Info.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, myIntent, 0);

    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
    views.setOnClickPendingIntent(R.layout.info, pendingIntent );

    int widgetID = R.id.AnalogClock;
    AppWidgetManager manager = AppWidgetManager.getInstance(context);
    manager.updateAppWidget(widgetID, views);
    }

  • ichiboo says:

    Thanks for the tutorial. i downloaded your full eclipse project and tried running on both emulator and android phone.Though there weren’t any errors on the codes, the clock’s not showing up on the home screen of both devices, and i don’t understand your reply….. >.> quote:” @jason How are you running it? There shouldn’t be anything to run, just add it to the home screen as a widget.”
    what do u mean by “Adding it ti the home screen as a widget?”

  • Jayanth says:

    Hi, Thanx for the wonderful tutorial.
    The widget works fine in terms of updating the time but doesn’t respond on clicking the clock (using Froyo). Also need some suggestion to debug the code. Since the activity present in the code has nothing to do with widget, there is no use placing a breakpoint. Is there any way I can start debugging the code?

    Thanx in advance.

  • vishal says:

    can anybody will tell me code for widgets for battrey backup in android 2.2 ……..?

  • thom says:

    Great Tut!
    Thx as much for this description!

  • Peter says:

    I download your Eclipse Project, compile and install widget in my htc desire, but, not work click on the clock.
    the code is ok, but not work.
    can you help me?
    thanks!

  • Martin says:

    Thanks for the tutorial. I’m not a coder, I’m a graphic designer. I have made few nice design for analog clock but i can’t compile it to a working widget. May you tell me how to compile the project when all the png’s are all modified. .apk = .zip file?

  • Deepika says:

    Hi,
    I deployed the application and its running too. But when I long press on the home screen, it is not giving me the “Add to home screen”. Instead it is just giving me option to add a wallpaper. How do i change it? 🙁

    FYI :
    Android : 4.0

  • Rahul says:

    Thanks, it help me out for understanding the basic concept

  • square says:

    tried to run project and recieve several of these errors

    Problems while saving variables and constainer: “org.eclips.core.resources”
    Problems while invoking code from plugin-in:”org.eclips.core.resources”
    JavaBuilder handling ImageBuilderInternalExcepton while buildingAnalogClockWidget

  • Sebastian says:

    Wonderful, BUT what make the clock run? Who moves the hands? Pretty less code.

  • Deni says:

    Hello.I use youre code but i get error in Go launcher,Apex launcher…Problem loading widget.Please help me.

  • Uptown says:

    Well … im assuming this tutorial is outdated. the first xml file i created gave an error saying that app widget provider is no longer a class (im assuming its depreciated). also on the first xml file, i got an error saying that the layout height hadnt been defined (even tho there was an attribute dealing with height). i read the tutorial twice before i actually tried to do it, so i can say it was definitely very helpful and informative. i hope a new updated tutorial can be made or if someone can point me to one.

  • admin says:

    I just downloaded the zipped project from the bottom of the post, imported into Eclipse, and built it without any issues. Did you try the project, or did you copy from the individual files?

  • Denitsa says:

    Hello.Can you help me please.Im trying to make clock in more sizes for different screen size(2×2,4×4).How can i do this?

  • How to add seconds needle?