9

I used the following code to set repeating alarm (every 5 minutes).

public void SetAlarm(Context context)
{
     AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
     Intent i = new Intent(context, Alarm.class);
     PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
     am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 5, pi); // Millisec * Second * Minute
 }

Is seems to work fine (it runs almost 20 hours), and in the server I can see that some constant message arrives.

However, there is something about the times: I want the times to be every five minutes, and it seems like in the server I receives the messages in different times.

I add a first sequence of times when the server received messages, when the phone was in sleep mode (in the night):

05:13:51,
05:18:54,
05:24:54,
05:28:54,
05:33:51,
05:38:54,
05:52:45,
05:54:54,
05:58:52,
06:04:54,
06:08:54,
06:16:19,
06:18:54,
06:24:54,
06:28:54,
06:34:54,
06:48:42,
06:48:44,
06:58:54,

And another sequence when I used the phone from time to time:

11:08:46,
11:13:45,
11:18:48,
11:23:52,
11:33:54,
11:38:47,
11:48:47,
11:58:47,
12:03:52,
12:08:45,
12:14:49,
12:18:43,
12:25:37,
12:28:41,
12:34:56,
12:38:47,
12:43:48,
12:48:56,
12:54:07,
12:58:48,
13:03:43,
13:08:56,
13:14:11,
13:18:55,
13:25:02,
13:28:45,
13:33:43,
13:44:57,
13:48:58,
13:54:57,
13:58:52,
14:03:58

I notice to three different anomalies:

  1. Skipping over alarm (for example interval of 10 minutes between two messages in the server) - it seems fine to me, and might be due to connectivity problems.

  2. Pattern of 6 minutes between two messages, and then 4 minutes. You can see this pattern more than one time. I have an assumption, that the OS does some optimization, and if for example it has other alarms every two minutes (for example checking if there are new emails), it runs them together (and the radio is turn on only one time instead of two).

  3. Strange intervals (I can't explain them) - you can see.

So my questions:

  1. How can I enforce the system to run exactly every 5 minutes (or to try harder)?

  2. What are the reasons for the strange timing? I wrote what I think, but these are only thoughts.

Thanks!

GrIsHu
  • 28,433
  • 10
  • 61
  • 99
Gari BN
  • 1,495
  • 1
  • 15
  • 28
  • Looks like more than one instance of your alarm is running. – Vigbyor Dec 03 '13 at 13:28
  • 1
    @Gari BN, did you got any luck solving the issue. I'm facing the same problem and I'm already targeting API Level 17 to see if it works but it does the same thing. My alarm runs 1 hour after its scheduled but that behavior is not the same in every device. – Junior Buckeridge Sep 13 '14 at 17:03

2 Answers2

8

From the API (here):

Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.

So, if you are using API 19, then answers to your two questions...

MeNa
  • 1,481
  • 9
  • 22
  • I know this. However, this is not my case. – Gari BN Dec 03 '13 at 18:57
  • Actually, in my manifest I have: . I see now, that in Project->Properties->Android, I have only one option for the target, and the API in this row is 19! So, if I actually run according to API 19, what is the meaning of what I wrote in the manifest? and how can I change this? – Gari BN Dec 04 '13 at 10:58
  • Maybe will help: http://stackoverflow.com/a/4994039/2075420 . And this too: http://stackoverflow.com/a/11296417/2075420 – MeNa Dec 04 '13 at 11:46
  • I unaccepted the answer, as I changed the API to 18 and it still not working. I was sure that it was the problem. – Gari BN Dec 05 '13 at 11:32
  • 1
    OK. Just a try: change `currentTimeMillis()` to `nanoTime()`. – MeNa Dec 05 '13 at 13:33
  • Why should it change something? – Gari BN Dec 05 '13 at 19:29
  • The API says something, see: http://developer.android.com/reference/java/lang/System.html#currentTimeMillis() – MeNa Dec 05 '13 at 19:56
  • I re-accepted your answer, as after long run, I saw that the number of deviations from the expected alarms sequence was decreased. Thank you!!! (I didn't check your offer about the nanoTime) – Gari BN Dec 06 '13 at 07:46
  • By some magic reason setExact with NanoTime helped me on Lollipop! – ar-g Jul 28 '15 at 14:30
-1

How can I enforce the system to run exactly every 5 minutes (or to try harder)?

Try this code, it works 100%

Calendar calendar = new GregorianCalendar();
calendar.setTimeZone(TimeZone.getDefault());
calendar.setTimeInMillis(System.currentTimeMillis());


calendar.set( Calendar.MINUTE, 00 );
calendar.set( Calendar.SECOND, 00 );

Intent intent = new Intent(context, Alarm.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0 );
hourlyAlarm = (AlarmManager) context.getSystemService( Context.ALARM_SERVICE );
hourlyAlarm.setRepeating( AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),1000 * 60 * 5, pi );
Vigbyor
  • 2,334
  • 4
  • 18
  • 34