`

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

阅读更多

 

一、 AppWidget

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

No.

类名称

描述

1

AppWidgetProvider

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

2

AppWidgetProviderInfo

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

3

AppWidgetHostView

创建 AppWidget View 显示,此为真正的 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 组件的操作相对应,通过文档可以发现 AppWidgetProvider BroadcastReceiver 的子类,所以在使用时需要在 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 时触发

注:

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

2 、对于 onDisabled onEnabled 方法,因为 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>

 

分享到:
评论
Global site tag (gtag.js) - Google Analytics