Android之初學Appwidget

本次開始學習App Widgets

App Widgets 是一個小型應用程序的View  他可以嵌入到其他應用程序中(如 桌面程序並且可以得到週期性刷新。

在創建App Widget之前需要了解以下幾個概念

AppWidgetProviderInfo對象

      它是對App Widget 元數據的一個描述,譬如 AppWidget的佈局,刷新頻率,以及   AppWidgetProvider 類  這些元數據都是定義在XML中。

AppWidgetProvider 類的實現

       對於App Widget定義了(回調接口)一些基本的方法,這些方法都是基於廣播事件    (broadcast events ),,通過它,當App Widget更新,創建,無       效,卸載時,你可以接收廣播。

View layout

       爲App Widget定義初始佈局,用XML來佈局

       另外,你可以爲App Widget 實現一個配置的Activity,這是一個可選擇的Activity,在用戶添加你的App Widget 準備創建時允許他修改或者配           置App Widget 


下面我們就開始創建一個App Widget

① 在Manifest聲明App Widget

     首先,在AndroidManifest.xml中聲明  AppWidgetProvider  

 

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

<receiver>元素需要android:name 屬性,AppWidgetProvider作爲引用

<intent-filter>  元素務必要包含 <action>元素 然後Action中要有android:name 屬性,這個屬性需要指定能接

  收 ACTION_APPWIDGET_UPDATE 廣播的AppWidgetProvider,也就是ExampleAppWidgetProvider 這個廣播必須唯一 必須明確

  聲明,因爲AppWidgetManager會自動的發送所有其他應用程序的廣播給AppWidgetProvider,所以很重要。

<meta-data> 元素指定AppWidgetProviderInfo資源需要以下屬性

  Android:name -指定了元數據的名字,用android.appwidget.provider代表數據是AppWidgetProviderInfo描述。

  Android:resource -引用AppWidgetProviderInfo 資源的位置

  總之一句話:在AndroidManifest.xml主要聲明概念中AppWidgetProvider 和AppWidgetProviderInfo

②添加AppWidgetProviderInfo元數據

  AppWidgetProviderInfo爲AppWidgeet定義了一些最基本的數據,譬如佈局的最小尺寸,初始化佈局資源,怎樣更新App Widget

  以及在創建app Widget時的可配置Activity(可選

  要定義一個AppWidgetProviderInfo對象可以用XML資源文件定義,保存在res/xml/自己的文件名 ,XML文件中用一個單一的元

  素<appwidget-provider> 請看下面的例子:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="294dp"
    android:minHeight="72dp"
    android:updatePeriodMillis="86400000"
    android:previewImage="@drawable/preview"
    android:initialLayout="@layout/example_appwidget"
    android:configure="com.example.android.ExampleAppWidgetConfigure" 
    android:resizeMode="horizontal|vertical">
</appwidget-provider>


  initialLayout:指定App Widget佈局資源文件

  Configure:在創建App Widget時爲他配置屬性的activity

  updatePeriodMillis: appwidget更新頻率

③ 創建App Widget 佈局

  你必須爲你的App Widget定義個初始化佈局文件,可以將佈局文件放在 res/layout/directory。 你可以設計你的App Widget用下面列出來

  的View對象,但是在你設計開始之前,請你熟讀

App Widget Design Guidelines. 

  如果你熟悉XML Layouts ,那麼創建一個App Widget將會是簡單的, 然而,你必須意識到App Widget佈局是基於 RemoteViews ,它

  並不是支持每一種layout和View widget。

  一個RemoteView對象只能支持下面幾種layout佈局類:

 FrameLayout  LinearLayout   RelativeLayout

  支持下面幾種widget 類:

 AnalogClock   Button  Chronometer  ImageButton  ImageView  ProgressBar  TextView  ViewFlipper  ListView  GridView

 StackView  AdapterViewFlipper

 PS:這些類的繼承類也是不被支持的。

 

下面是我本次寫的demo中的Appwidget

     功能很簡單隻爲初步理解AppWidget ,響應Appwidget上按鈕事件

package com.manymorere.appwidget;

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 ExampleAppWidgetProvider extends AppWidgetProvider{

	private static final String ACTION = "com.manymore.appwidget"; 
	private int id;
	@Override
	public void onDeleted(Context context, int[] appWidgetIds) {
		
 		System.out.println("onDeleted");

 		super.onDeleted(context, appWidgetIds);
	}

	
	@Override
	public void onDisabled(Context context) {
		// TODO Auto-generated method stub
		System.out.println("onDisabled");

		super.onDisabled(context);
	}

	
	@Override
	public void onEnabled(Context context) {
		// TODO Auto-generated method stub
		System.out.println("onEnabled");

		super.onEnabled(context);
	}

	
	@Override
	public void onReceive(Context context, Intent intent) {
 		System.out.println("onReceive");

 		// 自己定義的ACTION
 		if(intent.getAction().equals(ACTION))
 		{
 			RemoteViews remoteView = new RemoteViews(context.getPackageName(),R.layout.appwidget_layout);
 			remoteView.setCharSequence(R.id.button, "setText", "22222222222222");
 			AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
 			ComponentName componentName = new ComponentName(context, ExampleAppWidgetProvider.class);
 			
 			appWidgetManager.updateAppWidget(componentName	, remoteView);
 			
 			
 			System.out.println("收到自定義ACTION");
 			
 		}else{
 			super.onReceive(context, intent);
 		}
		
		
	}

    
	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		
		int N = appWidgetIds.length;
		
		for(int i = 0; i<N; i++)
		{
			int appWidgetId = appWidgetIds[i];
			
			Intent intent = new Intent(ACTION);
		
			PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
			
			RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.appwidget_layout);
		
			remoteViews.setOnClickPendingIntent(R.id.button, pendingIntent);
		
			appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
			
			System.out.println(appWidgetId);
 
		}

		super.onUpdate(context, appWidgetManager, appWidgetIds);
	}
	
	

}

         每次添加Appwidget實例 都會調用onUpdate()方法 然後會註冊裏面的Button Onclick事件,當你點擊該按鈕時會發送一個broadcast,

    這個broadcast是自己定義的,然後onReceive方法會收到該broadcast,然後再做出一些反應,我這裏是把修改了TextView上的text。


         由於Appwidget和本身的應用,雖然是在一個程序中,但運行時,它們並不是在一個進程中,所以在在調用方法和修改界面上多少會 

    有點限制,沒有普通的(Activity上對View的一些操作)那麼自由,所以想對Appwidget上的View做一些操作,或者更新Appwidget,一

    般需要用到RemoteViews,AppWidgetManager 同時可能還會用到ComponentName

    個人理解:RemoteViews在創建時主要代表一個Appwidget實例中View的一個集合 ,而ComponentName則代表一個整個Appwidget實例                           Src\appwidgetTest  下載


發佈了61 篇原創文章 · 獲贊 380 · 訪問量 58萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章