以下是我正在处理的内容。Android应用小部件更新问题
我有一个小部件与我的Android应用程序相关联,我想每隔10分钟更新一次(当前正在使用AlarmManager),只有在屏幕打开的情况下。如果屏幕关闭,pendingIntent的警报将被取消。一旦屏幕再次打开,我检查上次更新和当前时间是否有10分钟或更长时间的差异,如果是我发送广播更新小部件。
会发生什么,并且问题是待定Intent的警报可能未被取消(可能),并且在屏幕关闭时堆叠的pendingIntent的所有警报都会执行小部件更新。
以下是一些代码片段。
@Override
public void onReceive(Context context, Intent intent) {
check_intent = intent.getAction();
if(check_intent.equals("android.appwidget.action.APPWIDGET_UPDATE")){
mAppPreferences = PreferenceManager.getDefaultSharedPreferences(context);
int saved_num_widgets = mAppPreferences.getInt(NUM_WIDGETS, 0);
/*Check if there is atleast one widget on homescreen*/
if (saved_num_widgets>0){
boolean check = CheckScreenOn.check_screen_on(context);
/*Check if Screen is ON*/
if(check == true){
Intent widgetUpdate = new Intent(context, MyWidget.class);
widgetUpdate.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
alarms = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
newPending = PendingIntent.getBroadcast(context, 0, widgetUpdate,0);
alarms.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime()+ PERIOD, newPending);
context.startService(new Intent(context, UpdateService.class));
}
else{
alarms.cancel(newPending);
/*Screen is OFF no point updating the widget, cancel Alarms and do nothing*/
}
}
else{
int duration = Toast.LENGTH_LONG;
CharSequence text = "Please place My Widget on your home screen to keep earning money.";
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
}
if(check_intent.equals("android.appwidget.action.APPWIDGET_ENABLED")){
this.onEnabled(context);
}
if(check_intent.equals("android.appwidget.action.APPWIDGET_DELETED")){
this.onDeleted(context);
}
if(check_intent.equals("android.appwidget.action.APPWIDGET_DISABLED")){
this.onDisabled(context);
}
}
这里是接收SCREEN_ON广播,并且如果当前时间发送出用于小窗口更新请求中的广播接收器 - 上次插件被更新> = 10分钟。
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// ...
long update_interval = mAppPreferences.getLong(LASTUPDATETIME, 0);
long curtimemillis = System.currentTimeMillis();
long calculate_interval = curtimemillis - update_interval;
if(calculate_interval >= PERIOD){
int saved_num_widgets = mAppPreferences.getInt(NUM_WIDGETS, 0);
if (saved_num_widgets>0){
alarms.cancel(newPending);
Intent widgetUpdate = new Intent(context, MyWidget.class);
widgetUpdate.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
context.sendBroadcast(widgetUpdate);
}
}
}
}, new IntentFilter(Intent.ACTION_SCREEN_ON));
可以说上次更新发生在上午10点,屏幕关闭30分钟。当屏幕出现时,小部件会立即更新为pendingIntent存储的所有警报。当屏幕再次出现时,我希望小部件更新只发生一次。
最初我明白AlarmManager.ELAPSED_REALTIME会在设备从闲置状态唤醒时触发。
我不知道为什么报警取消不起作用。其他一切按预期工作。
顺便说一下,我已经在各种设备上进行了10分钟小部件更新的性能测试,并且它对可用资源没有任何负担。此外,所提供的服务甚至不会出现在Android设备的电池使用监视器中。
任何帮助,非常感谢。
答案你为什么不只是跳过你的'AlarmManager'报警'_WAKEUP'部分,并用它做什么?为什么你浪费时间在毫无意义的'SCREEN_OFF'和'SCREEN_ON'检测上忙乱了,所有这些都与使用非唤醒警报的基本相同? – CommonsWare 2011-03-15 22:21:54
@CommonsWare我为AlarmManager使用了非唤醒警报AlarmManager.ELAPSED_REALTIME。这是我的方法,但我发现即使使用非唤醒警报,更新也会继续触发。如果屏幕关闭时如果我停止发生更新,屏幕开启时会立即发生多个更新... – Aakash 2011-03-15 22:31:23
我觉得非唤醒警报不会唤醒设备。然后可以在设备醒来时传递警报,但您只需记下上次您的工作情况并跳过多余的警报。 – CommonsWare 2011-03-15 23:04:31