FORUMS
Remove All Ads from XDA

[TUT] Create your First Widget Step by Step

1,988 posts
Thanks Meter: 1,067
 
Post Reply Email Thread
Hi guys, as the Title implies this Tutorial is just a Beginner's Guide on Creating Widgets (Widget that displays current time) and how do they work on an Android device.

Pre-requisites :
  • Basic Java Knowledge (Not mandatory, as Google is there for you)
  • Already have created basic HelloWorld apps specified here and here.

So, let's start with the Project shall we ...


Starting Development :


Quote:

Step 1: Open up your Eclipse, click File > New > Other > Android Project
The project name could be given as "HelloWidget", and then select any Build Target Platform of your choice (Android 2.1/2.2/2.3/4.0 etc.), and then specify a package name.
And then, uncheck the probably already checked Box “Create Activity”. We won’t create an Activity here we just want a simple widget. Just like the below picture :


Quote:

Step 2 : So now as you have created your Project, lets start with the Layout and design of our widget. Open up main.xml (Path:- HelloWidget > res > layout > main.xml) and modify it like as shown in the below picture :



We have a simple linear layout with a TextView for your message to display. At this point, you will get an Error saying ERROR Error: No resource found that matches the given name (at 'background' with value '@drawable/widget_bg_normal') That’s because you don’t have the widget_bg_normal resource at this point. You could download the picture I used, and you can put that picture or find your own .9.png image. Put that image (Path:- HelloWidget > res > drawable > widget_bg_normal.9.png). If you don't find a folder named drawable, just create one in that path

You'll also encounter another error suggesting that @string/widget_text can't be found. To correct that open up strings.xml (Path:- HelloWidget > res > values > strings.xml) and modify it as shown in the below picture :


Quote:

Step 3 [Slightly big Step, don't get bored] : So, we just have finished our design part. Now we have to tell Android that we are going to have a widget. Open up AndroidManifest.xml (Path:- HelloWidget > AndroidManifest.xml) and modify it as shown in the below picture :



NOTE: minSdkVersion="15" denotes that minimum Android version required is Android 4.0.3 (API Level 15) and if you are building on Android 2.2/2.3 just leave it as default and don't edit it to 15. [In other words, it will be set default according to whatever platform versions you have downloaded]

Explanations : We declare our Broadcast Receiver which will be “HelloWidget”. Don’t forget the dot before HelloWidget, this will create the full qualified path name with the declared package at the top of the file. The Label of our application was already set by the project wizard and is located in our strings.xml.

From the Documentation, The <intent-filter> element must include an <action> element with the android:name attribute. This attribute specifies that the AppWidgetProvider accepts the ACTION_APPWIDGET_UPDATE broadcast. This is the only broadcast that you must explicitly declare. The AppWidgetManager automatically sends all other App Widget broadcasts to the AppWidgetProvider as necessary.

The meta-data tag tells android about your widget provider. In this case, the widget provider is located at HelloWidget > res > xml > hello_widget_provider.xml Create folder xml under res. Create a new XML file inside that xml folder and name it as "hello_widget_provider.xml". Create like shown in the below picture :



Now, after all these, the only thing that is missing to run our widget is the Class that extends the AppWidgetProvider which we declared in AndroidManifest.xml at the receiver-tag.

Right-Click your Project (HelloWidget) > New > Class
And create the class as shown in the below picture :



So, your new Class will look like this :


Quote:

Step 4 : So, we have created a blank widget that actually does nothing. We'll just see for ourselves how does it looks like. Run your Application (HelloWidget > Run As > 1 Android Application) and your AVD is powered up. And voila, you should see the output as something like this as shown in the below picture :



And yes, it seems its not that crazy as we thought . Just one widget alignment mistake which could be corrected by modifying the design layout in xml, I believe.
Anyways, lets just quickly head over to the next step which would actually define the widget (The Java way)


Quote:

Step 5 : Now, open up the HelloWidget.java (Path:- HelloWidget > src > com.coolsandie.android.widget > HelloWidget.java) file, and modify it as shown in the below picture (In order to display the Time inside the Widget, apart from displaying a default text)



I'll also give it as CODE, but I recommend not to copy-paste. Type all the codes by yourself in order to learn. Avoid writing the import statements first and directly start with class and methods. Eclipse will give a warning to import, so you can do it from there. And one more, look out for spelling mistakes, as Java is highly case sensitive language such as the letter A and a are different.

Code:
package com.coolsandie.android.widget;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.widget.RemoteViews;

public class HelloWidget extends AppWidgetProvider {
	
	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
		
		Timer timer = new Timer();
		timer.scheduleAtFixedRate(new MyTime(context, appWidgetManager), 1, 1000);
	}
	
	private class MyTime extends TimerTask {
		RemoteViews remoteViews;
		AppWidgetManager appWidgetManager;
		ComponentName thisWidget;
		DateFormat format = SimpleDateFormat.getTimeInstance(SimpleDateFormat.MEDIUM, Locale.getDefault());
		
	public MyTime(Context context, AppWidgetManager appWidgetManager) {
		this.appWidgetManager = appWidgetManager;
		remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
		thisWidget = new ComponentName(context, HelloWidget.class);
	}
	
	@Override
	public void run() {
		remoteViews.setTextViewText(R.id.widget_textview, "TIME = " +format.format(new Date()));
		appWidgetManager.updateAppWidget(thisWidget, remoteViews);
	}
		
	} 
}


Quote:

