Showing posts with label widget. Show all posts
Showing posts with label widget. Show all posts

Sunday, July 8, 2012

Tutorial on Android Homescreen Widget with AlarmManager.

This is a follow up tutorial on Android widget. If you haven't read it till now then please go through    it before starting this tutorial. You may be aware that AppWidgetProvider's lowest interval is 30 mins. In this tutorial we will learn  to create widget with update interval less than 30 mins using AlarmManager.

New update:

In Android 4.1, a new feature has been introduced for Homescreen widget which enables widget to reorganize its view when resized. To support this feature a new method onAppWidgetOptionsChanged() has been introduced in AppWidgetProvider class. This method gets called in response to the ACTION_APPWIDGET_OPTIONS_CHANGED broadcast when this widget has been layed out at a new size. 

Project Information:  Meta-information about the project.

Platform Version : Android API Level 16.
IDE : Eclipse Helios Service Release 2
Emulator: Android 4.1

Prerequisite: Preliminary knowledge of Android application framework, Intent Broadcast receiver and AlarmManager.

Example with fixed update interval less than 30 mins.

In this tutorial we will create time widget which shows current time. This widget will get updated every second and we will be using AlarmManager for it. Here, repeating alarm is set for one second interval. But in real world scenario, it is not recommended to use one second repeating alarm because it drains the battery fast. You have to follow the similar steps mentioned in previous widget tutorial  to write widget layout file. But this time we are introducing a TextView field in the layout which will display the time. The content of the "time_widget_layout.xml" is given below.
<linearlayout android:background="@drawable/widget_background" 
   android:layout_height="match_parent" android:layout_width="match_parent" 
   android:orientation="vertical" 
   xmlns:android="http://schemas.android.com/apk/res/android">
     <textview android:gravity="center_horizontal|center_vertical" 
          android:id="@+id/tvTime" android:layout_gravity="center" 
          android:layout_height="match_parent" android:layout_margin="4dip" 
          android:layout_width="match_parent" android:textcolor="#000000" 
          style="android: style/TextAppearance.Medium;"/>
</linearlayout>

Follow the same procedure to create the AppWidgetProvider metadata file. The content of metadata file "widget_metadata.xml" is given below.
  <appwidget-provider android:initiallayout="@layout/time_widget_layout" 
        android:minheight="40dp" android:minwidth="130dp"  
        android:updateperiodmillis="1800000" 
        xmlns:android="http://schemas.android.com/apk/res/android">
</appwidget-provider>

In this tutorial, onEnabled(), onDsiabled(), onUpdate() and onAppWidgetOptionsChanged() have been defined unlike the previous widget tutorial where only onUpdate() was defined. 

  • onEnabled(): An instance of AlarmManager is created here to start the repeating timer and register the intent with the AlarmManager.  As this method gets called at the very first instance of widget installation, it helps to set repeating alarm  only once.
  • onDisabled(): In this method, alarm is canceled because this method gets called as soon as the very last instance of widget is removed/uninstalled and we don't want to leave the registered alarm even when it's not being used.
  • onUpdate(): This method updates the time on remote TextView.
  • onAppWidgetOptionsChanged(): This method gets called when the widget is resized.

package com.rakesh.widgetalarmmanagerexample;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.RemoteViews;
import android.widget.Toast;

public class TimeWidgetProvider extends AppWidgetProvider {

 @Override
 public void onDeleted(Context context, int[] appWidgetIds) {
  Toast.makeText(context, "TimeWidgetRemoved id(s):"+appWidgetIds, Toast.LENGTH_SHORT).show();
  super.onDeleted(context, appWidgetIds);
 }

 @Override
 public void onDisabled(Context context) {
  Toast.makeText(context, "onDisabled():last widget instance removed", Toast.LENGTH_SHORT).show(); 
  Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
  PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
  AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
  alarmManager.cancel(sender);
  super.onDisabled(context);
 }

 @Override
 public void onEnabled(Context context) {
  super.onEnabled(context);
  AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
  Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
  PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
  //After after 3 seconds
  am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+ 100 * 3, 1000 , pi);
 }

 @Override
 public void onUpdate(Context context, AppWidgetManager appWidgetManager,
   int[] appWidgetIds) {
  ComponentName thisWidget = new ComponentName(context,
    TimeWidgetProvider.class);

  for (int widgetId : appWidgetManager.getAppWidgetIds(thisWidget)) {

   //Get the remote views
   RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
     R.layout.time_widget_layout);
   // Set the text with the current time.
   remoteViews.setTextViewText(R.id.tvTime, Utility.getCurrentTime("hh:mm:ss a"));
   appWidgetManager.updateAppWidget(widgetId, remoteViews);
  }
 }

 @Override
 public void onAppWidgetOptionsChanged(Context context,
   AppWidgetManager appWidgetManager, int appWidgetId,
   Bundle newOptions) {
  //Do some operation here, once you see that the widget has change its size or position.
  Toast.makeText(context, "onAppWidgetOptionsChanged() called", Toast.LENGTH_SHORT).show();
 }
}


