Download Lecture 17 - Florida State University

Document related concepts
no text concepts found
Transcript
Mobile
Programming
Lecture 17
Creating Homescreen
Widgets
Agenda
•
Shape Drawables
•
Homescreen Widgets
•
Updating Widgets with a BroadcastReceiver
•
Updating Widgets with a Service
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
Shape Drawables
•
•
•
•
•
To create a new Shape
File > New > Android XML File
Resource Type: Drawable
File: e.g. myshape.xml
Root element: shape
Shape Drawables
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
</shape>
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
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
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
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
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
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
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
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" />
Shape Drawables
See ShapeExample.tar
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 widget
o
o
one is based on an XML configuration file and
the other is based on the Android AlarmManager
service.
Homescreen Widgets
•
A Widget runs as part of the homescreen
process
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
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.
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
Example
In this example, we will create a widget that will
display a random number every 30 minutes
or whenever the widget is clicked.
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
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>
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"
Add your Shape XML file
android:background="@drawable/myshape" >
as the background in the
Layout for your Widget
<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>
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
2 Create XML Widget info file
•
File > New > Android > Android XML File
•
Resource Type: AppWidget Provider
•
File: e.g. "widget_info.xml"
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)
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>
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"
Set the minimum height
android:minHeight="72dp"
and width of the AppWidget
android:minWidth="300dp"
android:updatePeriodMillis="180000" >
</appwidget-provider>
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
3 Create and register BCR
•
•
Your BroadcastReceiver extends AppWidgetProvider
The AppWidgetProvider class implements the
onReceive() method
o it extracts the required information and calls the
following widget lifecycle methods
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
3 Create and register BCR
public 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);
}
}
}
3 Create and register BCR
This is a
BroadcastReceiver
public 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);
}
}
}
3 Create and register BCR
The regular BCR doesn't have
onUpdate, but
AppWidgetProvider does.
Override this method
public 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);
}
}
}
3 Create and register BCR
This will be used to update
AppWidget state. It can be used to get
information about an installed
AppWidget provider
public 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);
}
}
}
3 Create and register BCR
These are the AppWidgets that
need to be updated. It may be
all of them, or just a subset
public 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);
}
}
}
3 Create and register BCR
ComponentName simply
encapsulates the package name
and the class name
ofAppWidgetProvider {
public class MyWidgetProvider
extends
MyWidgetProvider
@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);
}
}
}
3 Create and register BCR
We will get all of the widget ids
anyway, and tryextends
to update
them
public class MyWidgetProvider
AppWidgetProvider
{
all (however, in this example
there's just one widget)
@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);
}
}
}
3 Create and register BCR
We will show how to have
multiple widgets for a single
app in step 4
public 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);
}
}
}
3 Create and register BCR
public class MyWidgetProvider extends AppWidgetProvider {
Iterate through all of the widget
ids. This is similar to using
@Override
allWidgetIds.length
to iterate
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);
}
}
}
3 Create and register BCR
public class MyWidgetProvider extends AppWidgetProvider {
@Override
Getvoid
a random
number context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
public
onUpdate(Context
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);
}
}
}
3 Create and register BCR
public class MyWidgetProvider extends AppWidgetProvider {
A RemoteView can be executed by
@Override
another process. Here the widget
public
context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
will void
run onUpdate(Context
with the same permissions
as the app
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);
}
}
}
3 Create and register BCR
public class MyWidgetProvider extends AppWidgetProvider {
We use this because the
@Override
Homescreen app will run our
public
void onUpdate(Context
context,
Widget,
instead of our own
appAppWidgetManager appWidgetManager, int[] appWidgetIds) {
running the Widget
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);
}
}
}
3 Create and register BCR
public class MyWidgetProvider extends AppWidgetProvider {
First argument is the package
@Override
of your app. We
can get the {
public void onUpdate(Context context, AppWidgetManagername
appWidgetManager,
int[] appWidgetIds)
package name from the Context
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);
}
}
}
3 Create and register BCR
public class MyWidgetProvider extends AppWidgetProvider {
@Override
argument isint[]
the
resource id{
public void onUpdate(Context context, AppWidgetManagerSecond
appWidgetManager,
appWidgetIds)
of the Layout defining what the
Widget looks like. This is the XML
ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);
file from step 1
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);
}
}
}
3 Create and register BCR
public class MyWidgetProvider extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Here we change the text that
shouldComponentName
show up on thethisWidget
Widget = new ComponentName(context, MyWidgetProvider.class);
allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
when itint[]
is updated
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);
}
}
}
3 Create and register BCR
public class MyWidgetProvider extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);
setTextViewText on the
int[] allWidgetIdsCall
= appWidgetManager.getAppWidgetIds(thisWidget);
RemoteView
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);
}
}
}
3 Create and register BCR
public 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);
First argument is the id of the
TextView in our XML Layout file
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);
}
}
}
3 Create and register BCR
public 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);
Second argument is the text. Here
we convert the int to a String
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);
}
}
}
3 Create and register BCR
public class MyWidgetProvider extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);
Next we will register an onClick
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
event that will allow the widget to
be updated when it is clicked
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);
}
}
}
3 Create and register BCR
public class MyWidgetProvider extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);
Nothing new here. We're just
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
creating an instance of an Intent the
way we know how, for a
for (int
widgetId : allWidgetIds) {
BroadcastReceiver
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);
}
}
}
3 Create and register BCR
public 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);
Set the Intent Action. This intent will
bewidgetId
sent when
it's time to
for (int
: allWidgetIds)
{ update the
AppWidget,
when
it's being
int number or
= (new
Random().nextInt(100));
instantiated
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);
}
}
}
3 Create and register BCR
public 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);
Here
for (int widgetId : allWidgetIds)
{ we put extra information in our
Intent. EXTRA_APPWIDGET_IDS is a
int number = (new Random().nextInt(100));
String,= and
used for exactly this
RemoteViews remoteViews
new is
RemoteViews(context.getPackageName(),
purpose (used as the key for the extra) 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);
}
}
}
3 Create and register BCR
public 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);
Since
we don't want to fire off the Intent
for (int widgetId : allWidgetIds)
{
now, we create a PendingIntent so that
int number = (new Random().nextInt(100));
we can
hand
it off to the
RemoteViews remoteViews
= new
RemoteViews(context.getPackageName(),
AppWidgetManager
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);
}
}
}
3 Create and register BCR
public 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));
This is equivalent to calling
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
setOnClickListener on a View. The View
R.layout.widget_layout);
in this case is the TextView identified by
remoteViews.setTextViewText(R.id.update, String.valueOf(number));
R.id.update
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);
}
}
}
3 Create and register BCR
public 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);
Here we set the RemoteViews used to
remoteViews.setTextViewText(R.id.update,
String.valueOf(number));
update this widget. Again,
the
Intent intent = new RemoteView
Intent(context, MyWidgetProvider.class);
can be executed by
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
another process.
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);
}
}
}
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>
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>
4 Add Widget Config to Manifest
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>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_info" />
</receiver>
</application>
4 Add Widget Config to Manifest
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>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_info" />
</receiver>
</application>
4 Add Widget Config to Manifest
See this post on StackOverflow on adding
multiple widgets for the same App
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
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
Available Views and Layouts
•
•
•
A widget is restricted in the elements it can use.
o For layouts you can use
 FrameLayout, LinearLayout, RelativeLayout
o 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
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.
Widget Size
Why use a BroadcastReceiver for updating 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
Updating Widget via Service
Create a new Service, e.g. UpdateWidgetService that
extends Service
We will use our BroadcastReceiver to start
UpdateWidgetService
Updating Widget via Service
public 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);
}
}
Updating Widget via Service
public 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
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
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);
Updating Widget via Service
@Override public void onStart(Intent intent, int startId) {
AppWidgetManager appWidgetManager =
AppWidgetManager.getInstance(this.getApplicationContext());
Most of this code has remained
unchanged from the BCR code
in our previous example
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);
}
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
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
Updating Widget via Service
See WidgetServiceExample.tar
Updating Widget via Service
Code examples taken from
http://www.vogella.com/articles/AndroidWidgets/article.html
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