我有一个显示数据使用情况的小部件,为此我创建了一个PreferenceActivity,用户可以从中选择各种更新频率。 我从SharedPreferences中获取所选的freq值,然后我开始发出警报,但结果很奇怪。这是我的AppWidgetProvider:
private static PendingIntent pendingIntent = null;
...
public void onReceive(Context context, Intent intent) {
Log.d("TAG", "receive");
super.onReceive(context, intent);
if (CLOCK_WIDGET_UPDATE.equals(intent.getAction())) {
ComponentName thisAppWidget = new ComponentName(context.getPackageName(), getClass().getName());
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int ids[] = appWidgetManager.getAppWidgetIds(thisAppWidget);
for (int appWidgetID : ids) {
updateAppWidget(context, appWidgetManager, appWidgetID);
}
}
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Log.d("TAG", "update");
super.onUpdate(context, appWidgetManager, appWidgetIds);
for (int i = 0; i < appWidgetIds.length; i++) {
int appWidgetId = appWidgetIds[i];
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
// starting timer
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
Intent intent = new Intent(CLOCK_WIDGET_UPDATE);
pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
SharedPreferences prefs = context.getSharedPreferences(Integer.toString(appWidgetId), Context.MODE_PRIVATE);
int updateFrequencyMin = Integer.parseInt(prefs.getString(KEY_UPDATE_FREQ, DEFAULT_UPDATE_FREQ));
Log.d("TAG", "Update freq: " + updateFrequencyMin);
long updateFrequencyMillis = updateFrequencyMin * 60 * 1000;
// alarmManager.cancel(pendingIntent);
alarmManager.setInexactRepeating(AlarmManager.RTC, System.currentTimeMillis(), updateFrequencyMillis,
pendingIntent);
....
appWidgetManager.updateAppWidget(appWidgetId, view);
}
public void onDisabled(Context context) {
AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
m.cancel(pendingIntent);
}
如果我使用InexactRepeating将更新频率设置为5分钟,我会收到此日志:
08-18 15:30:17.902: D/TAG(23624): receive
08-18 15:30:18.122: D/TAG(23624): receive
08-18 15:30:18.122: D/TAG(23624): update
08-18 15:30:18.122: D/TAG(23624): Update freq: 60
08-18 15:30:22.582: D/TAG(23624): receive
08-18 15:30:22.602: D/TAG(23624): Update freq: 60
08-18 15:30:33.272: D/TAG(23624): receive
08-18 15:30:33.282: D/TAG(23624): Update freq: 60
08-18 15:30:39.692: D/TAG(23624): receive
08-18 15:30:39.692: D/TAG(23624): Update freq: 60
08-18 15:31:33.292: D/TAG(23624): receive <--- I have chosen the freq
08-18 15:31:33.292: D/TAG(23624): Update freq: 5
08-18 15:31:39.962: D/TAG(23624): receive
08-18 15:31:39.962: D/TAG(23624): Update freq: 5
我不知道为什么在配置活动时多次调用onReceive和onUpdate。
使用setRepeat方法会更糟糕,因为您可以看到时间戳:
08-18 15:38:59.992: D/TAG(24011): receive
08-18 15:39:00.242: D/TAG(24011): receive
08-18 15:39:00.242: D/TAG(24011): update
08-18 15:39:00.252: D/TAG(24011): Update freq: 60
08-18 15:39:00.442: D/TAG(24011): receive
08-18 15:39:00.442: D/TAG(24011): Update freq: 60
08-18 15:39:00.562: D/TAG(24011): receive
08-18 15:39:00.562: D/TAG(24011): Update freq: 60
08-18 15:39:00.642: D/TAG(24011): receive
08-18 15:39:00.642: D/TAG(24011): Update freq: 60
08-18 15:39:00.652: D/TAG(24011): receive
08-18 15:39:00.652: D/TAG(24011): Update freq: 60
08-18 15:39:00.662: D/TAG(24011): receive
08-18 15:39:00.662: D/TAG(24011): Update freq: 60
最后,这是我的偏好活动:
public class DataStatWidgetConfigure extends PreferenceActivity {
private int widgetId;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
if (extras != null) {
widgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
Log.d("meeegy", Integer.toString(widgetId));
getPreferenceManager().setSharedPreferencesName(Integer.toString(widgetId));
addPreferencesFromResource(R.xml.prefs);
}
}
@Override
public void onBackPressed() {
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
setResult(RESULT_OK, resultValue);
finish();
}
}
答案 0 :(得分:1)
从我在代码中看到的内容,您在更新窗口小部件时永远不会取消以前的警报。所以你不断向AlarmManager添加越来越多的回调。尝试删除之前的回叫,然后添加一个新回复
答案 1 :(得分:0)
问题在于:
alarmManager.setInexactRepeating(AlarmManager.RTC, System.currentTimeMillis(), updateFrequencyMillis,
pendingIntent);
第二个参数是需要先调用的时候,System.currentTimeMillis()现在意味着,所以在OnReceive()之后就调用了updateAppWidget(),它立即再次调用了这个setInexactRepeating(),依此类推..
解决方案:
alarmManager.setInexactRepeating(AlarmManager.RTC, System.currentTimeMillis() + updateFrequencyMillis,
updateFrequencyMillis, pendingIntent);