Broadcast receiver is defined to handle the intent registered with alarm. This broadcast receiver gets called every second because repeating alarm has been set in the AppWidgetProvider classs for 1 second. Here, onReceive() method has been defined which updates the widget with the current time and getCurrentTime() has been used to get the current time.
package com.rakesh.widgetalarmmanagerexample;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.widget.RemoteViews;
import android.widget.Toast;

public class AlarmManagerBroadcastReceiver extends BroadcastReceiver {

 @Override
 public void onReceive(Context context, Intent intent) {
  PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
  PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "YOUR TAG");
  //Acquire the lock
  wl.acquire();

  //You can do the processing here update the widget/remote views.
  RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
    R.layout.time_widget_layout);
  remoteViews.setTextViewText(R.id.tvTime,  Utility.getCurrentTime("hh:mm:ss a"));
  ComponentName thiswidget = new ComponentName(context, TimeWidgetProvider.class);
  AppWidgetManager manager = AppWidgetManager.getInstance(context);
  manager.updateAppWidget(thiswidget, remoteViews);
  //Release the lock
  wl.release();
 }
}

It's always a good idea to keep utility methods in some utility class which can be accessed from other packages. getCurrentTime() has been defined in the Uitility class. This method is used in AppWidgetProvider and BroadcastReciever classes. 
package com.rakesh.widgetalarmmanagerexample;

import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Utility {
  public static String getCurrentTime(String timeformat){
      Format formatter = new SimpleDateFormat(timeformat);
         return formatter.format(new Date());
     }
}

In Android manifest file, we need to include WAKE_LOCK permission because wake lock is used in broadcast receiver. AlarmManagerBroadcastReceiver has been registered as broadcast receiver. Remaining part is simple to understand.
  <manifest android:versioncode="1" android:versionname="1.0" 
      package="com.rakesh.widgetalarmmanagerexample" 
      xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-sdk android:minsdkversion="16" android:targetsdkversion="16"/>

<uses-permission android:name="android.permission.WAKE_LOCK"/>
    <application android:icon="@drawable/ic_launcher" 
          android:label="@string/app_name">
        <activity android:label="@string/title_activity_widget_alarm_manager" 
                android:name=".WidgetAlarmManagerActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <receiver android:icon="@drawable/ic_launcher" 
             android:label="@string/app_name"
             android:name=".TimeWidgetProvider">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
            </intent-filter>
            <meta-data android:name="android.appwidget.provider"  
                android:resource="@xml/widget_metadata"/>
        </receiver>
        <receiver android:name=".AlarmManagerBroadcastReceiver"/>
    </application>
</manifest>

Once the code is executed, the widget gets registered. When you install widget on homescreen, it appears as shown below.
Android Homescreen time widget

you can download source code from here.

Related tutorial:



Your valuable comments are always welcomed. It will help to improve my post and understanding.

"By three methods we may learn wisdom: First, by reflection, which is noblest; Second, by imitation, which is easiest; and third by experience, which is the bitterest."
By : Confucius

Tuesday, July 3, 2012

Android widget tutorial

Android widgets are small application which can be embedded inside another application such as Home screen. It can be used to show updated data to the user. You can embed these widgets in  an application. These widgets get updated periodically based either on their periodicity set in the widget xml configuration file or by the use of Alarm-manager. Widgets can also be updated asynchronously from Broadcast receiver. The tutorial given below explains the procedure to update the widget from broadcast receiver. But before that you must be aware of certain basics about widget. You can also find the related documentation here.

Basic building blocks

  • AppWidgetProviderInfo object
  • AppWidgetProvider 
  • Widget View layout 

AppWidgetProviderInfo object:

It provides meta-data about the widget for e.g widget initial layout, its min-height, min-width, update frequency and AppWidgetProvider class. It should be defined in xml file.

AppWidgetProvider:

It provides interfaces and ways to interact with the widget. The callback methods get called based on the broadcast events. These events get triggered as soon as the widget is added, removed, enabled,  disabled or update interval lapses.

Widget ViewLayout:

View layout is basically written in the xml file. This is the initial layout of the widget. There are very  few View components available. The RemoteView Object can support the following layout classes:
  • FrameLayout
  • GridLayout (Available on API 16)
  • LinearLayout
  • RelativeLayout
