Android學習筆記(33)--- Widget中AppWidgetProvider,update更新問題

關於AppWidgetProvider我就不多說了,這個可以去官方文檔看下。

最近因爲碰到一個問題,在xml中使用

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/widget"
    android:minHeight="120dip"
    android:minWidth="120dip"
    android:updatePeriodMillis="5000" >
</appwidget-provider>

裏面的android:updatePeriodMillis中的更新週期不起作用。首先有幾種原因,意思android版本的問題,還有一個是網上都說只能最快30分鐘更新一次,不然的話就使用Service進行更新。下面使用兩種方法來實現:

一、使用廣播來實現

1、既然android:updatePeriodMillis不符合我們的要求,我們可以使用廣播的方式來讓widget按照我們想要的更新週期來更新。

先來看下AppWidgetProvider.java文件:(準對我的一個備忘錄項目:http://blog.csdn.net/moruna/article/details/7895817

public class AppWidget extends AppWidgetProvider {

	private DatabaseHelper dbHelper;
	String[] desk_text;
	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		// TODO Auto-generated method stub
		super.onUpdate(context, appWidgetManager, appWidgetIds);
		//讀取數據庫中的記錄
		dbHelper = new DatabaseHelper(context, "ideal.sql");
		SQLiteDatabase db = dbHelper.getReadableDatabase();
		Cursor cursor = db.query("user", null, null, null, null, null, null);
		int desk_num=0;
		//桌面的便籤只顯示6條記錄
		desk_text = new String[6];
		while(cursor.moveToNext()){
			if(desk_num == 6){
				break;
			}
			String temp_text = cursor.getString(cursor.getColumnIndex("mtext"));
			//控制每條記錄顯示的長度
			if(temp_text.length()>7){
				temp_text=temp_text.substring(0, 7)+"...";
			}
			desk_text[desk_num]=temp_text;
			System.out.println("desk_text[desk_num]"+desk_text[desk_num]);
			desk_num++;			
		}
		db.close();
		final int Num = appWidgetIds.length;
		for (int i = 0; i < Num; i++) {
			int[] mAppWidgetId = appWidgetIds;
			RemoteViews mRemoteViews = new RemoteViews(context.getPackageName(),
					R.layout.widget);
			mRemoteViews.setTextViewText(R.id.desktop_text, array_to_string(desk_text));

			Intent clickIntent = new Intent(context, NoteActivity.class);
			PendingIntent pdIntent = PendingIntent.getActivity(context, 0,
					clickIntent, 0);
			mRemoteViews.setOnClickPendingIntent(R.id.widget_layout, pdIntent);
			appWidgetManager.updateAppWidget(mAppWidgetId, mRemoteViews);
		}
	}
	//onReceive方法用來接收廣播,以便更新桌面的便籤
	
	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		super.onReceive(context, intent);
		if(intent.getAction().equals("com.ideal.note.widget")){
			dbHelper = new DatabaseHelper(context, "ideal.sql");
		SQLiteDatabase db = dbHelper.getReadableDatabase();
		Cursor cursor = db.query("user", null, null, null, null, null, null);
		int desk_num=0;
		desk_text = new String[6];
		while(cursor.moveToNext()){
			if(desk_num == 6){
				break;
			}
			String temp_text = cursor.getString(cursor.getColumnIndex("mtext"));
			if(temp_text.length()>7){
				temp_text=temp_text.substring(0, 7)+"...";
			}
			desk_text[desk_num]=temp_text;
			System.out.println("desk_text[desk_num]"+desk_text[desk_num]);
			desk_num++;			
		}
		db.close();
		}
		RemoteViews mRemoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
		mRemoteViews.setTextViewText(R.id.desktop_text, array_to_string(desk_text));
		AppWidgetManager.getInstance(context).updateAppWidget(new ComponentName(context, AppWidget.class), mRemoteViews);		
	}
	
	//數組轉化爲字符顯示
	public String array_to_string(String[] array){
		String temp_str = "";
		for(int i=0;i<array.length;i++){
			if(array[i]==null){
				break;
			}else {
				temp_str = temp_str+"\n* "+array[i];
			}
		}
		return  temp_str;
	}
}

上面我override了onUpdate和onReceive,其中onUpdate是在爲桌面添加Widget的時候執行,也會在android:updatePeriodMillis="****"(最少30分鐘) 時間滿足之後執行。onReceive是爲了接收那些修改了數據庫之後發來的廣播,以便更新桌面Widget。

在上面的onReceive中可以看到,當

if(intent.getAction().equals("com.ideal.note.widget"))
成歷時便重新讀取數據庫,更新桌面Widget。


2、發送廣播源:

NotoActivity.java爲例子:

Intent mWidgetIntent = new Intent();
				mWidgetIntent.setAction("com.ideal.note.widget");
				NoteActivity.this.sendBroadcast(mWidgetIntent);

3、注意的是,還需要在AndroidManifest.xml進行註冊:

<receiver android:name=".AppWidget"> 
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
                <action android:name="com.ideal.note.widget"/>
            </intent-filter>
            <meta-data  android:name="android.appwidget.provider"
           	android:resource="@xml/appwidget_info"/> 
        </receiver>

這樣便實現了按照需要進行更新桌面widget。

二、使用Timer來更新數據:

public class AppWidget extends AppWidgetProvider {

	private DatabaseHelper dbHelper;
	String[] desk_text;
	Handler mHandler;
	Context mContext;

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		// TODO Auto-generated method stub
		super.onUpdate(context, appWidgetManager, appWidgetIds);
		mContext = context;
		Timer mTimer = new Timer();
		mTimer.scheduleAtFixedRate(new MyTime(context, appWidgetManager), 1,
				60000);
	}

	private class MyTime extends TimerTask {

		RemoteViews mRemoteViews;
		AppWidgetManager mAppWidgetManager;
		ComponentName thisWidget;

		public MyTime(Context context, AppWidgetManager appWidgetManager) {
			this.mAppWidgetManager = appWidgetManager;
			this.mRemoteViews = new RemoteViews(context.getPackageName(),
					R.layout.widget);
			thisWidget = new ComponentName(context, AppWidget.class);

		}

		@Override
		public void run() {
			// TODO Auto-generated method stub

			dbHelper = new DatabaseHelper(mContext, "ideal.sql");
			SQLiteDatabase db = dbHelper.getReadableDatabase();
			Cursor cursor = db
					.query("user", null, null, null, null, null, null);
			int desk_num = 0;
			desk_text = new String[6];
			while (cursor.moveToNext()) {
				if (desk_num == 6) {
					break;
				}
				String temp_text = cursor.getString(cursor
						.getColumnIndex("mtext"));
				if (temp_text.length() > 7) {
					temp_text = temp_text.substring(0, 7) + "...";
				}
				desk_text[desk_num] = temp_text;
				System.out.println("desk_text[desk_num]" + desk_text[desk_num]);
				desk_num++;
			}
			db.close();

			mRemoteViews.setTextViewText(R.id.desktop_text,
					array_to_string(desk_text));

			Intent clickIntent = new Intent(mContext, NoteActivity.class);
			PendingIntent pdIntent = PendingIntent.getActivity(mContext, 0,
					clickIntent, 0);
			mRemoteViews.setOnClickPendingIntent(R.id.widget_layout, pdIntent);
			mAppWidgetManager.updateAppWidget(thisWidget, mRemoteViews);
		}

	}

	// 數組轉化爲字符顯示
	public String array_to_string(String[] array) {
		String temp_str = "";
		for (int i = 0; i < array.length; i++) {
			if (array[i] == null) {
				break;
			} else {
				temp_str = temp_str + "\n* " + array[i];
			}
		}
		return temp_str;
	}
}

這種方法是每秒鐘更新一次桌面Widget,不過這樣太消耗資源了,弄得桌面很卡,使用線程來進行更新應該會好一點。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章