Category Archives: Widgets

Creating a Clock Widget in Android with Custom Font.

Hi all

if you have been a regular visitor of this website you have seen that I have shown you how to create a simple widget, adding controls to it, adding event handlers in the views etc…
Do check this website for more tutorials on widgets.

You can find other tutorials by following this LINK.

This tutorial is also an important one on widgets.
People always find it difficult to customize their widgets with Custom Fonts. AS of now you cannot directly set the font in a TextView in a Widget. For that you have to go indirectly.

In this example I will show you how to create a Clock widget with Custom Font.

Custom Font in Android Widget

Custom Font in Android Widget

So we will start.

At first we will create the XML files.

acitvity_main.xml – This is our main layout which contains a button that creates the widget.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:background="@android:color/white" >

    <Button
        android:id="@+id/create_widget"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="Create Widget" />

</RelativeLayout>

Now the layout for the Widget and the WidgetProvider.

my_widget_provider.xml

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="250dip"
    android:minHeight="70dip"
    android:updatePeriodMillis="300000"
    android:configure="com.coderzheaven.customfontinwidget.SettingsPage" 
    android:initialLayout="@layout/widget_main"
/> 

widget_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/widget_root"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:baselineAligned="false"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/imageView_bg"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitXY"
        android:contentDescription="@drawable/ic_launcher" />
    
    <ImageView
        android:id="@+id/imageView_txt"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitXY"
        android:contentDescription="@drawable/ic_launcher" />

</FrameLayout>

OK Now the AndroidManifest File.

Do look at my old posts for more explanation about the Mainfest files when you are using the widgets.

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

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.coderzheaven.customfontinwidget.SettingsPage"
            android:configChanges="keyboardHidden|orientation"
            android:label="@string/app_name"
            android:theme="@android:style/Theme.Translucent" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
            </intent-filter>
        </activity>

        <receiver
            android:name=".RepeatingAlarm"
            android:process=":remote" />

        <!-- Broadcast Receiver that will process AppWidget Updates -->
        <receiver
            android:name="com.coderzheaven.customfontinwidget.MyAppWidgetProvider"
            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="@layout/my_widget_provider" />
        </receiver>
    </application>

</manifest>

Now create an XML file inside the drawable folder and name it theme0.xml and copy this code into it.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item><shape>
            <gradient android:angle="90" android:centerColor="#7700FF00" android:endColor="#3300FF00" android:startColor="#3300FF00" />

            <stroke android:width="1dp" android:color="#FF00FF00" />

            <corners android:radius="10dp" />

            <padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" />
        </shape></item>

</selector>

Now our XML files are over.
Now we look at the java code.

we have 4 java classes
1. MyAppWidgetProvider.java
2. MyTimer.java
3. RepeatingAlarm.java
4. SettingsPage.java

SettingsPage.java

package com.coderzheaven.customfontinwidget;

import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RemoteViews;

public class SettingsPage extends Activity implements OnClickListener {

	int thisWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		getIdOfCurrentWidget(savedInstanceState);

		((Button) findViewById(R.id.create_widget)).setOnClickListener(this);

	}

	/**
	 * Get the Id of Current Widget from the intent from the Widget or if it is
	 * the first time
	 **/
	void getIdOfCurrentWidget(Bundle savedInstanceState) {
		setResult(RESULT_CANCELED);
		Bundle extras = getIntent().getExtras();
		if (extras != null) {
			thisWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
					AppWidgetManager.INVALID_APPWIDGET_ID);
		}
	}

	/**
	 * Update the widget on first run
	 * 
	 * @param widgetId
	 *            - the ID of current widget to be created
	 */
	public void updateWidget(int widgetId) {
		RemoteViews remoteViews = new RemoteViews(getPackageName(),
				R.layout.widget_main);

		MyTimer myTimer = new MyTimer(this);
		Bitmap bmp = myTimer.buildUpdate(myTimer.getTodaysTime());
		remoteViews.setImageViewBitmap(R.id.imageView_txt, bmp);

		// set a background
		remoteViews.setImageViewResource(R.id.imageView_bg, R.drawable.theme0);

		AppWidgetManager appWidgetManager = AppWidgetManager
				.getInstance(SettingsPage.this);
		// update the widget
		appWidgetManager.updateAppWidget(widgetId, remoteViews);
	}

	public void setResultDataToWidget(int result, int widgetId) {
		System.out.println("WID ID = " + widgetId);

		// update the widget on creation
		updateWidget(widgetId);

		// set the result back to widget
		Intent resultValue = new Intent();
		// pass the widget ID along with the intent so that we will get it on
		// the cofiguration activity
		resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
		setResult(result, resultValue);
		finish();
	}

	@Override
	public void onClick(View v) {
		if (v.getId() == R.id.create_widget)
			setResultDataToWidget(Activity.RESULT_OK, thisWidgetId);
	}

}

