Mobile Programming Lecture 17 Creating Homescreen Widgets.

Slides:



Advertisements
Similar presentations
Android Application Development Tutorial. Topics Lecture 6 Overview Programming Tutorial 3: Sending/Receiving SMS Messages.
Advertisements

Mobile Computing Lecture#13. Lecture Contents 2 Widgets  Creating App Widget  Unsupported/Supported Views/Layouts  Widget Layout  Widget Settings.
All About Android Introduction to Android 1. Creating a New App “These aren’t the droids we’re looking for.” Obi-wan Kenobi 1. Bring up Eclipse. 2. Click.
CSS216 MOBILE PROGRAMMING Android, Chapter 10 Book: “Professional Android™ 2 Application Development” by Reto Meier, 2010 by: Andrey Bogdanchikov (
Application Fundamentals. See: developer.android.com/guide/developing/building/index.html.
Filip Debelić What is it? Android is a mobile operating system (OS) based on the Linux kernel and currently developed by Google Android,
Android 101 Application Fundamentals January 29, 2010.
Cosc 4730 Android TabActivity and ListView. TabActivity A TabActivity allows for multiple “tabs”. – Each Tab is it’s own activity and the “root” activity.
Android Development (Basics)
Chien-Chung Shen Manifest and Activity Chien-Chung Shen
Mobile Programming Lecture 1 Getting Started. Today's Agenda About the Eclipse IDE Hello, World! Project Android Project Structure Intro to Activities,
Introduction to Android Programming Content Basic environmental structure Building a simple app Debugging.
Introducing the Sudoku Example
CS5103 Software Engineering Lecture 08 Android Development II.
ANDROID UI – FRAGMENTS. Fragment  An activity is a container for views  When you have a larger screen device than a phone –like a tablet it can look.
Mobile Computing Lecture#08 IntentFilters & BroadcastReceivers.
Favorite Twitter® Searches App Android How to Program © by Pearson Education, Inc. All Rights Reserved.
1 Mobile Computing Monetizing An App Copyright 2014 by Janson Industries.
Chapter 2: Simplify! The Android User Interface
Broadcast Receiver Android Club Agenda Broadcast Receiver Widget.
Tip Calculator App Building an Android App with Java © by Pearson Education, Inc. All Rights Reserved.
Android Layouts. Layouts Define the user interface for an activity Layouts are defined in.xml files – within /res/layout folder – different layout can.
Cosc 5/4730 Introduction: Threads, Android Activities, and MVC.
Homescreen Widgets Demystified Pearl AndroidTO // Oct 26, 2010.
Using Intents to Broadcast Events Intents Can be used to broadcast messages anonymously Between components via the sendBroadcast method As a result Broadcast.
Mobile Programming Lecture 6
CS378 - Mobile Computing Intents.
16 Services and Broadcast Receivers CSNB544 Mobile Application Development Thanks to Utexas Austin.
1 Announcements Homework #2 due Feb 7 at 1:30pm Submit the entire Eclipse project in Blackboard Please fill out the when2meets when your Project Manager.
Frank Xu Gannon University.  Linear Layout  Relative Layout  Table Layout.
Chapter 2 The Android User Interface. Objectives  In this chapter, you learn to:  Develop a user interface using the TextView, ImageView, and Button.
INTRODUCTION TO ANDROID. Slide 2 Application Components An Android application is made of up one or more of the following components Activities We will.
Cosc 5/4730 Android App Widgets. App Widgets App Widgets are miniature application views that can be embedded in other applications (such as the Home.
SpotOn Game App Android How to Program © by Pearson Education, Inc. All Rights Reserved.
CS378 - Mobile Computing Intents. Allow us to use applications and components that are part of Android System – start activities – start services – deliver.
Android Boot Camp for Developers Using Java, 3E
User Interfaces: Part 1 (View Groups and Layouts).
Application Development for mobile Devices
Android – Fragments L. Grewe.
Android Boot Camp for Developers Using Java, Comprehensive: A Guide to Creating Your First Android Apps Chapter 2: Simplify! The Android User Interface.
Mobile Programming Lecture 5 Composite Views, Activities, Intents and Filters.
Liang, Introduction to Java Programming, Eighth Edition, (c) 2011 Pearson Education, Inc. All rights reserved Introduction to Android (Part.
Field Trip #32 Digital Alarm Clock By Keith Lynn.
Cosc 4730 Android Fragments. Fragments You can think of a fragment as a modular section of an activity, which has its own lifecycle, receives its own.
Announcements Homework #2 will be posted after class due Thursday Feb 7, 1:30pm you may work with one other person No office hours tonight (sorry!) I will.
Mobile Programming Lecture 3 Debugging. Lecture 2 Review What widget would you use to allow the user to enter o a yes/no value o a range of values from.
Mobile Programming Lecture 11 Animation and TraceView.
Graphics Concepts CS 2302, Fall /17/20142 Drawing in Android.
HW#9 Clues CSCI 571 Fall, HW#9 Prototype
Services Background operating component without a visual interface Running in the background indefinitely Differently from Activity, Service in Android.
CS378 - Mobile Computing User Interface Basics. User Interface Elements View – Control – ViewGroup Layout Widget (Compound Control) Many pre built Views.
Building User Interfaces Basic Applications
Android Boot Camp for Developers Using Java, Comprehensive: A Guide to Creating Your First Android Apps Chapter 10: Move! Creating Animation 1 Android.
Mobile Programming Lecture 4 Resources, Selection, Activities, Intents.
ANDROID LAYOUTS AND WIDGETS. Slide 2 Introduction Parts of the Android screen Sizing widgets and fonts Layouts and their characteristics Buttons, checkboxes.
Resources. Android Resources We’ve already talked about the different types of Android Resources DirectoryResource Type anim/XML files that define tween.
Chapter 2: Simplify! The Android User Interface
Lab7 – Appendix.
Android – Event Handling
Mobile Application Development Chapter 3 [Using Eclipse Android Studio for Android Development] IT448-Fall 2017 IT448- Fall2017.
2D Graphics: Part 2.
Android Widget Tutorial
Creation of an Android App By Keith Lynn
Mobile Application Development Chapter 4 [Android Navigation and Interface Design] IT448-Fall 2017 IT448- Fall2017.
ANDROID UI – FRAGMENTS UNIT II.
HNDIT2417 Mobile Application Development
Android Layout Basics Topics
CS5103 Software Engineering
Android Notifications (Part 2) Plus Alarms and BroadcastReceivers
CA16R405 - Mobile Application Development (Theory)
Presentation 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

Shape Drawables <shape xmlns:android=" android:shape="rectangle"> Specify the type of shape by adding the android:shape attribute

Shape Drawables <stroke android:width="2dp" android:color="#000000" /> The element defines the border of the rectangle

Shape Drawables <stroke android:width="2dp" android:color="#000000" /> Here we make the border black and 2dp thick

Shape Drawables <stroke android:width="2dp" android:color="#000000" /> <gradient android:angle="0" android:endColor="#DD2ECCFA" android:startColor="#DD000000" /> The element allows you to fade from one start color to an end color

Shape Drawables <stroke android:width="2dp" android:color="#000000" /> <gradient android:angle="0" android:endColor="#DD2ECCFA" android:startColor="#DD000000" /> Here we have a linear gradient from black to white

Shape Drawables <stroke android:width="2dp" android:color="#000000" /> <gradient android:angle="0" android:endColor="#DD2ECCFA" android:startColor="#DD000000" /> <corners android:radius="25dp" /> The element allows you to add rounded corners for your shape

Shape Drawables <stroke android:width="2dp" android:color="#000000" /> <gradient android:angle="0" android:endColor="#DD2ECCFA" android:startColor="#DD000000" /> <corners android:radius="25dp" /> 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:layout_width="100dp" android:layout_height="50dp" android:layout_marginTop="41dp" />

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 one is based on an XML configuration file and o 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: 1Define 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. 3Create 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. 4Maintain 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 <shape xmlns: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" /> Create your Shape XML file

1 Define Layout file for Widget <LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="8dip" > <TextView 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" >

1 Define Layout file for Widget <LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="8dip" > <TextView 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" > Add your Shape XML file as the background in the Layout for your Widget

1 Define Layout file for Widget <LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="8dip" > <TextView 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" > 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 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 <appwidget-provider xmlns:android=" android:minHeight="72dp" android:minWidth="300dp" android:updatePeriodMillis="180000" >

2 Create XML Widget info file Modify the file (using the XML form method, or the XML editor) to look like this <appwidget-provider xmlns:android=" android:minHeight="72dp" android:minWidth="300dp" android:updatePeriodMillis="180000" > Set the minimum height and width of the AppWidget

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 MethodDescription 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 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 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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)

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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)

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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

3 Create and register BCR public class MyWidgetProvider extends AppWidgetProvider 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.

3 Create and register BCR You need to register your BCR in the manifest file <application > <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />

3 Create and register BCR You need to register your BCR in the manifest file <application > <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />

4 Add Widget Config to Manifest You need to register your BCR in the manifest file <application > <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <meta-data android:name="android.appwidget.provider" />

4 Add Widget Config to Manifest You need to register your BCR in the manifest file <application > <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <meta-data android:name="android.appwidget.provider" />

4 Add Widget Config to Manifest See this post on StackOverflow on adding multiple widgets for the same Appthis post on StackOverflow

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 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 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 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 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 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

Updating Widget via 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 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

References The Busy Coder's Guide to Android Development - Mark Murphy The Busy Coder's Guide to Android Development - Mark Murphy Android Developers The Mobile Lab at Florida State University