78
Mobile Programming Lecture 17 Creating Homescreen Widgets

Mobile Programming Lecture 17 Creating Homescreen Widgets

Embed Size (px)

Citation preview

Page 1: Mobile Programming Lecture 17 Creating Homescreen Widgets

Mobile ProgrammingLecture 17

Creating Homescreen Widgets

Page 2: Mobile Programming Lecture 17 Creating Homescreen Widgets

Agenda

• Shape Drawables

• Homescreen Widgets

• Updating Widgets with a BroadcastReceiver

• Updating Widgets with a Service

Page 3: Mobile Programming Lecture 17 Creating Homescreen Widgets

Shape Drawables

• If you need to show a simple shape on the screen, you can use a Shape Drawable

• Useful for displaying rectangles, squares, circles, ovals, rings, and lines

• Can also be used when creating homescreen widgets

• Use an ImageView to display a shape in your Layout

Page 4: Mobile Programming Lecture 17 Creating Homescreen Widgets

Shape Drawables

• To create a new Shape

• File > New > Android XML File

• Resource Type: Drawable

• File: e.g. myshape.xml

• Root element: shape

Page 5: Mobile Programming Lecture 17 Creating Homescreen Widgets

Shape Drawables

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

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

</shape>

Page 6: Mobile Programming Lecture 17 Creating Homescreen Widgets

Shape Drawables

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

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

android:shape="rectangle">

</shape>

Specify the type of shape by adding the android:shape attribute

Page 7: Mobile Programming Lecture 17 Creating Homescreen Widgets

Shape Drawables

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

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">

<stroke

android:width="2dp"

android:color="#000000" />

</shape>

The <stroke> element defines the border of the rectangle

Page 8: Mobile Programming Lecture 17 Creating Homescreen Widgets

Shape Drawables

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

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">

<stroke

android:width="2dp"

android:color="#000000" />

</shape>

Here we make the border black and 2dp thick

Page 9: Mobile Programming Lecture 17 Creating Homescreen Widgets

Shape Drawables

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

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">

<stroke

android:width="2dp"

android:color="#000000" />

<gradient

android:angle="0"

android:endColor="#DD2ECCFA"

android:startColor="#DD000000" />

</shape>

The <gradient> element allows you to fade from one start color to an end color

Page 10: Mobile Programming Lecture 17 Creating Homescreen Widgets

Shape Drawables

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

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">

<stroke

android:width="2dp"

android:color="#000000" />

<gradient

android:angle="0"

android:endColor="#DD2ECCFA"

android:startColor="#DD000000" />

</shape>

Here we have a linear gradient from black to white

Page 11: Mobile Programming Lecture 17 Creating Homescreen Widgets

Shape Drawables

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

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">

<stroke

android:width="2dp"

android:color="#000000" />

<gradient

android:angle="0"

android:endColor="#DD2ECCFA"

android:startColor="#DD000000" />

<corners

android:radius="25dp" />

</shape>

The <corners> element allows you to add rounded corners for your shape

Page 12: Mobile Programming Lecture 17 Creating Homescreen Widgets

Shape Drawables

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

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">

<stroke

android:width="2dp"

android:color="#000000" />

<gradient

android:angle="0"

android:endColor="#DD2ECCFA"

android:startColor="#DD000000" />

<corners

android:radius="25dp" />

</shape>

You can also round each corner individually. Use Ctrl+Space to see your options

Page 13: Mobile Programming Lecture 17 Creating Homescreen Widgets

Shape Drawables

• To show the Shape on the screen, add an ImageView and set the android:src attribute

• Modify the layout_height and layout_width attributes and your shape will adjust accordingly

<ImageView

android:id="@+id/myShapeView"

android:layout_width="100dp"

android:layout_height="50dp"

android:layout_marginTop="41dp"

android:src="@drawable/my_shape" />

Page 14: Mobile Programming Lecture 17 Creating Homescreen Widgets

Shape Drawables

See ShapeExample.tar

Page 15: Mobile Programming Lecture 17 Creating Homescreen Widgets

Homescreen Widgets

• Widgets are little applications which can be placed on the home screen of your Android device

• A Widget gets its data on a periodic timetable

