Android平台上在桌面上所放置的一种小控件
AppWidgetProviderInfo对象:
定义App Widget的一些信息,为App Widget提供元数据,包括App Widget布局文件的指定,更新频率等数据。
这个对象被定义在XML文件当中,其相对于一个Config配置“文件”.
AppWidgetProvider:
继承自BroadcastReicever广播接收器。
定义了App Widget的基本生命周期的回调函数.
在res/xml文件夹当中定义描述AppWidgetProviderInfo的xml文件。
例:…\res\xml\appwidget_info.xml
updatePeriodMillis为更新的毫秒数、initialLayout为初始化的widget布局;
previewImage为该app widget的预览图,在桌面小部件选择时显示;
resizeMode:app widget 在水平和垂直方向是否可以调整大小。
定义App Widget展示时的布局文件appwidget_layout
例:…\res\layout\appwidget_layout.xml
onUpdate:在到达指定的更新时间之后或者当用户向桌面添加App Widget时会调用该方法
onDeleted:在App Widget被删除时,会调用该方法
onEnable:当一个App Widget的实例第一次被创建时,会调用该方法
onDisable:当最后一个App Widget实例被删除后,会调用该方法
onReceive:监听/接收广播事件,可用于处理控件的点击事件等
(桌面上可以有多个同样的app widget)
例:
public class MyAppWidgetProvider extends AppWidgetProvider {
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
}
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
}
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
}
}
因AppWidgetProvider又继承自BroadcastReceiver,所以需要在AndroidManifest中注册:
其中action是引用android自定义的action,meta-data为元数据:resource为说明该App Widget 的配置信息的xml文件,name必须是android.appwidget.provider。
>使用App Widget布局中的控件其中涉及到了PendingIntent,RemoteViews..
Pending:待处理的。PendingIntent 可以看作为一种“留待日后处理”的意图,是对Intent的一种包装,创建之后并不马上使用,一旦某种触发事件的发生,意图才马上执行。
创建PendingIntent对象的三个静态方法:
根据PeningIntent具体发送/启动(广播/Activity/服务)来选择对应的一个静态方法来创建PendingIntent对象。
RemoteViews:远程控件。App Widget里的控件和主程序不在同一进程中,所以App Widget里的控件相对于一种远程控件。
由于AppWidget的Button不与主程序在同一进程中,所以无法按照之前惯用的方法给Button绑定监听器。
为AppWidget的Button绑定监听器:
新方法:remoteViews.setOnClickPendingIntent(R.id.widget_button, pendingIntent);
第一个参数为AppWidget的Button的id,第二参数为PendingIntent对象。
当Button被点击时,会引起pendingIntent的执行。
例:重新实现AppWidgetProvider:点击Button时启动Activity
public class MyAppWidgetProvider extends AppWidgetProvider {
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
Log.i("z","onReceive");
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
// appWidgetMahager:管理app widget
// appWidgetIds : appWidget的id数组(桌面可放置多个同样的小部件)
for (int i= 0;i< appWidgetIds.length;i++){
//给每一个小部件的按钮绑定监听器
Log.i("z",appWidgetIds[i]+" ");
//创建一个Intent对象
Intent intent = new Intent(context,MainActivity.class);
//包装成一个PendingIntent对象
PendingIntent pendingIntent = PendingIntent.getActivity(context,0,intent,0);
//得到RemoteViews对象
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.appwidget_layout);
//给app widget中的Button绑定监听器
remoteViews.setOnClickPendingIntent(R.id.widget_button,pendingIntent);
//更新app widget
appWidgetManager.updateAppWidget(appWidgetIds[i],remoteViews);
}
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
Log.i("z","onDeleted");
}
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
Log.i("z","onEnabled");
}
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
Log.i("z","onDisabled");
}
}
在AndroidManifest当中为AppWidgetProvider注册新的intent-filter,配置所要接收的广播行为。AppWidgetProvider本质上是一个广播接收器。
使用getBroadcast(…)方法创建一个发送广播PendingIntent。
为AppWidget当中的控件注册处理器,用来触发发送广播的行为。
在onReceive方法当中接收来自AppWidget发送的广播消息,并执行自己的业务逻辑,使用RemoteViews对象更新App Widget当中的控件状态。
AppWidgetProvider的运行机制:通过onReceive来接收广播,接收到特定的系统内置广播时来调用onUpdate(..)等生命周期的回调方法,由onReceive来调用生命周期函数。
例:重新在AndroidMainfest注册AppWidgerProvider:
“android.appwidget.action.APPWIDGET_UPDATE”:系统自带广播,用来接收后回调声明周期函数。
“my.appwidget.Text_UPDATE”:自定义广播,用来接收后进行对TextView的操作。
重新实现AppWidgetProvider:
public class MyAppWidgetProvider extends AppWidgetProvider {
private static final String TEXT_UPDATE = "my.appwidget.Text_UPDATE";
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if(intent!=null&& TextUtils.equals(TEXT_UPDATE,intent.getAction())){
Log.i("z","onReceiveTextUpdate");
//获取app widget的所有控件
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.appwidget_layout);
//设置TextView的文本
remoteViews.setTextViewText(R.id.widget_text,"Changed Text");
//获取app widget的管理器
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
//获取app widget的对象
ComponentName componentName = new ComponentName(context,MyAppWidgetProvider.class);
//管理器更新app widget
appWidgetManager.updateAppWidget(componentName,remoteViews);
}
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
// appWidgetMahager:管理app widget
// appWidgetIds : appWidget的id数组(桌面小部件可重复放置多个小部件)
for (int i= 0;i< appWidgetIds.length;i++){
Log.i("z",appWidgetIds[i]+" ");
//创建一个发送广播的Intent对象,并设置action
Intent intent = new Intent();
intent.setAction(TEXT_UPDATE);
//包装成一个PendingIntent对象,执行时会发送一个广播。
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0,intent,0);
//得到RemoteViews对象
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.appwidget_layout);
//给app widget中的Button绑定监听器
remoteViews.setOnClickPendingIntent(R.id.widget_button,pendingIntent);
//更新app widget
appWidgetManager.updateAppWidget(appWidgetIds[i],remoteViews);
}
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
Log.i("z","onDeleted");
}
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
Log.i("z","onEnabled");
}
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
Log.i("z","onDisabled");
}
}