我现在已经搜索了3天,但在其他地方找不到解决方案或类似的问题/问题。这是交易:
1小时内触发 - >工作正确
2小时内触发 - >在1:23
进入在1天内触发 - >进入~11:00
那么为什么AlarmManager如此不可预测且总是太快?或者我做错了什么?是否有另一种方式可以正常工作?
这是我在AlarmManager中注册PendingIntent(剥离)的方式:
AlarmManager alarmManager = (AlarmManager)parent.getSystemService(ALARM_SERVICE);
Intent myIntent = new Intent(parent, UpdateKlasRoostersService.class);
PendingIntent pendingIntent = PendingIntent.getService(parent, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//Set startdate of PendingIntent so it triggers in 10 minutes
Calendar start = Calendar.getInstance();
start.setTimeInMillis(SystemClock.elapsedRealtime());
start.add(Calendar.MINUTE, 10);
//Set interval of PendingIntent so it triggers every day
Integer interval = 1*24*60*60*1000;
//Cancel any similar instances of this PendingIntent if already scheduled
alarmManager.cancel(pendingIntent);
//Schedule PendingIntent
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, start.getTimeInMillis(), interval, pendingIntent);
//Old way I used to schedule a PendingIntent, didn't seem to work either
//alarmManager.set(AlarmManager.RTC_WAKEUP, start.getTimeInMillis(), pendingIntent);
如果有人有解决方案,这将是非常棒的。谢谢你的帮助!
更新: 2小时前它以2小时的间隔触发它,但之后它在1:20小时后触发。这变得非常奇怪。我将使用日志文件跟踪触发器,并在明天将其发布到此处。
更新: PendingIntent计划每3小时运行一次。从日志的第二行开始,似乎旧计划的PendingIntent仍在运行:
[2012-5-3 2:15:42 519] Updating Klasroosters
[2012-5-3 4:15:15 562] Updating Klasroosters
[2012-5-3 5:15:42 749] Updating Klasroosters
[2012-5-3 8:15:42 754] Updating Klasroosters
[2012-5-3 11:15:42 522] Updating Klasroosters
但是,我确定在安排新的PendingIntent之前我取消了预定的PendingIntent。并且每个PendingIntent都不会以相同的方式重新创建,因此它应该完全相同。如果没有,这个线程问题就不再适用了。
答案 0 :(得分:1)
使用日历时,您会考虑日历使用的时间为Milli秒。也许你应该将Milli第二个字段和秒字段设置为零,这样它就会出现在点上。
同样在一天中使用此
会更容易Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(0);
cal.add(Calendar.DAY_OF_MONTH, 1);
此外,当您使用getInstance时,不会将日历时间设置为创建时间,因此不需要再次设置时间吗?
答案 1 :(得分:1)
重写:我最终看到了你的错误,但不可预测。
我确实改变了这个:
PendingIntent.getService(parent, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
到此:
PendingIntent.getService(parent, 0, myIntent, PendingIntent.FLAG_CANCEL_CURRENT);
在与你一样的假设下以某种方式旧的意图是广播。我从没见过侥幸......
我见过的唯一一次是在我最初的通话中。另一种方法可能是跟踪current
和previous
日历对象,如果间隔不符合您的预期,则忽略此“早期”广播。 (虽然这种方法似乎是多余的,考虑到警报应该如何工作,但它有助于防止这些无关的呼叫考虑警报 的工作方式......)
希望有所帮助,如果我发现其他任何事情,我会通知您。
答案 2 :(得分:1)
我知道这个问题有点陈旧,但我自己也有同样的问题。我发现如果我试图在方法之外声明Calendar变量,它将无法正常播放并且警报会提前触发。由于您的课程被剥离了,因此很难确切地说出您正在调用日历实例的位置。
如果我这样设置,那么它会按时启动:
protected void nextAlarm(Context context, int seconds){
Calendar nextAlarm = Calendar.getInstance();
Intent intent = new Intent(context, MyClass.class);
PendingIntent pending = PendingIntent.getBroadcast(context, MainActivity.REPEATING_ALARM, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager amanager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
nextAlarm.add(Calendar.SECOND, seconds);
amanager.set(AlarmManager.RTC_WAKEUP, nextAlarm.getTimeInMillis(), pending);
}
答案 3 :(得分:1)
确保您的服务onStartCommand返回START_NOT_STICKY,否则将自动重新尝试:
public class UpdateKlasRoostersService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
buildUpdate();
return START_NOT_STICKY;
}
}