• There are two methods to update a widgeto one is based on an XML configuration file and o the other is based on the Android AlarmManager

service.

Page 16: Mobile Programming Lecture 17 Creating Homescreen Widgets

Homescreen Widgets

• A Widget runs as part of the homescreen process

Page 17: Mobile Programming Lecture 17 Creating Homescreen Widgets

Homescreen Widgets

• 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

Page 18: Mobile Programming Lecture 17 Creating Homescreen Widgets

Homescreen Widgets

• The user interface for an Widget is defined by an BroadcastReceiver

• This BroadcastReceiver inflates its layout into an object of type RemoteViews

• This RemoteViews object is delivered to Android, which hands it over the HomeScreen application.

Page 19: Mobile Programming Lecture 17 Creating Homescreen Widgets

Steps to Create a Widget

To create a Widget you:

1 Define a layout file for your Widget

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

3 Create and register a BroadcastReceiver which will be used to build the user interface of the Widgets. This receiver extends the AppWidgetProvider class which provides additional lifecycle hooks for Widgets.

4 Maintain the App Widget configuration in the AndroidManifest.xml file

Page 20: Mobile Programming Lecture 17 Creating Homescreen Widgets

Example

In this example, we will create a widget that will display a random number every 30 minutes or whenever the widget is clicked.

Page 21: Mobile Programming Lecture 17 Creating Homescreen Widgets

1 Define Layout file for Widget

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

<stroke android:width="2dp" android:color="#FFFFFFFF" />

<gradient android:angle="225" android:endColor="#DD2ECCFA" android:startColor="#DD000000" />

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

</shape>

Create your Shape XML file

Page 22: Mobile Programming Lecture 17 Creating Homescreen Widgets

1 Define Layout file for Widget

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layout" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="8dip" android:background="@drawable/myshape" >

<TextView android:id="@+id/update" style="@android:style/TextAppearance.Medium" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:gravity="center_horizontal|center_vertical" android:layout_margin="4dip" android:text="Static Text" > </TextView>

</LinearLayout>

Page 23: Mobile Programming Lecture 17 Creating Homescreen Widgets

1 Define Layout file for Widget

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layout" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="8dip" android:background="@drawable/myshape" >

<TextView android:id="@+id/update" style="@android:style/TextAppearance.Medium" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:gravity="center_horizontal|center_vertical" android:layout_margin="4dip" android:text="Static Text" > </TextView>

</LinearLayout>

Add your Shape XML file as the background in the Layout for your Widget

Page 24: Mobile Programming Lecture 17 Creating Homescreen Widgets

1 Define Layout file for Widget

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layout" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="8dip" android:background="@drawable/myshape" >

<TextView android:id="@+id/update" style="@android:style/TextAppearance.Medium" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:gravity="center_horizontal|center_vertical" android:layout_margin="4dip" android:text="Static Text" > </TextView>

</LinearLayout>

This TextView will be used to show the random number

Page 25: Mobile Programming Lecture 17 Creating Homescreen Widgets

2 Create XML Widget info file

• File > New > Android > Android XML File

• Resource Type: AppWidget Provider

• File: e.g. "widget_info.xml"

Page 26: Mobile Programming Lecture 17 Creating Homescreen Widgets

2 Create XML Widget info file

• In the widget configuration file you can specify a fixed update interval

o the system will wake up after this time interval and call your broadcast receiver to update the widget

o the smallest update interval is 180000 milliseconds (30 minutes)

Page 27: Mobile Programming Lecture 17 Creating Homescreen Widgets

2 Create XML Widget info file

• Modify the file (using the XML form method, or the XML editor) to look like this

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

xmlns:android="http://schemas.android.com/apk/res/android"android:initialLayout="@layout/widget_layout"android:minHeight="72dp"android:minWidth="300dp"android:updatePeriodMillis="180000" >

</appwidget-provider>

Page 28: Mobile Programming Lecture 17 Creating Homescreen Widgets

2 Create XML Widget info file

• Modify the file (using the XML form method, or the XML editor) to look like this

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

xmlns:android="http://schemas.android.com/apk/res/android"android:initialLayout="@layout/widget_layout"android:minHeight="72dp"android:minWidth="300dp"android:updatePeriodMillis="180000" >

