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界面进行交互。
1
package cn.vaga.today;
2
3
import java.util.Calendar;
4
5
import android.app.PendingIntent;
6
import android.appwidget.AppWidgetManager;
7
import android.appwidget.AppWidgetProvider;
8
import android.content.ComponentName;
9
import android.content.Context;
10
import android.content.Intent;
11
import android.graphics.Canvas;
12
import android.text.format.Time;
13
import android.widget.RemoteViews;
14
15
public 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到底是如何定义的了。