3

I need to run a service each night at midnight. I would like to use the AlarmManager to do this.

Can you give me some guidance of how to make it work correctly?

alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, System.currentTimeMillis(), AlarmManager.INTERNAL_DAY, serviceIntent);

Perhaps I need to use a Calendar object to specify the time? Thanks for any help!

Cristian
  • 198,401
  • 62
  • 356
  • 264
Nate Radebaugh
  • 1,044
  • 2
  • 20
  • 29

2 Answers2

6

setInexactRepeating(), as the name suggests, is inexact. Bear in mind that it might run somewhat before or after midnight.

To determine when midnight is, use a Calendar object. Then call getDate() to get a Date and getTime() on the Date to get the proper millisecond value for your setInexactRepeating() call.

Community
  • 1
  • 1
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 1
    I need it to run as close to midnight as possible without being before midnight. Would this be more appropriate? Calendar midnight = Calendar.getInstance(); midnight.set(Calendar.HOUR_OF_DAY,0); midnight.set(Calendar.MINUTE,0); midnight.set(Calendar.SECOND,0); midnight.set(Calendar.MILLISECOND,0); alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, midnight.getTimeInMillis(), AlarmManager.INTERVAL_DAY, serviceIntent); – Nate Radebaugh May 30 '10 at 21:10
  • Well, `setRepeating()` will be more accurate than `setInexactRepeating()`. Even still, there may be other things going on with the device at the time, and so there is no absolute millisecond-level guarantee over the timing of when your alarm code gets control. – CommonsWare May 30 '10 at 21:46
  • Ok, another question then.. In DDMS I keep seeing "Scheduling restart of crashed service..." This seems to stop my service from being repeated. Is there any way to successfully get around that problem because at that point my widget stops updating the way I need it to? – Nate Radebaugh May 30 '10 at 21:53
  • That implies your service crashed. There should be messages preceding it showing where you are blowing up. – CommonsWare May 30 '10 at 22:11
  • It says "Low Memory: No more background processes." I assumed this to just be a normal thing... does it mean there's a memory leak in my code? – Nate Radebaugh May 30 '10 at 22:14
  • It means your service isn't shutting down like it should. The point behind `AlarmManager` is to eliminate the need for your service to try running forever (which it can't). If Android killed off your service to free up memory, that implies the service was still running. I would not expect that to impact your alarms at all, though. – CommonsWare May 30 '10 at 22:34
  • This setRepeating() call is within an onUpdate() function for my widget. Perhaps that's where my issue is? I'm very new at this and not sure how else to go about making a widget that shows the correct date all the time. Thank you for your help. – Nate Radebaugh May 30 '10 at 23:09
  • `setRepeating()` only needs to be invoked once, probably from a `BroadcastReceiver` set up to get control at boot time. See: http://github.com/commonsguy/cw-advandroid/tree/master/SystemServices/Alarm/ for an example of this. – CommonsWare May 30 '10 at 23:35
0

If you want your code to run specifically midnight, don't use "setInexactRepeating". In fact, you need: alarmManager.setRepeating(RTC_WAKEUP, ...), and then use Calendarto calculate the next midnight you want to run at.

If your need to wake up at midnight is dependent on user activity such that there's no need to wake up the phone exactly at midnight, just that the action should be run first if the user uses the phone after midnight, you can change RTC_WAKEUP to just RTC. Although, the battery effects of waking up exactly at midnight with RTC_WAKEUP should be neglible, so it's probably simpler to just force the wakeup.

Nakedible
  • 4,067
  • 7
  • 34
  • 40