</appwidget-provider>

Set the minimum height and width of the AppWidget

Page 29: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCR

Next we create and register our Broadcast Receiver

Our BroadcastReceiver will extend AppWidgetProvider, which is itself a subclass of BroadcastReceiver

Page 30: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCR

• Your BroadcastReceiver extends AppWidgetProvider

• The AppWidgetProvider class implements the onReceive() methodo it extracts the required information and calls the

following widget lifecycle methods

Page 31: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCR

Lifecycle Methods

Method Description

onEnabled() Called the first time an instance of your widget is added to the homescreen

onDisabled() Called once the last instance of your widget is removed from the homescreen.

onUpdate() Called for every update of the widget. Contains the ids of 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, as stated in the methods JavaDoc. For example if more than one widget is added to the homescreen, only the last one changes (until reinstall).

onDeleted() Widget instance is removed from the homescreen

Page 32: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

Page 33: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

This is a BroadcastReceiver

Page 34: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

{

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

The regular BCR doesn't have onUpdate, but AppWidgetProvider does. Override this method

Page 35: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

This will be used to update AppWidget state. It can be used to get information about an installed AppWidget provider

Page 36: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

These are the AppWidgets that need to be updated. It may be all of them, or just a subset

Page 37: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

ComponentName simply encapsulates the package name and the class name of MyWidgetProvider

Page 38: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

We will get all of the widget ids anyway, and try to update them all (however, in this example there's just one widget)

Page 39: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

We will show how to have multiple widgets for a single app in step 4

Page 40: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

Iterate through all of the widget ids. This is similar to using allWidgetIds.length to iterate

Page 41: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

Get a random number

Page 42: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

A RemoteView can be executed by another process. Here the widget will run with the same permissions as the app

Page 43: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

We use this because the Homescreen app will run our Widget, instead of our own app running the Widget

Page 44: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

First argument is the package name of your app. We can get the package name from the Context

Page 45: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

Second argument is the resource id of the Layout defining what the Widget looks like. This is the XML file from step 1

Page 46: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

Here we change the text that should show up on the Widget when it is updated

Page 47: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

Call setTextViewText on the RemoteView

Page 48: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

First argument is the id of the TextView in our XML Layout file

Page 49: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

Second argument is the text. Here we convert the int to a String

Page 50: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);

remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

Next we will register an onClick event that will allow the widget to be updated when it is clicked

Page 51: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

Nothing new here. We're just creating an instance of an Intent the way we know how, for a BroadcastReceiver

Page 52: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

Set the Intent Action. This intent will be sent when it's time to update the AppWidget, or when it's being instantiated

Page 53: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

Here we put extra information in our Intent. EXTRA_APPWIDGET_IDS is a String, and is used for exactly this purpose (used as the key for the extra)

Page 54: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

Since we don't want to fire off the Intent now, we create a PendingIntent so that we can hand it off to the AppWidgetManager

Page 55: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

This is equivalent to calling setOnClickListener on a View. The View in this case is the TextView identified by R.id.update

Page 56: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCRpublic class MyWidgetProvider extends AppWidgetProvider {

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

ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

for (int widgetId : allWidgetIds) { int number = (new Random().nextInt(100));

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

remoteViews.setTextViewText(R.id.update, String.valueOf(number));Intent intent = new Intent(context, MyWidgetProvider.class);intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);appWidgetManager.updateAppWidget(widgetId, remoteViews);

}}

}

Here we set the RemoteViews used to update this widget. Again, the RemoteView can be executed by another process.

Page 57: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCR

You need to register your BCR in the manifest file

<application android:icon="@drawable/icon" android:label="@string/app_name" > <receiver android:name="MyWidgetProvider" > <intent-filter > <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> </receiver> </application>

Page 58: Mobile Programming Lecture 17 Creating Homescreen Widgets

3 Create and register BCR

You need to register your BCR in the manifest file

<application android:icon="@drawable/icon" android:label="@string/app_name" > <receiver android:name="MyWidgetProvider" > <intent-filter > <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> </receiver> </application>

