2010. 2. 2. 09:21

How to make a simple Android widget





Yesterday I made my first Android widget. A very simple widget, just to try it out. It can show the time. No more, no less. I will here show you how to get started on widgets. I’ll start from scratch, so you actually don’t need any knowledge on Android development. Well, of course you need to have the SDK, and Eclipse installed and ready.

I used the 1.5 SDK, but it will probably work on newer SDK’s too.

I will show you how to do it in 6 easy steps.

 

1. Create a new Android project
Fire up Eclipse, and click File -> New -> Android project
Skærmbillede 2009-11-07 kl. 14.26.27
Type in a name for you project, eg. WatchWidget. Select the target, 1.5 in my case. I guess that there could be differences, so if you are not experienced in Android development, I suggest that you use 1.5 too.

Then we need an application name, which is the name that will show up on your phone. And last but not least, a package name.

Uncheck “Create activity”, as we don’t want any activities in this sample.

Click Finish to create the project. Now you have a structure that looks like this:

WatchWidget structure

 

2. Create the Java class
Right-click com.kasperholtze.watchwidget (or whatever you used for package name), and select New -> Class:

Create WatchWidget class

Give the class a name, i.e. WatchWidget. Then we need to extend the AppWidgetProvider, so type in android.appwidget.AppWidgetProvider as superclass, or browse for it.

Click Finish, and Eclipse will generate the following code:

package com.kasperholtze.watchwidget;

import android.appwidget.AppWidgetProvider;

public class WatchWidget extends AppWidgetProvider {

}

 

3. Create the Java code
Now it’s time to create our Java code, for updating the widget. Type in the following code:

package com.kasperholtze.watchwidget;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import com.kasperholtze.watchwidget.R;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.widget.RemoteViews;

public class WatchWidget extends AppWidgetProvider
{
    @Override
    public void onUpdate( Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds )
    {
        RemoteViews remoteViews;
        ComponentName watchWidget;
        DateFormat format = SimpleDateFormat.getTimeInstance( SimpleDateFormat.MEDIUM, Locale.getDefault() );

        remoteViews = new RemoteViews( context.getPackageName(), R.layout.main );
        watchWidget = new ComponentName( context, WatchWidget.class );
        remoteViews.setTextViewText( R.id.widget_textview, "Time = " + format.format( new Date()));
        appWidgetManager.updateAppWidget( watchWidget, remoteViews );
    }
}

The only method we use in this class, is onUpdate( Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds ), which we override from the AppWidgetProvider class.

First we create three objects. remoteViews, watchWidget and format. remoteViews is a reference to the main view, which we will create in a moment. watchWidget is a reference to our class, and format is the date format used to show the time.

Then we initialize the remoteViews and watchWidget. You will get an error one the line remoteViews.setTextViewText(), which is where we actually update the text on our widget, stating that R.id is not found, but that’s all right for now. We will create that one in a moment too.

appWidgetManager.updateAppWidget sets the RemoteViews that should be used for our widget.

 

4. Edit the view for our widget, main.xml
Using the UI designer takes some trying, testing and failing. If you have not tried this yet, you should try playing around with it. It takes some time to get the feeling of it.

My main.xml looks like this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/LinearLayout01"
    android:layout_height="200dp"
    android:background="@drawable/background"
    android:layout_width="160dp"
    android:orientation="horizontal">
    <TextView
        android:id="@+id/widget_textview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center_vertical|center_horizontal"
        android:textColor="@android:color/black"
        android:text="17:12:34 PM"
        android:textSize="8pt"
    />
</LinearLayout>

It contains a LinearLayout with a TextView inside. The important thing is the id of out TextView, which we used earlier in the WatchWidget class.
I used a standard widget background, which you can download at http://developer.android.com/guide/practices/ui_guidelines/widget_design.html. You can also grab it here:

WatchWidget background

Save it in the project, at res/drawable/background.png

 

5. Edit AndroidManifest.xml
The next thing is to edit the AndroidManifest.xml, which defines the application. We need to add an intent-filter, meta-data that defines which xml file we use for defining the widget provider, and name and other details of the application.

Here it goes…

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.kasperholtze.watchwidget"
    android:versionCode="1"
    android:versionName="1.0">

    <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">

        <receiver android:name=".WatchWidget" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/watch_widget_provider" />
        </receiver>

    </application>
   
    <uses-sdk android:minSdkVersion="3" />

</manifest>

 

6. Create widget provider
The last thing we have to do, before the application is ready to run, is to create a XML file, defining the widget provider. Create a new folder under res, called xml, and save the file as res/xml/watch_widget_provider.xml.

<?xml version="1.0" encoding="utf-8" ?>
<appwidget-provider
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="146dp"
    android:initialLayout="@layout/main"
    android:updatePeriodMillis="1000"
    android:minHeight="144dp"/>

Here we set the minimum size that the widget needs to be added to a home screen. And then we set the updatePeriodMillis. updatePeriodMillis defines how often we wish to call the onUpdate method that we created earlier in the Java class.

That’s it! Connect your phone, or fire up a virtual device, and try it out