Step 6 : So guys, we have finished it. The completely working widget should be ready by now. Run your Application (HelloWidget > Run As > 1 Android Application) and your application is synced, and it will show the output just like as shown in the below picture :

Finally, we have made it. It only took 6 steps for a completely working Widget.
And I hope you enjoyed this Tutorial. Its made as simple as possible, so surely anyone could give it a try.

NB: If anyone faces issues, as a last resort you can check out the Eclipse project which I've used for this Tutorial. Try importing the Project in Eclipse. Only use it, if you are really annoyed of errors. Anyways I'd recommend Trial and Error method and fixing it by your own before using mine. Download Project Source codes
The Following 56 Users Say Thank You to coolsandie For This Useful Post: [ View ] Gift coolsandie Ad-Free
 
 
26th June 2012, 09:36 AM |#2  
coolsandie's Avatar
OP Senior Member
Flag Kochi, Kerala
Thanks Meter: 1,067
 
More
Info 2 FOOT-NOTE
The method onUpdate will be called at first. We create a timer that will run our MyTime-Thread every second. The constructor of the MyTime-Class gets some information to update our widget on the desktop/home screen. Get our main view that we created (at that point you could also change your layout to another design).

remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);

In the run method, we set the time with our new Date and update the remote View. That’s already it. Now you have a widget that is displaying the current time.
The Following 6 Users Say Thank You to coolsandie For This Useful Post: [ View ] Gift coolsandie Ad-Free
2nd July 2012, 12:36 AM |#4  
s-X-s's Avatar
Senior Member
Flag Dublin
Thanks Meter: 193
 
More
great tut buddy... so u r from cochin... me trichur ( but in dublin)
2nd July 2012, 11:08 AM |#5  
coolsandie's Avatar
OP Senior Member
Flag Kochi, Kerala
Thanks Meter: 1,067
 
More
Quote:
Originally Posted by s-X-s

great tut buddy... so u r from cochin... me trichur ( but in dublin)

Thanks mate, and yes I'm from Cochin
The Following User Says Thank You to coolsandie For This Useful Post: [ View ] Gift coolsandie Ad-Free
2nd July 2012, 08:24 PM |#6  
shahrukhraza's Avatar
Senior Member
Thanks Meter: 379
 
More
Thumbs up
thank you so much for these amazing and super easy tutorials!! please make a few more!!
2nd July 2012, 08:48 PM |#7  
coolsandie's Avatar
OP Senior Member
Flag Kochi, Kerala
Thanks Meter: 1,067
 
More
Quote:
Originally Posted by shahrukhraza

thank you so much for these amazing and super easy tutorials!! please make a few more!!

Welcome mate, yeah sure will make more Tutorials
27th November 2012, 09:27 AM |#8  
Member
Thanks Meter: 12
 
More
Hey, I am trying to follow your tutorial. But I don't understand why the error "ERROR Error: No resource found that matches the given name (at 'background' with value '@drawable/widget_bg_normal')" won't disappear. It's just like Eclipse doesn't want to accept that i have put a new folder including the picture inside the res folder. I can see both the drawble folder and the widget_bg_normal.9.png in the project explorer, but Eclipse keeps saying that no resource is found.





Edit: Hm, putting the image file inside of one of the res/drawble-Xdpi folders works. But still I don't understand why creating a new drawble folder doesn't.
27th November 2012, 11:38 AM |#9  
coolsandie's Avatar
OP Senior Member
Flag Kochi, Kerala
Thanks Meter: 1,067
 
More
Quote:
Originally Posted by elyts

Hey, I am trying to follow your tutorial. But I don't understand why the error "ERROR Error: No resource found that matches the given name (at 'background' with value '@drawable/widget_bg_normal')" won't disappear. It's just like Eclipse doesn't want to accept that i have put a new folder including the picture inside the res folder. I can see both the drawble folder and the widget_bg_normal.9.png in the project explorer, but Eclipse keeps saying that no resource is found.





Edit: Hm, putting the image file inside of one of the res/drawble-Xdpi folders works. But still I don't understand why creating a new drawble folder doesn't.

Hi, from the screenshot I see that your widget_bg_normal.9.png image is put inside the drawable folder which is inside the layout folder. That is plain false. The drawable folder should be out side the layout folder, and inside the res folder. The folder tree looks like this :

res
- drawable-hdpi
- drawable-ldpi
- drawable-mdpi
- drawable-xhdpi
- drawable

layout
- main.xml
The Following 2 Users Say Thank You to coolsandie For This Useful Post: [ View ] Gift coolsandie Ad-Free
27th November 2012, 12:02 PM |#10  
Junior Member
Thanks Meter: 3
 
More
great tutorial...thanks
27th November 2012, 02:10 PM |#11  
Member
Thanks Meter: 12
 
More
Quote:
Originally Posted by coolsandie

Hi, from the screenshot I see that your widget_bg_normal.9.png image is put inside the drawable folder which is inside the layout folder. That is plain false. The drawable folder should be out side the layout folder, and inside the res folder. The folder tree looks like this :

res
- drawable-hdpi
- drawable-ldpi
- drawable-mdpi
- drawable-xhdpi
- drawable

layout
- main.xml

Ok, thanks. I was pretty confused - you should change the path in your tutorial then.(Path:- HelloWidget > res > layout > drawable > widget_bg_normal.9.png)
The Following User Says Thank You to elyts For This Useful Post: [ View ] Gift elyts Ad-Free
Post Reply Subscribe to Thread

Tags
android, app, application, development, widget
Previous Thread Next Thread
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes