您的位置:首页 > 移动开发 > Android开发

Android学习笔记(33)--- Widget中AppWidgetProvider,update更新问题

2012-11-05 21:07 387 查看
关于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文件:(准对我的一个备忘录项目:/article/1640243.html

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,不过这样太消耗资源了,弄得桌面很卡,使用线程来进行更新应该会好一点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: