所谓桌面小控件,就是指能直接显示在Android系统桌面的小程序,比如模拟时钟等。桌面小控件是通过Broadcast的形式来进行控制的,每个桌面小控件都对应一个BroadcastReceiver。Android提供了一个AppWidgetProvider类,它是BroadcastReceiver的子类,开发者只要开发一个继承AppWidgetProvider的子类,并重写其不同状态的生命周期方法即可。AppWidgetProvider提供如下四个不同的生命周期方法:
onUpdate:负责更新桌面控件的方法;实现桌面控件通常会考虑重写该方法。
onDeleted:当一个或多个桌面小控件被删除时回调该方法。
onEnabled:当接收到ACTION_APPWIDGET_ENABLED 广播时回调该方法。
onDisabled:当接收到ACTION_APPWIDGET_DISABLED广播时回调该方法。
开发桌面小控件步骤:
1、创建一个RemoteViews对象,创建该对象时可以指定加载指定的界面布局文件。
2、如果需要改变上一步所加载的界面布局文件的内容,可通过RemoteViews对象进行修改。一般来说,界面中主要包含ImageView和TextView两种组件。
3、创建一个ComponentName对象。
4、调用AppWidgetManager的updateAppWidget方法更新桌面小控件。
下面以开发数字时钟为例(代码原型来源疯狂讲义):
AppWidgetProvider子类:
package com.home;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.widget.RemoteViews;
public class DigitClock extends AppWidgetProvider {
private Timer timer = new Timer();
private AppWidgetManager appWidgetManager;
private Context context;
// 将0~9的液晶数字图片定义成数组
private int[] digits = new int[] { R.drawable.image0, R.drawable.image1,
R.drawable.image2, R.drawable.image3, R.drawable.image4,
R.drawable.image5, R.drawable.image6, R.drawable.image7,
R.drawable.image8, R.drawable.image9 };
// 将显示小时、分钟、秒钟的ImageView定义成数组
private int[] digitViews = new int[] { R.id.digit_image1,
R.id.digit_image2, R.id.digit_image3, R.id.digit_image4,
R.id.digit_image5, R.id.digit_image6 };
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
this.appWidgetManager = appWidgetManager;
this.context = context;
// 定义计时器
timer = new Timer();
// 启动周期性调度
timer.schedule(new TimerTask() {
@Override
public void run() {
// 发送空消息,通知界面更新
handler.sendEmptyMessage(0x123);
}
}, 0, 1000);
}
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 0x123) {
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.digit);
// 定义SimpleDateFormat对象
SimpleDateFormat df = new SimpleDateFormat("HHmmss");
// 将当前时间格式化成HHmmss的形式
String timeStr = df.format(new Date());
for (int i = 0; i < timeStr.length(); i++) {
// 将第i个数字字符转换成对应的数字
int num = timeStr.charAt(i) - 48;
// 将第i个图片设为对应的液晶数字图片
views.setImageViewResource(digitViews[i], digits[num]);
}
// 将AppWidgetProvider子类实例包装成ComponentName对象
ComponentName componentName = new ComponentName(context,
DigitClock.class);
// 调用AppWidgetManager将remoteViews添加到ComponentName中
appWidgetManager.updateAppWidget(componentName, views);
super.handleMessage(msg);
}
}
};
}
布局文件(digit.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ImageView
android:id="@+id/digit_image1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/digit_image2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/digit_image7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:src="@drawable/image" />
<ImageView
android:id="@+id/digit_image3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/digit_image4"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/digit_image8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:src="@drawable/image" />
<ImageView
android:id="@+id/digit_image5"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/digit_image6"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
配置receiver:
<receiver
android:name="com.home.DigitClock"
android:label="@string/app_name" >
<!-- 将该BroadcastReceiver当成桌面下控件 -->
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<!-- 指定桌面小控件的meta-data -->
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/appwidget_provider" />
</receiver>
appwidget_provide.xml:
<?xml version="1.0" encoding="utf-8"?>
<!--
指定该桌面组件的基本配置信息:
minWidth:桌面小控件的最小宽度
minHeight:桌面小控件的最小高度
updatePeriodMillis:更新频率
initialLayout:初始时显示的布局
-->
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/digit"
android:minHeight="70dp"
android:minWidth="150dp"
android:updatePeriodMillis="1000" />