Android——AppWidgetProvider應用



What is App Widget?

在手機桌面上放置的控件,即Android的桌面組件

AppWidgetProviderInfo
public class
AppWidgetProviderInfo
extends Object
implements Parcelable

Describes the meta data for an installed AppWidget provider. The fields in this class correspond to the fields in the <appwidget-provider> xml tag.


AppWidgetProvider

public class
AppWidgetProvider
extends BroadcastReceiver

A convenience class to aid in implementing an AppWidget provider. Everything you can do with AppWidgetProvider, you can do with a regularBroadcastReceiver. AppWidgetProvider merely parses the relevant fields out of the Intent that is received in onReceive(Context,Intent), and calls hook methods with the received extras.

創建一個簡單的App Widget的基本步驟:


① 在res文件夾下創建一個xml文件夾,裏面創建一個xml文件(這裏創建了一個test_appwidget_info.xml文件)用於提供元數據:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="200dp"
    android:minHeight="80dp"
    android:updatePeriodMillis="10000"
    android:initialLayout="@layout/test_appwidget"
 >
</appwidget-provider>

其中的test_appwidget爲App Widget的佈局文件,在第二步創建。

② 創建App Widget的佈局文件test_appwidget.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView
	android:id="@+id/widgetId"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="This is an AppWidget"
    android:background="#000"
    />
</LinearLayout>


③ 創建一個類繼承AppWidgetProvider並覆蓋裏面的幾個常用的方法:

onDeleted(Context context, int[] appWidgetIds) 刪除App Widget是調用此方法
onDisabled(Context context) 最後一個App Widget實例刪除後調用此方法
onEnabled(Context context) App WIdget實例第一次被創建是調用此方法
onReceive(Context context, Intent intent) 接收廣播事件
onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) 到達指定更新時間或用戶向桌面添加了App Widget時調用此方法
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;

public class TestAppWidgetProvider extends AppWidgetProvider{

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		System.out.println("onUpdate");
		super.onUpdate(context, appWidgetManager, appWidgetIds);
	}
	@Override
	public void onDeleted(Context context, int[] appWidgetIds) {
		System.out.println("onDeleted");
		super.onDeleted(context, appWidgetIds);
	}
	@Override
	public void onDisabled(Context context) {
		System.out.println("onDisabled");
		super.onDisabled(context);
	}
	@Override
	public void onEnabled(Context context) {
		System.out.println("onEnabled");
		super.onEnabled(context);
	}
}


④ 在AndroidManifest.xml文件中聲明一個receiver,注意intent和meta-data子標籤的設置:

<receiver android:name=".TestAppWidgetProvider">
	<intent-filter>
		<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
	</intent-filter>
	<meta-data android:name="android.appwidget.provider"
		android:resource="@xml/test_appwidget_info" />
</receiver>

PendingIntent

public final class
PendingIntent
extends Object
implements Parcelable

A description of an Intent and target action to perform with it. Instances of this class are created with getActivity(Context, int, Intent, int),getBroadcast(Context, int, Intent, int), getService(Context, int, Intent, int); the returned object can be handed to other applications so that they can perform the action you described on your behalf at a later time.

RemoteViews

public class
RemoteViews
extends Object
implements Parcelable LayoutInflater.Filter

A class that describes a view hierarchy that can be displayed in another process. The hierarchy is inflated from a layout resource file, and this class provides some basic operations for modifying the content of the inflated hierarchy.

使用PendingIntent和RemoteViews對App Widget綁定監聽器:

創建PendingIntent的基本方法:

getActivity(Context context, int requestCode, Intent intent, int flags)
getBroadcast(Context context, int requestCode, Intent intent, int flags)
getService(Context context, int requestCode, Intent intent, int flags)

在創建一個簡單的App Widget的基本步驟基礎之上進行一下操作:

① 在test_appwidget.xml文件中添加一個按鈕

<Button
	android:id="@+id/widgetButtonId"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content"
	android:text="click me?"
	/>


② 通過RemoteViews在TestAppWidgetProvider的onUpdate()方法中爲Botton綁定監聽器

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
		int[] appWidgetIds) {
	for (int i = 0; i < appWidgetIds.length; i++) {
		//這裏TargetActivity爲Intent跳轉到的Activity,這個Activity類需要另外編寫,在第三步創建
		Intent intent = new Intent(context,TargetActivity.class);
		PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
		RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.test_appwidget);
		//PendingIntent爲事件觸發是所要執行的PendingIntent
		remoteViews.setOnClickPendingIntent(R.id.widgetButtonId, pendingIntent);
		appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);
	}
	super.onUpdate(context, appWidgetManager, appWidgetIds);
}


③ 創建一個TargetActivity用作Botton的跳轉到的Activity

接收來自AppWidget中的廣播消息:

在創建一個簡單的App Widget的基本步驟基礎之上進行一下操作:

1、 在AndroidManifest.xml文件中爲TestAppWidgetProvider註冊新的intent

<receiver android:name=".TestAppWidgetProvider">
	<intent-filter>
		<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
	</intent-filter>
	<intent-filter>
		<action android:name="com.test.UPDATE_APP_WIDGET"/>
	</intent-filter>
	<meta-data android:name="android.appwidget.provider"
		android:resource="@xml/test_appwidget_info" />
</receiver>


2、 在TestAppWidgetProvider中定義一個常量:

private static final String UPDATE_ACTION = "com.test.UPDATE_APP_WIDGET";


3、 在TestAppWidgetProvider的onUpdate()方法中使用getBroadcast()方法創建一個PendingIntent;併爲AppWidget當中的控件註冊監聽器

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
		int[] appWidgetIds) {
	Intent intent = new Intent();
	intent.setAction(UPDATE_ACTION);
	PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
			intent, 0);
	RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
			R.layout.test_appwidget);
	remoteViews.setOnClickPendingIntent(R.id.widgetButtonId, pendingIntent);
	appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
}


4、 在onReceive()方法中接收所需要的廣播:

public void onReceive(Context context, Intent intent) {
	super.onReceive(context, intent);
	String action = intent.getAction();
	if (UPDATE_ACTION.equals(action)) {
		System.out.println(UPDATE_ACTION);
	}
}
如果需要改變App Widget中控件的狀,可以在TestAppWidgetProvider的onReceive()方法中通過RemoteViews對象去改變:
@Override
public void onReceive(Context context, Intent intent) {
	String action = intent.getAction();
	if (UPDATE_ACTION.equals(action)) {
		RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
				R.layout.test_appwidget);
		remoteViews.setTextViewText(R.id.widgetTextId, "change");
		AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
		//區分:RemoteViews代表App Widget中的所有空間,而ComponentName代表整個App Widget對象
		ComponentName componentName = new ComponentName(context,ExampleAppWidgetProvider.class);
		appWidgetManager.updateAppWidget(componentName, remoteViews);
	} else {
		super.onReceive(context, intent);
	}
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章