and following widget classes
  • AnalogClock
  • Button
  • Chronometer
  • FrameLayout
  • ImageButton
  • ImageView
  • ProgressBar
  • TextView
  • ViewFlipper
  • ViewStub (Available on API 16)
Project Information:  Meta-information about the project.
Platform Version : Android API Level 10.
IDE : Eclipse Helios Service Release 2
Emulator: Android 4.0.4
Prerequisite: Preliminary knowledge of Android application framework, Intent Broadcast receiver and Service.

Now create project by Eclipse > File> New Project>Android Application Project. The following dialog box will appear. Fill the required field, i.e Application Name, Project Name and Package Name. Don't forget to select the Build SDK version (for this tutorial Google API 10 has been selected). Now press the next button.


Once the dialog box appears, select the BlankActivity and click the next button.

Fill the Activity Name and Layout file name for the dialog box shown below and hit the finish button.

This process will setup the basic project files. The next step is to define the widget layout xml file. The  same can be created with the help of Android XML file generator dialog window which can be  accessed through these menu and sub-menu options Eclipse>File>new>Android XML File. Since we have to create Layout file so we need to select Layout for Resource Type. The project field is automatically populated with project name. In File field enter the suitable xml file name. Don't forget to put the ".xml" file extension otherwise the dialog window will show error. In the root element list select the layout  for the widget. For this tutorial Linear Layout has been selected as shown in the picture below.

Content of widget_layout.xml file. You can ignore the "android:background" attribute field for LinearLayout and button, since this field has been used here to customize the background color and the size.
 <linearlayout android:background="@drawable/background"
       android:gravity="center" android:layout_height="match_parent" 
       android:layout_margin="4dp" android:layout_width="match_parent"  
       android:orientation="vertical"   
       xmlns:android="http://schemas.android.com/apk/res/android">
   <button android:background="@drawable/button_shape" 
     android:id="@+id/BtEnableDisable" 
     android:layout_height="wrap_content" android:layout_width="100dp" 
     android:text="@string/strWidgetBtEnableDisable">
</button></linearlayout>

The next step is to define widget meta data. This xml file basically represents the AppWidgetProviderInfo object. As mentioned earlier this file contains information about the widget for e.g min-width, min-height, update frequency etc. Here the update frequency has been set as 0 because we want to asynchronously update the widget. The minimum frequency allowed by Android system is 30min(30X60X100 miliseconds). If the update frequency is less than 180,000 miliseconds Android may ignore  this value. This file also contains the widget layout file name which is widget_background.xml in this case. For creating this file you can use the Android XML file dialog as explained in the above steps. But make sure that you select the Resource Type as AppWiget Provider. The content of widget_metadata.xml file is as following. 
 
<appwidget-provider android:initiallayout="@layout/widget_layout" 
     android:minheight="40dp" android:minwidth="130dp" 
     android:updateperiodmillis="0" 
     xmlns:android="http://schemas.android.com/apk/res/android">
</appwidget-provider>
In order to customize the widget background and shape you need to define the xml and include it in widget_layout.xml file. To create this file use Android XML file dialog as mentioned in the previous steps but for customization file select Resource Type as Drawable and Root element as Shape. You can put the following content in background.xml.
  <shape android:id="@+id/Corners" 
           xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient android:angle="45" android:endcolor="#997f7f7f"
      android:startcolor="#99111111">
       <padding android:bottom="1dp" android:left="4dp"
             android:right="4dp" android:top="1dp">
        <corners android:radius="7dp">
          <stroke android:color="#FFFFFFFF" android:width="2dp">
          </stroke>
        </corners>
      </padding>
    </gradient>
</shape>

If you want to customize the button then you should define another customization file for button and include that in layout file. If you are not keen to customize the button or widget then go to the next step. Content of button_shape.xml
  <shape android:id="@+id/shapeBt" 
          xmlns:android="http://schemas.android.com/apk/res/android">
   <gradient android:angle="45" android:endcolor="#FFFAFAFA" 
           android:startcolor="#FFFFFFFF">
    <padding android:bottom="1dp" android:left="4dp" 
          android:right="4dp" android:top="1dp">
     <corners android:radius="7dp">
      <stroke android:color="#FFFFFFFF" android:width="2dp">
        <size android:height="35dp" android:width="90dp">
        </size>
      </stroke>
     </corners>
   </padding>
 </gradient>