Page 59: Mobile Programming Lecture 17 Creating Homescreen Widgets

4 Add Widget Config to Manifest

You need to register your BCR in the manifest file

<applicationandroid:icon="@drawable/icon"android:label="@string/app_name" ><receiver android:name="MyWidgetProvider" >

<intent-filter ><action

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

<meta-dataandroid:name="android.appwidget.provider"android:resource="@xml/widget_info" />

</receiver></application>

Page 60: Mobile Programming Lecture 17 Creating Homescreen Widgets

4 Add Widget Config to Manifest

You need to register your BCR in the manifest file

<applicationandroid:icon="@drawable/icon"android:label="@string/app_name" ><receiver android:name="MyWidgetProvider" >

<intent-filter ><action

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

<meta-dataandroid:name="android.appwidget.provider"android:resource="@xml/widget_info" />

</receiver></application>

Page 61: Mobile Programming Lecture 17 Creating Homescreen Widgets

4 Add Widget Config to Manifest

See this post on StackOverflow on adding multiple widgets for the same App

Page 62: Mobile Programming Lecture 17 Creating Homescreen Widgets

Homescreen Widgets

• How to run your app?

• Longpress an empty area on the home screen

• Add your Widget to the home screen

Tapping on the widget should update the number

Page 63: Mobile Programming Lecture 17 Creating Homescreen Widgets

Homescreen Widgets

See WidgetExample.tar

Also note when the callback methods for MyWidgetProvider are executed by looking at the Log tag for MyWidgetProvider in LogCat

Page 64: Mobile Programming Lecture 17 Creating Homescreen Widgets

Available Views and Layouts

• A widget is restricted in the elements it can use. o For layouts you can use

FrameLayout, LinearLayout, RelativeLayouto As views you can use

AnalogClock, Button, Chromometer, ImageButton,ImageView, ProgressBar and TextView

• As of Android 3.0 more views are available: GridView, ListView, StackView, ViewFlipper and AdapterViewFlipper

• The only interaction possible on the Views of a Widget is via on OnClickListener

Page 65: Mobile Programming Lecture 17 Creating Homescreen Widgets

Widget Size

• A 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.

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

• As of Android 3.1 a Widgets can be flexible in size, e.g. the user can make is larger or smaller.

o To enable this for Widgets you can use the android:resizeMode="horizontal|vertical" attribute in the XML configuration file for the widget.

Page 66: Mobile Programming Lecture 17 Creating Homescreen Widgets

Widget Size

Why use a BroadcastReceiver for updating widgets?

Page 67: Mobile Programming Lecture 17 Creating Homescreen Widgets

Updating Widget via Service

BroadcastReceiver should finish onReceive() in a timely manner

If you have a longer running operation for updating a widget, combine the BCR with a Service

Page 68: Mobile Programming Lecture 17 Creating Homescreen Widgets

Updating Widget via Service

Create a new Service, e.g. UpdateWidgetService that extends Service

We will use our BroadcastReceiver to start UpdateWidgetService

Page 69: Mobile Programming Lecture 17 Creating Homescreen Widgets

Updating Widget via Servicepublic class MyWidgetProvider extends AppWidgetProvider {

@Override

public void onUpdate(Context context, AppWidgetManager appWidgetManager,

int[] appWidgetIds) {

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

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

Intent intent = new Intent(context.getApplicationContext(), UpdateWidgetService.class);

intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);

context.startService(intent);

}

}

Page 70: Mobile Programming Lecture 17 Creating Homescreen Widgets

Updating Widget via Servicepublic class MyWidgetProvider extends AppWidgetProvider {

@Override

public void onUpdate(Context context, AppWidgetManager appWidgetManager,

int[] appWidgetIds) {

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

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

Intent intent = new Intent(context.getApplicationContext(),

UpdateWidgetService.class);

intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);

context.startService(intent);

}

}

Pass the information that was sent to the BCR to the our UpdateWidgetService

Page 71: Mobile Programming Lecture 17 Creating Homescreen Widgets

Updating Widget via 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(), MyWidgetProvider.class);

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

