当前位置: 代码迷 >> Android >> Android学习10-Android组件通讯 (8) 桌面显示组件:AppWidget
  详细解决方案

Android学习10-Android组件通讯 (8) 桌面显示组件:AppWidget

热度:111   发布时间:2016-05-01 12:59:20.0
Android学习10-----Android组件通信 (8) 桌面显示组件:AppWidget

?

一、AppWidget

在使用Android手机时,用户经常会将一些常使用的软件拖放到桌面上以方便操作。这时就需要使用AppWidget组件,在android.appwidget包综合那个定义了5个核心的操作类。

No.

类名称

描述

1

AppWidgetProvider

定义了AppWidget的基本操作,需要通过子类进行设置

2

AppWidgetProviderInfo

AppWidget组件的元数据提供者,如组件的大小、更新时间等

3

AppWidgetHostView

创建AppWidgetView显示,此为真正的View,与之对应的还有RemoteView

4

AppWidgetHost

监听AppWidget的服务以及创建AppWidgetHostView

5

AppWidgetManager

用于更新相应的AppWidget

由于AppWidget要在桌面上显示界面,而这个界面又要通过AppWidgetManager程序进行控制,所以还需要使用一个android.widget.RemoveViews类,此类的主要功能是描述一个View的显示实体,RemoveViews会通过进程间通信机制传递个AppWidgetHost

这里的RemoteViews只是把一个进程的控件嵌入到另外一个进程中显示的一个方法,所有的事件处理操作依然在原始进程中,而AppWidget需要依靠RemoveViews来完成显示内容的更新操作,RemoveViews常用方法有:

No.

方法

描述

1

Public RemoteViews(String packageName,int layoutId)

创建新的RemoveViews组件,并指定所需要的布局管理器文件

2

Public void addView(int viewId,RemoteViews nestedView)

RemoveViews增加一个组件

3

Public void setXxx(int viewId,String methodName,Xxx value)

设置指定内容,如setBoolean()setImageViewResource()setTextViewText()

4

Public void setOnClickPendingIntent(int viewId,PendingIntent pendingIntent)

设置单击事件触发之后要操作的PendingIntent对象

5

Public void setProgressBar(int viewId,int max,int progress,Boolean indeterminate)

设置要操作的ProgressBar组件

除了RemoveViews类作为远程View之外,Activity程序中也提供了对应的AppWidgetProvider类用于与RemoveView组件的操作相对应,通过文档可以发现AppWidgetProviderBroadcastReceiver的子类,所以在使用时需要在AndroidManifest.xml中配置receive节点,AppWidgetProvider类中也提供了像Activity类中的生命周期控制方法,其方法如下:

No.

方法

描述

1

Public void onDeleted(Context context,int[] appWidget)

删除AppWidget时触发

2

Public void onDisabled(Context context)

当最后一个AppWidget删除时触发

3

Public void onEnabled(Context context)

当第一个AppWidget启动时触发

4

Public void onReceive(Context context,Intent intent)

接受广播事件

5

Public void onUpdate(Context context,

AppWidgetManager appWidgetManger,

int[] appWidgetIds)

当指定的更新时间到达或者用户添加AppWidget时触发

注:

1onUpdate方法决定了AppWidget组件的显示功能以及远程AppWidget的事件处理绑定,当组件更新时,需要使用AppWidgetManager类更新远程AppWidget组件(严格说是RemoveViews),而AppWidgetManager会广播Action名称是“android.appwidget.action.APPWIDGET_UPDATE”的Intent

2、对于onDisabledonEnabled方法,因为android中一个程序可以同时在桌面上设置多个显示的组件。

MyAppWidget.java

