Pr.Pg Next Pg

Widgets Tutorials

  • Widgets are little applications which can be placed on a widget host, typically the homescreen or the lockscreen, of your Android device.

  • Widgets use RemoteViews to create there user interface. A RemoteView can be executed by another process with the same permissions as the original application. This way the Widget runs with the permissions of its defining application.

  • The screenshot above shows a clock widget.

 

Creating a Widget

  • To create an App Widget, you need the following:

  • AppWidgetProviderInfo object

  • Describes the metadata for an App Widget, such as the App Widget's layout, update frequency, and the AppWidgetProvider class. This should be defined in XML.

  • AppWidgetProvider class implementation

  • Defines the basic methods that allow you to programmatically interface with the App Widget, based on broadcast events. Through it, you will receive broadcasts when the App Widget is updated, enabled, disabled and deleted.

  • To create a widget you

  • Define a layout file.

  • Create an XML file (AppWidgetProviderInfo) which describes the properties of the widget, e.g. size or the fixed update frequency.

  • Create a BroadcastReceiver which is used to build the user interface of the Widget.

  • Enter the Widget configuration in the AndroidManifest.xml file.

  • Optional you can specify a configuration activity which is called once a new instance of the widget is added to the widget host.

 

 

Widget Size

  • When a widget is hosted on the lockscreen, the framework ignores the minWidth, minHeight, minResizeWidth, and minResizeHeight fields.

  • If a widget is also a home screen widget, these parameters are still needed as they're still used on home, but they will be ignored for purposes of the lockscreen.

  • Widget will take a certain amount of cells on the homescreen.

  • A cell is usually used to display the icon of one application.

  • As a calculation rule you should define the size of the widget with the formula: ((Number of columns / rows)* 74) - 2.

  • These are device independent pixels and the -2 is used to avoid rounding issues.

 

Declaring an App Widget in the Manifest

  • To register a widget you create a BroadcastReceiver with an intent filter for the android.appwidget.action.APPWIDGET_UPDATE action.

  • Add the code below in the Manifest.

 

 

 

<receiver

android:label="Our Widget"

android:name="MyWidgetExampleProvider">

<intent-filter >

<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />

</intent-filter>

 

<meta-data

android:name="android.appwidget.provider"

android:resource="@xml/widget_info"/>

</receiver>

 

  • The meta data which specifies the AppWidgetProviderInfo resource refers to the configuration file which contains the configuration settings for this widget.

  • Now we make the widget_info file which will contains the configurations.

  • Define the AppWidgetProviderInfo object in an XML resource using a single<appwidget-provider> element and save it in the project's res/xml/ folder.

 

 

 

<?xml version="1.0" encoding="utf-8"?>

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"

android:configure="com.example.helloandroid.WidgetConfig"

android:initialLayout="@layout/widget_example"

android:minHeight="40dp"

android:minWidth="40dp"

android:resizeMode="horizontal|vertical"

android:updatePeriodMillis="18000000"

android:widgetCategory="home_screen">

 

</appwidget-provider>

  • The values for the minWidth and minHeight attributes specify the minimum amount of space the App Widget consumes by default.

  • The initialLayout attribute points to the layout resource that defines the App Widget layout.

  • The updatePeriodMillis attribute defines how often the App Widget framework should request an update from the AppWidgetProvider by calling the onUpdate() callback method. The actual update is not guaranteed to occur exactly on time with this value and we suggest updating as infrequently as possible—perhaps no more than once an hour to conserve the battery.

  • The resizeMode attribute specifies the rules by which a widget can be resized. You use this attribute to make homescreen widgets resizeable—horizontally, vertically, or on both axes. 

  • The widgetCategory attribute declares whether your App Widget can be displayed on the home screen, the lock screen (keyguard), or both.

 

Widget Layout

  • You must define an initial layout for your App Widget in XML and save it in the project's res/layout/ directory. 

  • In our case we have defined a layout named widget_example.

 

Widget_example.xml

 

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical">

 

<TextView

android:id="@+id/tvDisplayDate"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="" />

 

<TextView

android:id="@+id/tvDisplayMessage"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="" />

 

<Button

android:id="@+id/bConfigureWidget"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="Configure Widget" />

 

 

 

</LinearLayout>

 

 

 

 

  • In our tutorial we will build a widget which will display the Date and also a message.

  • The widget will also have a configurations activity which will help us configure our widget.

  • Below is the code for the java class of the WidgetProvider which extends AppwidgetProvider.

 

MyWidgetExampleProvider.java

 

package com.example.helloandroid;

 

 

import java.text.SimpleDateFormat;

import java.util.Date;

 

import com.example.helloandroid.R.raw;

 

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;

import android.widget.TextView;

import android.widget.Toast;

 

public class MyWidgetExampleProvider extends AppWidgetProvider {

TextView time;

TextView message;

@Override

public void onReceive(Context context, Intent intent) {

// TODO Auto-generated method stub

super.onReceive(context, intent);

}

@Override

public void onUpdate(Context context, AppWidgetManager appWidgetManager,

int[] appWidgetIds) {

// TODO Auto-generated method stub

super.onUpdate(context, appWidgetManager, appWidgetIds);

//Perform this loop for each AppWidget that belongs to this provider

for(int i=0;i<appWidgetIds.length;i++){

int appWidgetId = appWidgetIds[i];

RemoteViews r = new RemoteViews(context.getPackageName(),R.layout.widget_example);

SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");

String str = sdf.format(new Date());

r.setTextViewText(R.id.tvDisplayDate,str);

Intent in = new Intent(context,WidgetConfig.class);

PendingIntent p = PendingIntent.getActivity(context, 0, in, 0);

r.setOnClickPendingIntent(R.id.bConfigureWidget, p);

appWidgetManager.updateAppWidget(appWidgetId, r);

}

}

@Override

public void onDeleted(Context context, int[] appWidgetIds) {

// TODO Auto-generated method stub

super.onDeleted(context, appWidgetIds);

Toast t =Toast.makeText(context,"The widget was removed", Toast.LENGTH_SHORT);

t.show();

}

}

 

 

 

  • In the onUpdate() method we take in the context in which the receiver is running, the AppWidgetManager object you can call updateAppWidget(ComponentName, RemoteViews) on and the appWidgetIds for which an update is needed. Note that this may be all of the AppWidget instances for this provider, or just a subset of them.

  • We then run the for loop for each app widget.

  • Basically widgets use remote views which can be used to modify the contents of the layout and inflate them.

  • In our widget we get the date in the desired format using the SimpleDateFormat object and then set the text of our first TextView as the date.

  • The second TextView will be set when the widget is configured which we explain later.

  • We will also have a button which will launch the configuration onClicking it. For this purpose we use PendingIntents. In simple words they are used when a task is to be done later on i.e the button is supposed to start a new activity when it is clicked and not when the onUpdate() method is called.

  • We then update() the widget using the updateAppWidget() method.

  • We also a display a toast when a widget is removed (deleted).

 

Pr.Pg border                                              Next Pg