为什么我的安卓闹钟管理器会立即触发?

13
我正在遵循一个每10秒发送更新通知的示例代码。以下是代码,位于用于AppWidgetProvider的UpdateService中。如果我加入Thread.sleep(10*1000);,我可以看到服务循环按预期运行。显然,我有一些根本性的问题,导致它立即触发。这应该是一个将更新广播到我的监听器的闹钟的PendingIntent。
long nextUpdate = 10*1000;
Log.d(TAG, "Requesting next update in " + nextUpdate + " msec." );

Intent updateIntent = new Intent(ACTION_UPDATE_ALL);
updateIntent.setClass(this, UpdateService.class);

PendingIntent pendingIntent = PendingIntent.getService(this, 0, updateIntent, 0);

// Schedule alarm, and force the device awake for this update
AlarmManager alarmManager = (AlarmManager)getBaseContext().getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), 
    nextUpdate, pendingIntent);
3个回答

22

AlarmManager.setRepeating方法定义为public void setRepeating (int type, long triggerAtTime, long interval, PendingIntent operation),第二个参数是它首次调用的时间。你正在告诉它从SystemClock.elapsedRealtime()开始,也就是现在。


感谢两位的快速准确回答,我点赞了。接下来是下一个问题。相当讽刺的是,我尝试在不到15秒的时间内发表第二条评论,结果收到了SO的计时器弹出通知。 :)) - mobibob
我是这样做的:amAlarm1.setInexactRepeating(AlarmManager.RTC_WAKEUP, 120000, AlarmManager.INTERVAL_DAY, alarm1Pending);,但是仍然会立即触发挂起意图? - Muhammad Babar
@MuhammadBabar:你应该发布一个新问题。但是无论如何回答你的问题,你正在传递“120000”到triggerAtTime,这对应于“Fri,02 Jan 1970 09:20:00 GMT”。 - Falmarri
@Falmarri,感谢您提供这个新信息(不过120000只是为了测试)。但问题在于 InexactRepeating,它无法保证在用户定义的触发器上运行。我使用了setRepeating,它像魔术一样正常工作 :) - Muhammad Babar
我甚至没有使用setRepeating或setInexactRepeating,但我的闹钟仍然立即触发。 - PaulG

16

如果您想让第一个闹钟立即响起(SystemClock.elapsedRealtime()),则需要使用 setRepeating()。如果您希望第一个闹钟在其他时间响起,则需添加偏移量(SystemClock.elapsedRealtime()+nextUpdate)。


感谢两位的快速准确回答,我也点赞了。接下来进入下一个问题。 - mobibob
你可以使用 System.currentTimeMillis() + nextUpdate。 - Suresh
@Suresh:问题中的代码正在使用AlarmManager.ELAPSED_REALTIME。为此,您需要使用SystemClock.elapsedRealtime()作为时间基准。如果您想要使用System.currentTimeMillis()作为时间基准,则需要使用AlarmManager.RTC作为警报类型。 - CommonsWare

6
如果您创建了一个过去时间的闹钟PendingIntent,它将立即触发。例如:为今天早上8点设置闹钟,但在11点左右执行代码将立即触发。
解决方案:
cal.add(Calendar.DATE, 1);

long delay = 24 * 60 * 60 * 1000;
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), delay,pendingIntent);` 

这将在第二天的指定时间(即上午8点)触发事件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接