package com.iflytek.demo;import android.appwidget.AppWidgetManager;import android.appwidget.AppWidgetProvider;import android.content.Context;import android.content.Intent;public class MyAppWidget extends AppWidgetProvider {	@Override	public void onDeleted(Context context, int[] appWidgetIds) {// 删除时触发		System.out.println("*** MyAppWidget onDeleted");		super.onDeleted(context, appWidgetIds);	}	@Override	public void onDisabled(Context context) {// 删除最后一个触发		System.out.println("*** MyAppWidget onDisabled");		super.onDisabled(context);	}	@Override	public void onEnabled(Context context) {// 启动第一个时触发		System.out.println("*** MyAppWidget onEnabled");		super.onEnabled(context);	}	@Override	public void onReceive(Context context, Intent intent) {// 处理广播		System.out.println("*** MyAppWidget onReceive");		super.onReceive(context, intent);	}	@Override	public void onUpdate(Context context, AppWidgetManager appWidgetManager,			int[] appWidgetIds) {// 更新时触发		System.out.println("*** MyAppWidget onUpdate");		super.onUpdate(context, appWidgetManager, appWidgetIds);	}}

上面只是对AppWidgetProvider中的几个与生命周期有关的方法进行覆写,但是如果想让一个AppWidget程序进行显示,还需要定义一个设置桌面显示的配置文件,该文件保存在res\xml文件夹中。
xdwang_appwidget.xml.xml

<?xml version="1.0" encoding="utf-8"?><appwidget-provider 	xmlns:android="http://schemas.android.com/apk/res/android"	android:minHeight="80px"	android:minWidth="300px"	android:updatePeriodMillis="6000"	android:initialLayout="@layout/xdwang_appwidget"></appwidget-provider>

xdwang_appwidget.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <ImageView        android:id="@+id/img"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:src="@drawable/ic_launcher" />    <Button        android:id="@+id/but"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_gravity="center_horizontal"        android:text="王旭东" /></LinearLayout>

AndroidManifest.xml

<receiver android:name=".MyAppWidget" >            <!-- AppWidget更新时触发 -->            <intent-filter >                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />            </intent-filter>            <!-- 定义AppWidget的元数据 ,android:name:AppWidget提供者,android:resource程序要使用的配置信息 -->            <meta-data                android:name="android.appwidget.provider"                android:resource="@xml/xdwang_appwidget" />        </receiver>

?

二、使用AppWidget跳转到Activity进行操作

前面我们简单描述了AppWidget程序的配置,但是在实际情况下,很多时候需要单击桌面显示的AppWidget可以进入一个Activity程序进行更加复杂的操作处理。这里我们首先来看看AppWidgetManager提供的方法:

No.

方法

描述

1

Public void updateAppWidget(int appWidgetId,RemoveViews views)

更新指定的AppWidget组件

2

Public void updateAppWidget(ComponentName provider,

RemoveViews views)

更新指定的AppWidget组件

3

Public void updateAppWidget(int[] appWidgetIds,RemoveViews views)

更新指定的AppWidget组件

4

Public static AppWidgetManager getInstance(Context context)

取得一个AppWidgetManager的实例

MyAppWidget.java

package com.iflytek.demo;import android.app.PendingIntent;import android.appwidget.AppWidgetManager;import android.appwidget.AppWidgetProvider;import android.content.Context;import android.content.Intent;import android.widget.RemoteViews;public class MyAppWidget extends AppWidgetProvider {	@Override	public void onUpdate(Context context, AppWidgetManager appWidgetManager,			int[] appWidgetIds) {// 更新时触发		for (int x = 0; x < appWidgetIds.length; x++) {// 更新所有显示的AppWidget			Intent intent = new Intent(context, AppWidget02Activity.class);// 设置Activity			PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,					intent, PendingIntent.FLAG_UPDATE_CURRENT);// 设置准备执行的Intent			RemoteViews remote = new RemoteViews(context.getPackageName(),					R.layout.xdwang_appwidget);// 更新要操作的RemoveViews			remote.setOnClickPendingIntent(R.id.but, pendingIntent);			appWidgetManager.updateAppWidget(appWidgetIds[x], remote);// 更新远程的视图		}	}}

三、使用AppWidget进行广播
MyAppWidget.java

package com.iflytek.demo;import android.app.PendingIntent;import android.appwidget.AppWidgetManager;import android.appwidget.AppWidgetProvider;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.widget.RemoteViews;public class MyAppWidget extends AppWidgetProvider {	@Override	public void onReceive(Context context, Intent intent) {		if ("com.iflytek.action.MYAPPWIDGET_UPDATE".equals(intent.getAction())) {// 判断是否是指定的Action			RemoteViews remote = new RemoteViews(context.getPackageName(),					R.layout.xdwang_appwidget);// 定义RemoveViews			remote.setImageViewResource(R.id.img, R.drawable.ic_launcher);// 设置图片			remote.setTextViewText(R.id.but, "王旭东改变");// 更新组件文字			AppWidgetManager appWidgetManager = AppWidgetManager					.getInstance(context);// 取得AppWidgetManager			ComponentName componentName = new ComponentName(context,					MyAppWidget.class);// 定义使用的组件			appWidgetManager.updateAppWidget(componentName, remote);// 更新组件		} else {			super.onReceive(context, intent); // 如果不写此代码,表示无法调用onUpdate()		}	}	@Override	public void onUpdate(Context context, AppWidgetManager appWidgetManager,			int[] appWidgetIds) {		Intent intent = new Intent();// 设置操作要执行的Intent		intent.setAction("com.iflytek.action.MYAPPWIDGET_UPDATE");		PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,				intent, PendingIntent.FLAG_UPDATE_CURRENT);// 设置准备执行的Intent		RemoteViews remote = new RemoteViews(context.getPackageName(),				R.layout.xdwang_appwidget);// 定义要操作的RemoveViews		remote.setOnClickPendingIntent(R.id.but, pendingIntent);		appWidgetManager.updateAppWidget(appWidgetIds, remote);// 更新远程视图	}}

AndroidManifest.xml

<receiver android:name=".MyAppWidget" >            <intent-filter >                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />            </intent-filter>            <intent-filter >                <action android:name="com.iflytek.action.MYAPPWIDGET_UPDATE" />            </intent-filter>            <meta-data                android:name="android.appwidget.provider"                android:resource="@xml/xdwang_appwidget" />        </receiver>

?

  相关解决方案