</shape>
SimpleWidgetAppWigetProvider class extends AppWidgetProvider class. The methods defined in the SimpleWidgetAppWidgetProvider determine the behavior of the the widget. These methods get called based on the events triggered.
Methods present in AppWidgetProvider:

  • onReceive(): This method gets called for every broadcast and before every other callback method present in AppWidgetProvider. In most of the cases you don't need to implement this method. 
  • onEnabled(): This method gets called at the very first instance when the widget gets created. This method is similar to onCreate() method present in Activity class. If some initialization is required for your widget then  this is the right place to do it.
  • onDisabled(): This method gets called when the very last instance is removed from the container.
  • onUpdate(): This method gets called to update the widget. It gets called even when you create an instance of widget, thus it makes some initial setup. This method gets called at interval defined by updatePeriodMillis attribute in widget-meta info.  
  • onDeleted(): As the name suggests, this method gets called whenever an instance is removed/deleted.
You will notice that Service gets invoked by startService()  method call and passing intent object as  a parameter in startService().

package com.rakesh.simplewidget;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;


public class SimpleWidgetAppWidgetProvider extends AppWidgetProvider {

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

  final int N = appWidgetIds.length;
  ComponentName thisWidget = new ComponentName(context,
    SimpleWidgetAppWidgetProvider.class);
  int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

  // Build the intent to call the service
  Intent intent = new Intent(context.getApplicationContext(),
    UpdateWidgetService.class);
  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);

  // Update the widgets via the service
  context.startService(intent);
}

UpdateWidgetService class extends the service class. Here onStart() method has been defined which  does the actual job(here we are trying to enable/disable the packet data) and then it tries to update the remote view with the help of updateAppWidget() method call. PendingIntent and setOnClickPendingIntent() method help to attach action listener to the button.
package com.rakesh.simplewidget;


import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.widget.RemoteViews;

public class UpdateWidgetService extends Service {

 @Override
 public void onStart(Intent intent, int startId) {

  AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this
    .getApplicationContext());

  int[] allWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);

  ComponentName thisWidget = new ComponentName(getApplicationContext(),
    SimpleWidgetAppWidgetProvider.class);

  for (int widgetId : allWidgetIds) {
   RemoteViews remoteViews = new RemoteViews(this
     .getApplicationContext().getPackageName(),
     R.layout.widget_layout);

   EnableDisableConnectivity edConn = new EnableDisableConnectivity(this.getApplicationContext());
   edConn.enableDisableDataPacketConnection(!checkConnectivityState(this.getApplicationContext()));

   // Register an onClickListener
   Intent clickIntent = new Intent(this.getApplicationContext(),
     SimpleWidgetAppWidgetProvider.class);

   clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
   clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,
     allWidgetIds);

   PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, clickIntent,
     PendingIntent.FLAG_UPDATE_CURRENT);
   remoteViews.setOnClickPendingIntent(R.id.BtEnableDisable, pendingIntent);
   appWidgetManager.updateAppWidget(widgetId, remoteViews);
  }
  stopSelf();

  super.onStart(intent, startId);
 }

 @Override
 public IBinder onBind(Intent intent) {
  return null;
 }

 private boolean checkConnectivityState(Context context){
  final TelephonyManager telephonyManager = (TelephonyManager) context
    .getSystemService(Context.TELEPHONY_SERVICE);
  return telephonyManager.getDataState() == TelephonyManager.DATA_CONNECTED;

 }
}

Since this tutorial is about how to update the widget when CONNECTIVITY_CHANGE intent is received, so here ConnectivityReceiver class has been defined which extends the BroadcastReceiver class. When application receives CONNECTIVITY_CHANGE intent it calls onReceive() method. In onReceive() method we try to get the remote view and then change the text and color of the button with the help of setTetViewText() and setTextColor() method respectively.

package com.rakesh.simplewidget;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;


public class ConnectivityReceiver extends BroadcastReceiver {

 @Override
 public void onReceive(Context context, Intent intent) {
  NetworkInfo info = (NetworkInfo)intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO);
  
  if(info.getType() == ConnectivityManager.TYPE_MOBILE){
   
   RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
     R.layout.widget_layout);
   
   if(info.isConnectedOrConnecting()){
    Toast.makeText(context, "Data packet enabled", Toast.LENGTH_SHORT).show();
    Log.d("RK","Mobile data is enabled");
    remoteViews.setTextColor(R.id.BtEnableDisable, Color.GREEN);
    remoteViews.setTextViewText(R.id.BtEnableDisable, "Enabled");
   }else{
    Toast.makeText(context, "Data packet disabled", Toast.LENGTH_SHORT).show();
    Log.e("RK","Mobile data is disconnected");
    remoteViews.setTextColor(R.id.BtEnableDisable, Color.BLACK);
    remoteViews.setTextViewText(R.id.BtEnableDisable,"Disabled");
   }
   