MyAppWidgetProvider.java

package com.coderzheaven.customfontinwidget;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;

public class MyAppWidgetProvider extends AppWidgetProvider {

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {

		Intent intent = new Intent(context, RepeatingAlarm.class);
		PendingIntent sender = PendingIntent
				.getBroadcast(context, 0, intent, 0);

		// We want the alarm to go off 1 seconds from now.
		long firstTime = SystemClock.elapsedRealtime();
		firstTime += 1000;

		// Schedule the alarm!
		AlarmManager am = (AlarmManager) context
				.getSystemService(Context.ALARM_SERVICE);
		am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, 1000,
				sender);

	}
}

MyTimer.java

package com.coderzheaven.customfontinwidget;

import java.util.Calendar;

import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Typeface;
import android.widget.RemoteViews;

public class MyTimer {
	RemoteViews remoteViews;
	Context context;
	AppWidgetManager appWidgetManager;
	ComponentName thisWidget;

	public MyTimer(Context context) {

		appWidgetManager = AppWidgetManager.getInstance(context);

		this.context = context;

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

		thisWidget = new ComponentName(context, MyAppWidgetProvider.class);

	}

	public synchronized void runAndUpdateTheWidget() {

		int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

		for (final int appWidgetId : allWidgetIds) {

			System.out.println("UPDATING......" + getTodaysTime() + " ID = "
					+ appWidgetId);

			remoteViews.setImageViewBitmap(R.id.imageView_txt,
					buildUpdate(getTodaysTime()));
			appWidgetManager.updateAppWidget(appWidgetId, remoteViews);

		}

	}

	public Bitmap buildUpdate(String time) {
		int bmpWidth = 250;
		int bmpHeight = 100;
		Bitmap myBitmap = Bitmap.createBitmap(bmpWidth, bmpHeight,
				Bitmap.Config.ARGB_8888);
		Canvas myCanvas = new Canvas(myBitmap);
		Paint paint = new Paint();
		Typeface clock = Typeface.createFromAsset(context.getAssets(),
				"digital-7.ttf");
		paint.setAntiAlias(true);
		paint.setSubpixelText(true);
		paint.setTypeface(clock);
		paint.setStyle(Paint.Style.FILL);
		paint.setColor(Color.RED);
		paint.setTextSize(70); 
		paint.setTextAlign(Align.CENTER);
		myCanvas.drawText(time, bmpWidth / 2, bmpHeight / 2 + (bmpHeight / 4),
				paint);
		return myBitmap;
	}

	public String getTodaysTime() {
		final Calendar c = Calendar.getInstance();
		int hour = Integer
				.parseInt(convertToNormal(c.get(Calendar.HOUR_OF_DAY)));
		int minute = c.get(Calendar.MINUTE);
		int seconds = c.get(Calendar.SECOND);
		return new StringBuilder().append(pad(hour)).append(":")
				.append(pad(minute)).append(":").append(pad(seconds))
				.toString();
	}

	private static String pad(int c) {
		if (c >= 10)
			return String.valueOf(c);
		else
			return "0" + String.valueOf(c);
	}

	public String convertToNormal(int hour) {
		if (hour > 12)
			hour = hour - 12;

		return pad(hour);
	}
}

And the Broadcast receiver
RepeatingAlarm.java

package com.coderzheaven.customfontinwidget;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class RepeatingAlarm extends BroadcastReceiver {
	@Override
	public void onReceive(Context context, Intent intent) {
		MyTimer myTimer = new MyTimer(context);
		myTimer.runAndUpdateTheWidget();
	}
}

Your Clock widget with custom Font is complete, Go on and run it and Check in the widgets area.

You can download the complete source code from this link.

Please leave your valuable comments on this post. We have put a lot of effort on creating this post for you.

