桌面部件是一种利用AppWidget框架将应用程序的某个部件摆放在桌面的组件。
要为程序定义桌面组件,首先要在程序的res/xml目录下新建一个XML文件来对桌面部件进行描述(桌面部件描述文件):
【注】这里是做一个显示时间的桌面部件。
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="146dip"
android:minHeight="72dip"
android:updatePeriodMillis="1000"
android:initialLayout="@layout/digitalclock"
/>
android:initialLayout="@layout/digitalclock"指定了桌面部件使用的布局文件。
下面是一个桌面部件的高度或宽度所占的单元格数换算最小尺寸的公式:
最小尺寸 = (单元格数*74)-2 (单位:dip)
AppWidget框架是通过广播Intent的方式来对桌面部件进行控制的,所以在AndroidManifest.xml文件中应该有一个广播接收器。AppWidget框架提供了一个继承子BroadcastProvider的AppWidgetProvider类。
AppWidgetProvider的回调方法:
onDeleted:一个或多个桌面部件被删除时调用此方法
onUpdate:每当周期跟新时间到了以后就会调用此方法
....
桌面布局的布局文件(可修改main.xml)
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/showtime"
android:textSize="20px"
android:textStyle="bold"
android:textColor="#FFFFFFFF"
android:background="@drawable/bg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
bg为一个*.9.png文件文件,可以根据定义的大小自动调整图片的大小。
接下来是定义AppWidgetProvider了:
public class TestAppWidget extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// super.onUpdate(context, appWidgetManager, appWidgetIds);
context.startService(new Intent(context, UpdateService.class));
}
public static class UpdateService extends Service {
@Override
public void onStart(Intent intent, int startId) {
// 构造一个美国东部时间的Time对象
Time estTime = new Time("EST");
// 将时间设置为当前
estTime.setToNow();
// RemoteViews是一个描述可在其他进程运行的部件的类,其构造方法需要传入 部件的布局文件以及
// 所在的包的包名
RemoteViews updateViews = new RemoteViews(this.getPackageName(),
R.layout.digitalclock);
updateViews.setTextViewText(R.id.showtime, estTime.format("%H:%M"));
// ComponentName用来表示应用程序中某个组件的完整名字
ComponentName timeWidget = new ComponentName(this,
TestAppWidget.class);
// AppWidgetManager负责桌面部件的管理
AppWidgetManager manager = AppWidgetManager.getInstance(this);
// 通过updateAppWidget传入修改好的RemoteViews对象
manager.updateAppWidget(timeWidget, updateViews);
// super.onStart(intent, startId);
}
public IBinder onBind(Intent arg0) {
return null;
}
}
}
最后要在AndroidManifest.xml文件中进行注册:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.shutao.testwidger"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon"
android:label="@string/app_name">
<!-- 定义一个广播的接受者,intent-filter表示接收的Action为 APPWIDGET_UPDATE的广播-->
<receiver
android:name="TestAppWidget"
android:label="@string/app_name">
<intent-filter>
<action
android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<!-- meta-data的name属性指定了元数据类型为android.appwidget.provider
而android:resource指定了桌面部件的描述文件 -->
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/testappwidget"
/>
</receiver>
<service android:name=".TestAppWidget$UpdateService"/>
</application>
<uses-sdk android:minSdkVersion="3"/>
</manifest>