关于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,不过这样太消耗资源了,弄得桌面很卡,使用线程来进行更新应该会好一点。