What is App Widget?
在手机桌面上放置的控件,即Android的桌面组件
Describes the meta data for an installed AppWidget provider. The fields in this class correspond to the fields in the <appwidget-provider> xml tag.
AppWidgetProvider
A convenience class to aid in implementing an AppWidget provider. Everything you can do with AppWidgetProvider, you can do with a regularBroadcastReceiver. AppWidgetProvider merely parses the relevant fields out of the Intent that is received in onReceive(Context,Intent), and calls hook methods with the received extras.
① 在res文件夹下创建一个xml文件夹,里面创建一个xml文件(这里创建了一个test_appwidget_info.xml文件)用于提供元数据:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="200dp" android:minHeight="80dp" android:updatePeriodMillis="10000" android:initialLayout="@layout/test_appwidget" > </appwidget-provider>
其中的test_appwidget为App Widget的布局文件,在第二步创建。
② 创建App Widget的布局文件test_appwidget.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/widgetId" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="This is an AppWidget" android:background="#000" /> </LinearLayout>
③ 创建一个类继承AppWidgetProvider并覆盖里面的几个常用的方法:
import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; public class TestAppWidgetProvider extends AppWidgetProvider{ @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { System.out.println("onUpdate"); super.onUpdate(context, appWidgetManager, appWidgetIds); } @Override public void onDeleted(Context context, int[] appWidgetIds) { System.out.println("onDeleted"); super.onDeleted(context, appWidgetIds); } @Override public void onDisabled(Context context) { System.out.println("onDisabled"); super.onDisabled(context); } @Override public void onEnabled(Context context) { System.out.println("onEnabled"); super.onEnabled(context); } }
④ 在AndroidManifest.xml文件中声明一个receiver,注意intent和meta-data子标签的设置:
<receiver android:name=".TestAppWidgetProvider"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/test_appwidget_info" /> </receiver>
PendingIntent
A description of an Intent and target action to perform with it. Instances of this class are created with getActivity(Context, int, Intent, int),getBroadcast(Context, int, Intent, int), getService(Context, int, Intent, int); the returned object can be handed to other applications so that they can perform the action you described on your behalf at a later time.
RemoteViews
A class that describes a view hierarchy that can be displayed in another process. The hierarchy is inflated from a layout resource file, and this class provides some basic operations for modifying the content of the inflated hierarchy.
创建PendingIntent的基本方法:
在创建一个简单的App Widget的基本步骤基础之上进行一下操作:
① 在test_appwidget.xml文件中添加一个按钮
<Button android:id="@+id/widgetButtonId" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="click me?" />
② 通过RemoteViews在TestAppWidgetProvider的onUpdate()方法中为Botton绑定监听器
@Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { for (int i = 0; i < appWidgetIds.length; i++) { //这里TargetActivity为Intent跳转到的Activity,这个Activity类需要另外编写,在第三步创建 Intent intent = new Intent(context,TargetActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.test_appwidget); //PendingIntent为事件触发是所要执行的PendingIntent remoteViews.setOnClickPendingIntent(R.id.widgetButtonId, pendingIntent); appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews); } super.onUpdate(context, appWidgetManager, appWidgetIds); }
③ 创建一个TargetActivity用作Botton的跳转到的Activity
在创建一个简单的App Widget的基本步骤基础之上进行一下操作:
1、 在AndroidManifest.xml文件中为TestAppWidgetProvider注册新的intent
<receiver android:name=".TestAppWidgetProvider"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <intent-filter> <action android:name="com.test.UPDATE_APP_WIDGET"/> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/test_appwidget_info" /> </receiver>
2、 在TestAppWidgetProvider中定义一个常量:
private static final String UPDATE_ACTION = "com.test.UPDATE_APP_WIDGET";
3、 在TestAppWidgetProvider的onUpdate()方法中使用getBroadcast()方法创建一个PendingIntent;并为AppWidget当中的控件注册监听器
@Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { Intent intent = new Intent(); intent.setAction(UPDATE_ACTION); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0); RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.test_appwidget); remoteViews.setOnClickPendingIntent(R.id.widgetButtonId, pendingIntent); appWidgetManager.updateAppWidget(appWidgetIds, remoteViews); }
4、 在onReceive()方法中接收所需要的广播:
public void onReceive(Context context, Intent intent) { super.onReceive(context, intent); String action = intent.getAction(); if (UPDATE_ACTION.equals(action)) { System.out.println(UPDATE_ACTION); } }
@Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (UPDATE_ACTION.equals(action)) { RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.test_appwidget); remoteViews.setTextViewText(R.id.widgetTextId, "change"); AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); //区分:RemoteViews代表App Widget中的所有空间,而ComponentName代表整个App Widget对象 ComponentName componentName = new ComponentName(context,ExampleAppWidgetProvider.class); appWidgetManager.updateAppWidget(componentName, remoteViews); } else { super.onReceive(context, intent); } }