Handling Multiple Instances of a Widget in Android and Identifying each instance with it’s own ID.

Hey everyone…….Hope all are well…..

This post is about Android Widgets.
This is going to be one of the bigger posts in Coderzheaven.

This posts helps you to handle multiple instances of a Widget.
Many of our problem is to identify different instances of the same widget.

But there is a solution to this problem.

Please check out my other posts in Coderzheaven to get an Idea of Android Widgets and it’s working.

Create new Widget

http://www.coderzheaven.com/2012/06/15/placing-controls-widget-android-listening-events-them/

How to get Notified when a widget is deleted?

Android Multiple Instance Widget

Android Multiple Instance Widget

Android Multiple Instance Widget

Android Multiple Instance Widget

Here is how we start.

First of all you need to keep these things about the Widget in Mind.

    1. Every instance of Same Widget is associated with a Unique ID.
    2. Widgets ID’s are sent through in the activities that has the “android.appwidget.action.APPWIDGET_CONFIGURE” intent-filter.
    3. RESULT_OK should sent back to the widget

Now we will start.

First we will look at the layouts.

This is the Widget Layout.
widget_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/widget_root"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:baselineAligned="false"
    android:orientation="vertical"
    android:background="@drawable/theme0" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Widget Text"
        android:gravity="center"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</LinearLayout>

Now the widgetprovider XML.

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="250dip"
    android:minHeight="72dip"
    android:updatePeriodMillis="100000"
    android:configure="com.coderzheaven.multiplewidgetinstance.SettingsPage" 
    android:initialLayout="@layout/widget_main"
/> 

Please note that you have to use the exact package name with the class named you used as Configure Intent-filter in the “android:configure” property.

Now the XML for the settings Page.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="20dp"
    tools:context=".MainActivity" 
    android:background="@drawable/theme0">

    <TextView
        android:id="@+id/id_tv"
        android:paddingBottom="20dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:textStyle="bold"
        android:textSize="18dp"
        android:text="@string/hello_world" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/id_tv"
        android:ems="10" >

        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/button1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText1"
            android:textStyle="bold"
        android:text="Save" />

</RelativeLayout>

Please check the above screenshot how it looks like when clicking on the widget.
It is having an edittext in which we will enter the value for the widget.

Our all layout xml are now complete.
Now we will go to the java classes.

We will write the MyAppWidgetProvider class

MyAppWidgetProvider.java

package com.coderzheaven.multiplewidgetinstance;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;

public class MyAppWidgetProvider extends AppWidgetProvider {

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
	}

	/*
	 * This is called when an instance the App Widget is created for the first
	 * time.
	 */
	@Override
	public void onEnabled(Context context) {
		super.onEnabled(context);
	}

	/*
	 * This is called for every broadcast and before each of the above callback
	 * methods.
	 */
	@Override
	public void onReceive(Context context, Intent intent) {
		super.onReceive(context, intent);
	}

	/*
	 * This is called When all instances of App Widget is deleted from the App
	 * Widget host.
	 */
	@Override
	public void onDisabled(Context context) {
		// Unschedule any timers and tasks
		super.onDisabled(context);
	}

	/*
	 * This is called every time an App Widget is deleted from the App Widget
	 * host.
	 */
	@Override
	public void onDeleted(Context context, int[] appWidgetIds) {
		// Unschedule any timers and tasks
		super.onDeleted(context, appWidgetIds);
	}
}

Please make sure you read the comments in this java, so I am providing any description for that.

Now the SettingsPage that edit the widget.

package com.coderzheaven.multiplewidgetinstance;

import android.app.Activity;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RemoteViews;
import android.widget.TextView;

public class SettingsPage extends Activity {

	int thisWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
	public static String ACTION_WIDGET_CONFIGURE = "WIDGET_CONFIGURED";
	SharedPreferences customSharedPreference;
	EditText ed = null;
	Button save = null;
	TextView widgetId = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		ed = (EditText) findViewById(R.id.editText1);
		save = (Button) findViewById(R.id.button1);
		widgetId = (TextView) findViewById(R.id.id_tv);