for (int widgetId : allWidgetIds) {

int number = (new Random().nextInt(100));

RemoteViews remoteViews = new RemoteViews(this .getApplicationContext().getPackageName(),

R.layout.widget_layout);

remoteViews.setTextViewText(R.id.update, "Random: " + String.valueOf(number));

Intent intent = new Intent(this.getApplicationContext(), MyWidgetProvider.class);

intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);

intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);

PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);

remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);

appWidgetManager.updateAppWidget(widgetId, remoteViews);

}

stopSelf();

super.onStart(intent, startId);

}

This code is in our UpdateWidgetService class, which extends Service

Page 72: Mobile Programming Lecture 17 Creating Homescreen Widgets

Updating Widget via 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(), MyWidgetProvider.class);

for (int widgetId : allWidgetIds) {

int number = (new Random().nextInt(100));

RemoteViews remoteViews = new RemoteViews(this .getApplicationContext().getPackageName(),

R.layout.widget_layout);

remoteViews.setTextViewText(R.id.update, "Random: " + String.valueOf(number));

Intent intent = new Intent(this.getApplicationContext(), MyWidgetProvider.class);

intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);

intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);

PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);

remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);

appWidgetManager.updateAppWidget(widgetId, remoteViews);

}

stopSelf();

super.onStart(intent, startId);

}

Page 73: Mobile Programming Lecture 17 Creating Homescreen Widgets

Updating Widget via 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(), MyWidgetProvider.class);

for (int widgetId : allWidgetIds) {

int number = (new Random().nextInt(100));

RemoteViews remoteViews = new RemoteViews(this .getApplicationContext().getPackageName(),

R.layout.widget_layout);

remoteViews.setTextViewText(R.id.update, "Random: " + String.valueOf(number));

Intent intent = new Intent(this.getApplicationContext(), MyWidgetProvider.class);

intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);

intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);

PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);

remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);

appWidgetManager.updateAppWidget(widgetId, remoteViews);

}

stopSelf();

super.onStart(intent, startId);

}

Most of this code has remained unchanged from the BCR code in our previous example

Page 74: Mobile Programming Lecture 17 Creating Homescreen Widgets

Updating Widget via 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(), MyWidgetProvider.class);

for (int widgetId : allWidgetIds) {

int number = (new Random().nextInt(100));

RemoteViews remoteViews = new RemoteViews(this .getApplicationContext().getPackageName(),

R.layout.widget_layout);

remoteViews.setTextViewText(R.id.update, "Random: " + String.valueOf(number));

Intent intent = new Intent(this.getApplicationContext(), MyWidgetProvider.class);

intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);

intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);

PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);

remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);

appWidgetManager.updateAppWidget(widgetId, remoteViews);

}

stopSelf();

super.onStart(intent, startId);

}

The main reason for starting this Service is in case you have code that takes too long to be run in a BCR

Page 75: Mobile Programming Lecture 17 Creating Homescreen Widgets

Updating Widget via 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(), MyWidgetProvider.class);

for (int widgetId : allWidgetIds) {

int number = (new Random().nextInt(100));

RemoteViews remoteViews = new RemoteViews(this .getApplicationContext().getPackageName(),

R.layout.widget_layout);

remoteViews.setTextViewText(R.id.update, "Random: " + String.valueOf(number));

Intent intent = new Intent(this.getApplicationContext(), MyWidgetProvider.class);

intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);

intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);

PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent,

PendingIntent.FLAG_UPDATE_CURRENT);

remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);

appWidgetManager.updateAppWidget(widgetId, remoteViews);

}

stopSelf();

super.onStart(intent, startId);

}

We stop the Service here because it has completed its task

Page 76: Mobile Programming Lecture 17 Creating Homescreen Widgets

Updating Widget via Service

See WidgetServiceExample.tar

Page 77: Mobile Programming Lecture 17 Creating Homescreen Widgets

Updating Widget via Service

Code examples taken from

http://www.vogella.com/articles/AndroidWidgets/article.html

Page 78: Mobile Programming Lecture 17 Creating Homescreen Widgets

References

• The Busy Coder's Guide to Android Development - Mark Murphy

• Android Developers

• http://www.vogella.com/articles/AndroidWidgets/article.html

• The Mobile Lab at Florida State University