Android的AppWidget的概念不好理解啊,我也不知道理解得对不对,先记在这里,以免以后又忘记了。
(1) 建立一个Android工程,用eclispse吧,下一步,下一步的就不多说了。
(2) 在res/xml目录下面建立一个xml文件。命名随便吧。写下如下内容
1<?xml version="1.0" encoding="utf-8"?>
2<appwidget-provider
3 xmlns:android="http://schemas.android.com/apk/res/android"
4 android:initialLayout="@layout/widget_layout_small"
5 android:minWidth="72dip" android:minHeight="72dip" android:updatePeriodMillis="3600000">
6</appwidget-provider>
这里是定义一个appwidget-provider,Android系统从这里认为该程序是一个widget程序。android:initialLayout指定布局文件,也就是在res/layout目录下的那些个xml文件;android:updatePeriodMillis知道更新周期,单位为毫秒;还有一个android:configure,这个是可选的,如果你的widget事先要启动一个Activity,就需要在这里指定一个Activity,显然我们这里不需要。他就是一个AppWidgetProviderInfo类的描述信息。
(3) 写布局文件,这个就不多说了。
(4) appwidget-provider,定义一个类,从AppWidgetProvider类继承,他实际是一个BroadcastReceiver,系统使用它和Widget界面进行交互。
1package cn.vaga.today;
2
3import java.util.Calendar;
4
5import android.app.PendingIntent;
6import android.appwidget.AppWidgetManager;
7import android.appwidget.AppWidgetProvider;
8import android.content.ComponentName;
9import android.content.Context;
10import android.content.Intent;
11import android.graphics.Canvas;
12import android.text.format.Time;
13import android.widget.RemoteViews;
14
15public class TodayDateSmall extends AppWidgetProvider
16{
17 // 当这个AppWidget提供者 被要求提供RemoteViews一系列的AppWidgets,这个方法作为ACTION_APPWIDGET_UPDATE
18 // 广播回复时被调用
19 // 每次更新AppWidget时候调用
20 @Override
21 public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
22 // 得到更新后的RemoteViews
23 RemoteViews updateView = buildUpdate(context);
24 //更新Widget的RemoteViews
25 appWidgetManager.updateAppWidget(appWidgetIds, updateView);
26 super.onUpdate(context, appWidgetManager, appWidgetIds);
27 }
28
29 private String[] months = {"一月", "二月", "三月", "四月",
30 "五月", "六月", "七月", "八月",
31 "九月", "十月", "十一月", "十二月"};
32
33
34 private RemoteViews buildUpdate(Context context) {
35 RemoteViews updateView = null;
36 // 这个Time更快
37 // Time time = new Time();
38 // 现在
39 //time.setToNow();
40 Calendar cal = Calendar.getInstance();
41 String month = months[cal.get(Calendar.MONTH)];
42 // 得到RemoteViews
43 updateView = new RemoteViews(context.getPackageName(), R.layout.widget_layout_small);
44 // 设置View的内容
45 // 日期
46 updateView.setTextViewText(R.id.Date, String.valueOf(cal.get(Calendar.DATE)));
47 // 月
48 updateView.setTextViewText(R.id.Month, month);
49 Lunar lunar = new Lunar(cal);
50 updateView.setTextViewText(R.id.Lunar,lunar.toString());
51 // OK,这个一个运行用的Intent啦
52 // 加下面这段应该只是为了让Widget相应click事件吧
53 Intent launchIntent = new Intent();
54 // 设置处理该Intent的组件,这里是android自带的日期启动组件
55 launchIntent.setComponent(new ComponentName("com.android.calendar", "com.android.calendar.LaunchActivity"));
56 // 设置该Itent为主进入点
57 launchIntent.setAction(Intent.ACTION_MAIN);
58 launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
59 launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
60 // 启动指定的Intent的Activity
61 PendingIntent intent = PendingIntent.getActivity(context, 0, launchIntent, 0);
62 // 监听点击事件
63 updateView.setOnClickPendingIntent(R.id.SmallBase, intent);
64 return updateView;
65 }
66}
67
68
他有四个方法:onDeleted、onEnabled、onDisabled、onUpdate,我们这里只实现了最主要的onUpdate方法,他在周期更新的时候调用。每次调用就用appWidgetManager来更新Widget(生成一个RemoteView)。appWidgetManager是系统生成的用于管理Widget的对象,我们不需要进行管理,它会向AppWidgetProvider发通知,他会更新Widget的UI。
(5) AndroidManifest.xml
1<?xml version="1.0" encoding="utf-8"?>
2<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3 package="cn.vaga.today"
4 android:versionCode="1"
5 android:versionName="1.0">
6 <application android:icon="@drawable/icon" android:label="@string/app_name_small">
7 <!-- 订阅指定的BroadcastReceiver -->
8 <receiver android:label="@string/app_name_small" android:name=".TodayDateSmall">
9 <intent-filter>
10 <!-- 就只处理更新的广播 -->
11 <action android:name="android.appwidget.action.APPWIDGET_UPDATE"></action>
12 </intent-filter>
13 <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_small"></meta-data>
14 </receiver>
15 </application>
16 <uses-sdk android:minSdkVersion="7" />
17
18</manifest>
在这里注册AppWidgetRecever指定其处理的Intent的Action为android.appwidget.action.APPWIDGET_UPDATE。当然还要个AppWidgetRecever指定它的描述文件
<meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_small"></meta-data>,这是很必要的,否则Android也不会知道这个Widget到底是如何定义的了。