Android Widget Tutorial PDF
Android Widget Tutorial PDF
Tutorials
Training
Books
Connect
by Lars Vogel
Tutorial
178
18.05.2012
Revision History Revision 0.1 Created Revision 0.2 - 2.2 bug fixes and enhancements 13.12.2010 - 18.05.2012 Lars Vogel 01.09.2010 Lars Vogel
Developing Android Widgets This article describes how to create widgets in Android. It is based on Eclipse 3.7, Java 1.6 and Android 4.0.4 (Ice Cream Sandwich).
Table of Contents
1. Android Widgets 1.1. Homescreen Widgets 1.2. Steps to create a Widget 1.3. Register Widget 1.4. Available views and layouts 1.5. Widget size 1.6. Widget updates 1.7. AppWidgetProvider 2. Prerequisites 3. Example with fixed update interval 4. Update via a service and onClickListener 5. Thank you 6. Questions and Discussion 7. Links and Literature 7.1. Source Code 7.2. Android Widget Resources 7.3. Android Resources 7.4. vogella Resources
1. Android Widgets
1.1. Homescreen Widgets
Widgets are little applications which can be placed on the home screen of your Android device. An Widget gets its data on a periodic timetable. There are two methods to update a widget, one is based on an XML configuration file and the other is based on the Android AlarmManager service.
A Widget runs as part of the homescreen process. This requires that Widgets preserve the permissions of their application.
Widgets use RemoteViews to create there user interface. A RemoteView can be executed by another process with the same permissions as the original application. This way the Widget runs with the
permissions of its defining application. The 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.
Maintain an XML file (AppWidgetProviderInfo) which describes the properties of the widget, e.g. size or the fixed update frequency. Create 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. Maintain the App Widget configuration in the AndroidManifest.xml file. You can also specify a configuration Activity which is called once a new instance instance of the widget is added to the Android homescreen.
The BroadcastReceiver can get an label and and icon assigned. These are used in the list of available Widgets. You also specify the meta-data for the widget via the
android:name="android.appwidget.provider" attribute. The configuration file referred to by this meta-data contains the configuration settings for the widget. If contains for example the update interface, the size and the initial layout before the first update() call on the widget.
<?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="146dp" android:updatePeriodMillis="180000" > </appwidget-provider>
converted by Web2PDFConvert.com
The AlarmManager allows you to be more resource efficient and to have a higher frequency of updates. Here you see an example configuration file for a widget.
<?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="146dp" android:updatePeriodMillis="180000" > </appwidget-provider>
1.7. AppWidgetProvider
Your BroadcastReceiver extends AppWidgetProvider. The AppWidgetProvider class implements the onReceive() method, extracts the required information and calls the following widget lifecycle methods. As you can added several instances of a widget to the homescreen you have lifecycle methods which are called only for the first instance added / removed to the homescreen and others which are called for every instance of your widget. Table 1. Lifecycle method
Method onEnabled() onDisabled() onUpdate() Description Called the first time an instance of your widget is added to the homescreen Called once the last instance of your widget is removed from the homescreen. 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). Widget instance is removed from the homescreen
onDeleted()
All long running operations in these methods should be performed in a service, as the execution time for a broadcast receiver is limited. Using asynchronous processing in the onReceive() method does not help as the system can kill the broadcast process after his onReceive() method.
2. Prerequisites
The following description assume that you have already experience in building standard Android application. Please see Android Tutorial . It also uses partly Android services. You find an introduction into Android Services in Android Service Tutorial .
converted by Web2PDFConvert.com
Create a new Android project de.vogella.android.widget.example with no Activity in the package de.vogella.android.widget.example. Create a new file myshape.xml under the path "/res/drawable-mdpi". This file will define the background we use in your 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:bottomLeftRadius="7dp" android:bottomRightRadius="7dp" android:topLeftRadius="7dp" android:topRightRadius="7dp" /> </shape>
Create the AppWidgetProvider metadata file "widget_info.xml", via File New Android Android XML File
converted by Web2PDFConvert.com
<?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="300000" > </appwidget-provider>
Create the BroadcastReeceiver which will be called for updates. We also register an OnClickListener on the view of the PendingIntent.
package de.vogella.android.widget.example; import java.util.Random; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.util.Log; import android.widget.RemoteViews; public class MyWidgetProvider extends AppWidgetProvider { private static final String ACTION_CLICK = "ACTION_CLICK";
@Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // Get all ids ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class); int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
converted by Web2PDFConvert.com
for (int widgetId : allWidgetIds) { // Create some random data int number = (new Random().nextInt(100)); RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout); Log.w("WidgetExample", String.valueOf(number)); // Set the text remoteViews.setTextViewText(R.id.update, String.valueOf(number));
This attribute specifies that the AppWidgetProvider accepts the ACTION_APPWIDGET_UPDATE broadcast and specifies the metadata for the widget. Run your app. Once your app has been deployed, long press on your desktop and install your new widget.
converted by Web2PDFConvert.com
@Override public void onStart(Intent intent, int startId) { Log.i(LOG, "Called"); // Create some random data
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); Log.w(LOG, "From Intent" + String.valueOf(allWidgetIds.length)); Log.w(LOG, "Direct" + String.valueOf(allWidgetIds2.length)); for (int widgetId : allWidgetIds) { // Create some random data int number = (new Random().nextInt(100)); RemoteViews remoteViews = new RemoteViews(this .getApplicationContext().getPackageName(), R.layout.widget_layout); Log.w("WidgetExample", String.valueOf(number)); // Set the text remoteViews.setTextViewText(R.id.update, "Random: " + String.valueOf(number));
converted by Web2PDFConvert.com
allWidgetIds); PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent); appWidgetManager.updateAppWidget(widgetId, remoteViews); } stopSelf(); super.onStart(intent, startId); }
Change MyWidgetProvider to the following. It will now only construct the service and start it.
package de.vogella.android.widget.example; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.util.Log; public class MyWidgetProvider extends AppWidgetProvider { private static final String LOG = "de.vogella.android.widget.example";
// Build the intent to call the service Intent intent = new Intent(context.getApplicationContext(), UpdateWidgetService.class); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds); // Update the widgets via the service context.startService(intent); } }
Once called this service will update all widgets. You can click on one of the widgets to update all widgets.
5. Thank you
Please help me to support this article:
converted by Web2PDFConvert.com
converted by Web2PDFConvert.com