   ComponentName thiswidget = new ComponentName(context, SimpleWidgetAppWidgetProvider.class);
   AppWidgetManager manager = AppWidgetManager.getInstance(context);
   manager.updateAppWidget(thiswidget, remoteViews);
   
  }
 }

}
Below is the Android manifest file which defines the application components and their permissions.
<manifest android:versioncode="1" android:versionname="1.0" 
      package="com.rakesh.simplewidget"  
      xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-sdk android:minsdkversion="10">
    
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE">
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE">

    &t;application android:icon="@drawable/widget_icon" 
            android:label="@string/app_name">
        <activity android:label="@string/app_name" 
              android:name=".SimpleWidgetExampleActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN">

                <category android:name="android.intent.category.LAUNCHER">
            </category></action></intent-filter>
        </activity>
        
        <receiversxml android:icon="@drawable/widget_icon"
             android:label="@string/app_name" 
             android:name=".SimpleWidgetAppWidgetProvider">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE">
            </action></intent-filter>
            <meta-data android:name="android.appwidget.provider" 
                 android:resource="@xml/widget_metadata">
        

        <service android:name=".UpdateWidgetService">
        <receiver android:name=".ConnectivityReceiver">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE">
            </action></intent-filter>
        </receiver>
    </service></meta-data></receiversxml></application>

     </uses-permission>
     </uses-permission>
   </uses-sdk>
</manifest>

You may have noticed that the AppwidgetProvider class has registered APPWIDGET_UPDATE intent. The class shown below is a helper class which basically enables/disables the packet data connection state. You can skip this part because it does not have much relevance to widget. But I have provided this code for those who may be interested in enabling/disabling packet data connection.

package com.rakesh.simplewidget;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import android.content.Context;
import android.net.ConnectivityManager;
import android.telephony.TelephonyManager;
import android.util.Log;

public class EnableDisableConnectivity {
 private Context mContext;
 public EnableDisableConnectivity(Context context){
  this.mContext = context;
 }
 public boolean enableDataPacketConnection(){
  return enableDisableDataPacketConnection(true);
 }
 public boolean disableDataPacketConnection(){
  return enableDisableDataPacketConnection(false);
 }

 public boolean enableDisableDataPacketConnection(boolean enable){
  boolean result = false;
  Method dataConnSwitchmethod;
  Class telephonyManagerClass;
  Object ITelephonyStub;
  Class ITelephonyClass;
  final ConnectivityManager conman = 
         (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
  try{
   final Class conmanClass = Class.forName(conman.getClass().getName());
   final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
   iConnectivityManagerField.setAccessible(true);
   final Object iConnectivityManager = iConnectivityManagerField.get(conman);
   final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
   final Method setMobileDataEnabledMethod = 
      iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
   setMobileDataEnabledMethod.setAccessible(true);
   setMobileDataEnabledMethod.invoke(iConnectivityManager, enable);
   result = true;
  }catch(Exception e){
   Log.e("Error", "here is an exception "+e.getMessage());
   result =false;
  }
  return result;
 }

 private boolean checkConnectivityState(){
  final TelephonyManager telephonyManager = (TelephonyManager) mContext
    .getSystemService(Context.TELEPHONY_SERVICE);
  return telephonyManager.getDataState() == TelephonyManager.DATA_CONNECTED;

 }
}

On executing this code you will notice that one icon named Data packet widget has been deployed     and appears in the application list as shown in Fig 1. If you want to check whether widget has been recognized by Android  ,then you need to check the widgets tab(Fig. 2) on Android 15. For Android version lower than 15, you need to long-press on the home-screen and then you will see the list of widgets available. Select the  data-packet-widget it will get deployed on home-screen. Once the widget is deployed you will see the widget on home-screen as shown in Fig 3.
Application tab which shows installed applications.
1. Applications tab
Widgets tab shows what all widgets are available.
2. Widgets tab
Home screen which shows that Data-packet widget is installed on  home screen.
3. Installed widget
If you want to explore the new features of widgets introduced in Android 4.1, watch the video below.

If you want to download the source code you can find it here. In next Widget tutorial we will learn how to use AlarmManger to update the widget if the periodicity of update is less than 30 mins.

Related tutorial:

Tutorial on Android Widget with AlarmManager
Tutorial on Android AlaramManager

Your valuable comments are always welcomed. It will help to improve my post and understanding.
"By three methods we may learn wisdom: First, by reflection, which is noblest; Second, by imitation, which is easiest; and third by experience, which is the bitterest."
By : Confucius