首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AlarmManager太快触发PendingIntent

AlarmManager太快触发PendingIntent
EN

Stack Overflow用户
提问于 2012-06-03 04:26:34
回答 4查看 2.2K关注 0票数 6

我已经搜索了3天,但在其他地方没有找到解决方案或类似的问题/问题。交易是这样的:

1小时触发->工作正常

2小时内触发->在1:23内触发

1天内触发->在约11:00内

那么,为什么AlarmManager如此不可预测,而且总是来得太快?或者我做错了什么?有没有其他方法可以让它正常工作?

这是我在AlarmManager中注册PendingIntent的方式(精简):

代码语言:javascript
复制
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仍在运行:

代码语言:javascript
复制
[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都不是以相同的方式重新创建的,所以它应该是完全相同的。如果不是,这个线程问题就不再相关了。

EN

回答 4

Stack Overflow用户

发布于 2012-06-03 05:23:50

当使用日历时,您是否考虑到日历使用精确到毫秒的时间。也许你应该将毫秒字段和秒字段设置为零,这样它就会精确到点。

另外,在一天内,使用以下代码会更容易

代码语言:javascript
复制
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(0);
cal.add(Calendar.DAY_OF_MONTH, 1);

另外,当您使用getInstance时,不是将日历时间设置为创建它的时间,这样就不需要再次设置时间了吗?

票数 1
EN

Stack Overflow用户

发布于 2012-06-03 07:16:38

重写:我最终看到了你的错误,但是不可预知。

我改变了这一点:

代码语言:javascript
复制
PendingIntent.getService(parent, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);

要这样做:

代码语言:javascript
复制
PendingIntent.getService(parent, 0, myIntent, PendingIntent.FLAG_CANCEL_CURRENT);

在与你相同的假设下,不知何故,一个旧的意图正在传播。我就没见过那次意外了自从..。

而且,我唯一一次看到它是在我第一次打电话的时候。另一种方法是跟踪一个current和一个previous日历对象,如果间隔不是您期望的时间间隔,那么忽略这个“提前”广播。(虽然考虑到警报的工作方式,这种方法似乎是多余的,但考虑到警报是如何工作的,它有助于防止这些无关的调用...)

希望这能帮上忙,如果我发现什么我会告诉你的。

票数 1
EN

Stack Overflow用户

发布于 2013-04-20 22:28:43

我知道这个问题有点老了,但我自己也有同样的问题。我发现,如果我试图在方法外部声明Calendar变量,它将不能很好地发挥作用,并且警报将提前触发。因为您的类是精简的,所以很难确切地说出您在哪里调用日历实例。

如果我这样设置它,那么它就会准时启动:

代码语言:javascript
复制
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);

}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10865691

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档