		save.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				updateWidget();
				if (ed.getText().toString().trim().length() > 0) {
					saveToPreferences("Widget" + thisWidgetId, ed.getText()
							.toString().trim());

					setResultDataToWidget(RESULT_OK);
				} else
					setResultDataToWidget(RESULT_CANCELED);
			}
		});

		getIdOfCurrentWidget(savedInstanceState);

	}

	/** Get the Id of Current Widget from the intent of the Widget **/
	void getIdOfCurrentWidget(Bundle savedInstanceState) {

		setResult(RESULT_CANCELED);

		Bundle extras = getIntent().getExtras();

		if (extras != null) {
			thisWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
					AppWidgetManager.INVALID_APPWIDGET_ID);
			if (getWidgetData("Widget" + thisWidgetId) != null) {
				save.setText("Update");
				ed.append(getWidgetData("Widget" + thisWidgetId));
			}

			widgetId.setText("Widget ID = " + thisWidgetId);
		}

		// If they gave us an intent without the widget id, just bail.
		if (thisWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
			finish();
		}

	}

	/**
	 * Update the Current Widget - This is very important to ensure the widget
	 * is enabled
	 **/
	void updateWidget() {
		AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
		RemoteViews remoteViews = new RemoteViews(getPackageName(),
				R.layout.widget_main);
		Intent clickIntent = getIntent();
		clickIntent.setAction(ACTION_WIDGET_CONFIGURE);
		remoteViews.setTextViewText(R.id.textView1, ed.getText().toString()
				.trim());
		clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, thisWidgetId);
		PendingIntent pendingIntent = PendingIntent.getActivity(this,
				thisWidgetId, clickIntent, 0);
		remoteViews.setOnClickPendingIntent(R.id.widget_root, pendingIntent);
		// update this widget
		appWidgetManager.updateAppWidget(thisWidgetId, remoteViews);
	}

	void setResultDataToWidget(int result) {
		Intent resultValue = new Intent();
		resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, thisWidgetId);
		setResult(result, resultValue);
		finish();
	}

	public void saveToPreferences(String file_name, String data) {
		SharedPreferences myPrefs = getSharedPreferences("Data",
				MODE_WORLD_WRITEABLE);
		SharedPreferences.Editor prefsEditor = myPrefs.edit();
		prefsEditor.putString(file_name, data);
		prefsEditor.commit();
	}

	public String getWidgetData(String file_name) {
		SharedPreferences myPrefs = getSharedPreferences("Data",
				MODE_WORLD_READABLE);
		return (myPrefs.getString(file_name, null));
	}

}

Now the AndroidManifest File.
Make sure you carefully read the Manifest files. Look at the intent filters in the activities and make sure that you have the correct package name in the provider xml file.

AndroidManifest.xml

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

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.coderzheaven.multiplewidgetinstance.SettingsPage"
            android:configChanges="keyboardHidden|orientation"
            android:label="@string/app_name"
            android:theme="@android:style/Theme.Dialog">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
            </intent-filter>
        </activity>

        <!-- Broadcast Receiver that will process AppWidget Updates -->
        <receiver
            android:name="com.coderzheaven.multiplewidgetinstance.MyAppWidgetProvider"
            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="@layout/my_widget_provider" />
        </receiver>
    </application>

</manifest>

Hooray you multiple instance code is complete.
Here we are saving data for each widget in the preferences with the widgetId as key with which we are reloading the data and editing it.

You can download the complete source code from here.

How to find your Google Plus ID

This is so simple

1. Go to your Google + account (https://plus.google.com/).

2. Click on the Profile icon on the Left.

3. If you look at the URL in the address bar, it should look something like this:

https://plus.google.com/104653270154306099169/posts

4. The long numerical string in the URL is your Google+ ID. Here is CoderzHeaven’s from the URL above:

104653270154306099169/

Google + CoderzHeaven

Placing Controls in a Widget in Android and Listening to the events from them.

Hello everyone..

I have already shown how to create a simple widget and add it to the home screen in my previous posts. If you have missed these posts please check it here.

How to create a widget in android?

In the next post I showed you how to listen to a widget delete action and delete the widget.

Now in today’s tutorial I am going to show how to place controls like buttons inside the widget and listen to their events and respond to it.

I am proceeding the same as the previous tutorials.

First I will create a new project named “ControlsInWidget” and name the activity “MyActivity.java”.

Now we will create a layout for this main activity. settings.xml

These are the contents of settings.xml

<TableLayout android:id="@+id/TableLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:id="@+id/tv1"
	android:text="CoderzHeaven Widget Settings Activity"
	android:textColor="@android:color/white"
	android:textSize="15dip"
	android:textStyle="bold"
	android:layout_marginTop="5dip"/>
</TableLayout>

This is the MyActivity. java that uses “settings.xml”

package com.coderzheaven.widgetpack;

import android.app.Activity;
import android.os.Bundle;

public class MyActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.settings);
	}	
}

Now we will create the class for the widget which is named “MyWidget.java”.
please follow the instructions in the link while creating this class for the widget.

How to create a widget in android?

Now replace the contents inside MyWidget.java with this one.

package com.coderzheaven.widgetpack;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.RemoteViews;

public class MyWidget extends AppWidgetProvider {
	
	public static String WIDGET_SETTINGS_ACTION = "SettingsForWidget";
	public static String WIDGET_RECEIVER_ACTION = "WidgetActionReceiver";
	
	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {
		
		Log.d("DEBUG","onUpdate");
		RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
		Intent configIntent = new Intent(context, MyActivity.class);
		configIntent.setAction(WIDGET_SETTINGS_ACTION);
		Intent active = new Intent(context, MyWidget.class);
		active.setAction(WIDGET_RECEIVER_ACTION);
		active.putExtra("Message", "Message for Button 1");
		PendingIntent actionPendingIntent = PendingIntent.getBroadcast(context, 0, active, 0);
		PendingIntent configPendingIntent = PendingIntent.getActivity(context, 0, configIntent, 0);
		remoteViews.setOnClickPendingIntent(R.id.button_one, actionPendingIntent);
		remoteViews.setOnClickPendingIntent(R.id.button_two, configPendingIntent);
		appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
	}
	
	@Override
	public void onReceive(Context context, Intent intent) {
		final String action = intent.getAction();
		if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
			final int appWidgetId = intent.getExtras().getInt(
			AppWidgetManager.EXTRA_APPWIDGET_ID,
			AppWidgetManager.INVALID_APPWIDGET_ID);
		if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
			this.onDeleted(context, new int[] { appWidgetId });
			}
		} else {
		// check, if our Action was called
		if (intent.getAction().equals(WIDGET_RECEIVER_ACTION)) {
			String msg = "";
			try {
				msg = intent.getStringExtra("Message");
			} catch (NullPointerException e) {
				Log.e("Error", "No Message");
			}
			PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, 0);
			NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
			Notification noty = new Notification(R.drawable.icon, "Button in the Widget Clicked.",System.currentTimeMillis());
			noty.setLatestEventInfo(context, "Notification from Widget", msg, contentIntent);
			notificationManager.notify(1, noty);
		}
		super.onReceive(context, intent);
		}
	}
}

Here we have two actions “WIDGET_SETTINGS_ACTION” and “WIDGET_RECEIVER_ACTION” which will be set as action for the two buttons inside the widget.

Now here is the main.xml which is the layout for the widget that contains the controls.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent"
	android:orientation="horizontal"
	android:background="@drawable/yellow_bkg"
	android:layout_gravity="center"
	android:layout_height="wrap_content">
<Button 
	android:text="Button1" 
	android:id="@+id/button_one"
	android:layout_weight="1"
	android:layout_gravity="center_horizontal|center"
	android:layout_height="fill_parent"
	android:layout_width="fill_parent"/>
<Button 
	android:text="Button2" 
	android:id="@+id/button_two"
	android:layout_weight="1"
	android:layout_gravity="center_horizontal|center"
	android:layout_height="fill_parent"
	android:layout_width="fill_parent"/>
</LinearLayout>

Widget

If you want the time to be updated every second, your have to modify simple_widget.xml
file and set updatePerdiodMillis to 1000.
The android update 1.6 unfortunately does not support any update periode that is less then 30
minutes.

Please go through this tutorial for setting up the xml for the widget.

How to create a widget in android?

Inside the onReceive we are checking this to ensure which button is clicked. You can write anything inside this function – like a http call or something to update the widget.

if (intent.getAction().equals(WIDGET_RECEIVER_ACTION)) {

}

The second button in the widget launches the activity “MyActivity” and the first one send a notification and doesn’t have a user interface.

Widget

Widget

Widget

You can download the complete eclipse java android source code from here.

Please leave your comments on this post and also share it and like it if this post was useful.