我正在开发AppWidget:
onAppWidgetOptionsChanged
onReceive
我的小部件有三种不同小部件大小的布局。 问题是当我调整窗口小部件并调用onReceive时,窗口小部件总是会获得初始视图。例如,小部件初始布局是4x1,而BroadCastReceiver的onReceive被调用,一切正常。当我在调用onReceive后将窗口小部件的大小调整为4x2时,窗口小部件的大小再次为4x1。 有人知道为什么吗?
以下是我的代码中的一些代码:
我有三个小部件布局:widget_layout.xml,widget_layout_1.xml,widget_layout_2.xml
以下是关于我的小部件的配置:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/widget_layout"
android:minHeight="40dip"
android:minWidth="390dip"
android:resizeMode="vertical"
android:configure="com.test.ConfigurationDummy"
>
</appwidget-provider>
以下是我的小部件提供商的代码:
public class WidgetProvider extends AppWidgetProvider { private AppWidgetManager appWidgetManager; int [] appWidgetIds;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Toast.makeText(context, "onUpdate():update widget instance ", Toast.LENGTH_SHORT).show();
this.appWidgetManager=appWidgetManager;
this.appWidgetIds= Arrays.copyOf(appWidgetIds,appWidgetIds.length);
RemoteViews updateViews = new RemoteViews(context.getPackageName(),
R.layout.widget_layout);
// do some with the view
appWidgetManager.updateAppWidget(appWidgetIds, updateViews);
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
Toast.makeText(context, "TimeWidgetRemoved id(s):" + appWidgetIds, Toast.LENGTH_SHORT).show();
super.onDeleted(context, appWidgetIds);
}
@Override
public void onDisabled (Context context){
Toast.makeText(context, "onDisabled():last widget instance removed", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
super.onDisabled(context);
}
/**
* this is called when first widget is created
*
* @param context
*/
@Override
public void onEnabled(Context context) {
Toast.makeText(context, "onEnabled id(s):" , Toast.LENGTH_SHORT).show();
super.onEnabled(context);
//TODO this should be read from StoreUtils class
SharedPreferences prefs = context.getSharedPreferences("AsebaSave", Activity.MODE_PRIVATE);
prefs.edit().putLong("refreshTime", 500).apply();
//TODO cards should be read from StoreUtils class
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, prefs.getLong("refreshTime", 500), prefs.getLong("refreshTime", 500), pi);
}
@TargetApi(16)
@Override
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) {
Toast.makeText(context, " onAppWidgetOptionsChanged" + appWidgetId, Toast.LENGTH_SHORT).show();
Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
int minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
int minHeight = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT);
appWidgetManager.updateAppWidget(appWidgetId, getRemoteViews(appWidgetManager,context, minWidth, minHeight, appWidgetId));
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
}
private RemoteViews getRemoteViews(AppWidgetManager appWidgetManager,Context context, int minWidth, int minHeight, int appWidgetId) {
int rows = getCellsForSize(minHeight);
RemoteViews updateViews;
switch (rows) {
case 1:
Toast.makeText(context, "case 1: ", Toast.LENGTH_SHORT).show();
updateViews = new RemoteViews(context.getPackageName(),
R.layout.widget_layout_1);
Intent svcIntent = new Intent(context, WidgetProvider.class);
svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
return updateViews;
case 2:
updateViews = new RemoteViews(context.getPackageName(),
R.layout.widget_layout_2);
Toast.makeText(context, "case 2: ", Toast.LENGTH_SHORT).show();
Intent svcIntent1 = new Intent(context, WidgetProvider.class);
svcIntent1.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
return updateViews;
default:
updateViews = new RemoteViews(context.getPackageName(),
R.layout.widget_layout);
Toast.makeText(context, "case 3: ", Toast.LENGTH_SHORT).show();
Intent svcIntent2 = new Intent(context, WidgetProvider.class);
svcIntent2.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
return updateViews;
}
}
private static int getCellsForSize(int size) {
int n = 2;
while (70 * n - 30 < size) {
++n;
}
return n - 1;
}
public Card getCard(Context context, String key){
SharedPreferences settings;
settings = context.getSharedPreferences(ConfigurationDummy.preferencesFile,
Context.MODE_PRIVATE);
if (settings.contains(key)) {
Gson gson = new Gson();
String json = settings.getString(key, "");
Card obj = gson.fromJson(json, Card.class);
return obj;
} else
return null;
}
}`
以下是我的BroadCastReceiver的代码:
public class AlarmManagerBroadcastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "onReceive():update widget instance ", Toast.LENGTH_SHORT).show(); PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "UPDATE_DONUT"); //Acquire the lock wl.acquire(); //You can do the processing here update the widget/remote views. AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; Intent intent1=new Intent(context,WidgetProvider.class); Bundle extras = intent1.getExtras(); if (extras != null) { Toast.makeText(context, "if (extras != null) { ", Toast.LENGTH_SHORT).show(); mAppWidgetId = extras.getInt( AppWidgetManager.EXTRA_APPWIDGET_ID); Toast.makeText(context, "Widget ID "+mAppWidgetId, Toast.LENGTH_SHORT).show(); } Bundle options=appWidgetManager.getAppWidgetOptions(mAppWidgetId); int minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT); int rows=getCellsForSize(minWidth); RemoteViews remoteViews; switch (rows) { case 1: Toast.makeText(context, "onReceive():remoteView 1 ", Toast.LENGTH_SHORT).show(); remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout_1); break; case 2: Toast.makeText(context, "onReceive():remoteView 2 ", Toast.LENGTH_SHORT).show(); remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget_layout_2); break; case 3: Toast.makeText(context, "onReceive():remoteView 3 ", Toast.LENGTH_SHORT).show(); remoteViews=new RemoteViews(context.getPackageName(),R.layout.widget_layout); break; default: Toast.makeText(context, "onReceive():remoteView default ", Toast.LENGTH_SHORT).show(); remoteViews=new RemoteViews(context.getPackageName(),R.layout.widget_layout); } new AsyncTaskRandom(remoteViews,context,rows).execute(); //Release the lock wl.release(); } //TODO This AsyncTask should call account balance private class AsyncTaskRandom extends AsyncTask<Void, Void,Void > { private RemoteViews remoteViews; private int rows; private Context context; int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; public AsyncTaskRandom(RemoteViews remoteViews,Context context,int rows){ this.remoteViews=remoteViews; this.context=context; this.rows=rows; } @Override protected Void doInBackground(Void... voids) { try { Thread.currentThread(); Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); Random rand = new Random(); switch (rows) { case 1: // do something with layout case 2: // do something with layout case 3: // do something with layout default: // do something with layout } ComponentName thiswidget = new ComponentName(context, WidgetProvider.class); AppWidgetManager manager = AppWidgetManager.getInstance(context); manager.updateAppWidget(thiswidget, remoteViews); } } private static int getCellsForSize(int size) { int n = 2; while (70 * n - 30 < size) { ++n; } return n - 1; } public Card getCard(Context context, String key){ SharedPreferences settings; settings = context.getSharedPreferences(ConfigurationDummy.preferencesFile, Context.MODE_PRIVATE); if (settings.contains(key)) { Gson gson = new Gson(); String json = settings.getString(key, ""); Card obj = gson.fromJson(json, Card.class); return obj; } else return null; }
}
当我尝试这个时:
Intent intent1=new Intent(context,WidgetProvider.class); Bundle extras = intent1.getExtras(); if (extras != null) { Toast.makeText(context, "if (extras != null) { ", Toast.LENGTH_SHORT).show(); mAppWidgetId = extras.getInt( AppWidgetManager.EXTRA_APPWIDGET_ID); Toast.makeText(context, "Widget ID "+mAppWidgetId, Toast.LENGTH_SHORT).show(); }
mAppWidgetId为0。 在这段代码中
Bundle options = appWidgetManager.getAppWidgetOptions(mAppWidgetId); int minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT);
选项为null,minWidth = 0。
我不知道为什么?