22

I have set the repeat time to 5 seconds. The first toast appears after 5 seconds, but all the next once repeat after 1 minute.
I tried the code with setRepeating() as well, it still doesn't work.
here is my code:

public void constructJob(){

    Intent alertIntent = new Intent(this, AlarmManagerService.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(
            this, 0,
            alertIntent,
            PendingIntent.FLAG_UPDATE_CURRENT);

    AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
    alarmManager.setInexactRepeating(
            AlarmManager.RTC_WAKEUP,
            GregorianCalendar.getInstance().getTimeInMillis(),
            repeatTime(),
            pendingIntent
    );

}

public long repeatTime(){
    return 5000;
}

AlarmManagerService.java

public class AlarmManagerService extends BroadcastReceiver {
      @Override
      public void onReceive(Context context, Intent intent) {
             Toast.makeText(context, "5 seconds have passed",
                            Toast.LENGTH_SHORT).show();
}
Nikhil Tambe
  • 502
  • 1
  • 4
  • 13

7 Answers7

24

The documentation needs to be updated. As of I think Android 5.1 (API version 22) there is a minimum period of 1 minute for repeating alarms, and alarms cannot be set less than 5 seconds in the future.

If you need to do work within one minute, just set the alarm directly, then set the next one from that alarm's handler, etc.

If you need to do work within 5 seconds, post it to a Handler instead of using the alarm manager?

ctate
  • 1,379
  • 10
  • 11
  • 1
    This seems pretty accurate based on empirical testing. I've tested a number of devices running 5.0, 5.1 and 6.x. Setting a 15-second repeating alarm generates repeats from 15 seconds to 10 minutes apart, on different devices. Samsung devices seem to favor 5 minute repeats. This is definitely broken, it definitely does NOT match the documentation (which specifically states that if you target API < 19 the alarm is delivered exactly as pre-API 19, and it is definitely manufacturer-dependent. Best solution seems to be to set one alarm and then schedule each one after the previous one triggers. – David Wasser Jun 02 '16 at 18:04
  • See also https://code.google.com/p/android/issues/detail?id=211988&thanks=211988&ts=1464886635 – David Wasser Jun 02 '16 at 18:05
15

Don't use setRepeating() or setInExactRepeating, it won't repeat after exactly 5 seconds. Instead, try scheduling the alarm once, then reschedule it again in the onReceive() method something like this. This will repeat after a particular time interval (5 seconds in this case)

MainActivity.java

public class MainActivity extends AppCompatActivity {

Button btnStartAlarm, btnStopAlarm;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btnStartAlarm = (Button) findViewById(R.id.btnStartAlarm);
    btnStopAlarm = (Button) findViewById(R.id.btnStopAlarm);

    Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
    final PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 100, intent, 0);

    final AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

    btnStartAlarm.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000, pendingIntent);
        }
    });

    btnStopAlarm.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            alarmManager.cancel(pendingIntent);
        }
    });
}
 }

AlarmReceiver.java

public class AlarmReceiver extends BroadcastReceiver {
public AlarmReceiver() {
}

@Override
public void onReceive(Context context, Intent intent) {

    Log.d("Javed", "onReceive called");
    Toast.makeText(context, "onReceive called", Toast.LENGTH_LONG).show();

    Intent intent1 = new Intent(context, AlarmReceiver.class);
    final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 100, intent1, 0);
    final AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000, pendingIntent);
}
  }
Javed Khatri
  • 719
  • 2
  • 7
  • 9
1

Try this code:
Calendar cal = Calendar.getInstance(); alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 5000, pendingIntent);

GIRIDHARAN
  • 169
  • 1
  • 1
  • 14
1

Try following code:

Long time = new GregorianCalendar().getTimeInMillis() +  3000;
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,time,5000, pendingIntent);

Once you run this code the alarm will first trigger after 3 sec and every 5 sec there after.

Also try using a WakefulBroadcastReceiver instead of BroadcastReceiver as it looks like the phone is going in doze mode after some time(If you are on android M).Make sure you include the WAKE_LOCK permission to use it correctly.

Additionally you must keep in mind,your alarm's first trigger will not be before the requested time, but it might not occur for almost a full interval after that time. In addition, while the overall period of the repeating alarm will be as requested, the time between any two successive firings of the alarm may vary.

Additionally

setInExactRepeating() does not guarantee accuracy of the triggering time. You can use setRepeating() before API 19 but beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. What you can do is, set a non-repeating alarm and when the alarm triggers you can reset the alarm again in your BroadcastReceiver 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.

Reference

setInexactRepeating() Official documentation

StackOverflow answer

Community
  • 1
  • 1
Parag Kadam
  • 3,620
  • 5
  • 25
  • 51
  • this code is exactly like mine except for the additional 3 seconds in "time". I tried using WakefulBroadcastReceiver as well, still no luck. i have seen the documentation as well. How can i achieve an exact repeating time for the successive firing? (in my case 5 seconds) – Nikhil Tambe Jan 05 '16 at 04:59
  • Repeating alarms will no longer give you guaranteed exactness. If you really need exact alarms at any given point, you need to chain one-shot alarms together: when each one fires, schedule the next one as a new one-shot exact alarm. – ctate Jun 03 '16 at 22:37
0

Try this

    Calendar cur_cal = new GregorianCalendar();

    PendingIntent pintent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    alarm.cancel(pintent);
    alarm.setRepeating(AlarmManager.RTC, cur_cal.getTimeInMillis(), interval, pintent);
Srishti Roy
  • 576
  • 5
  • 17
  • "alarm.cancel(pintent);" cancels the alarm matching the pending intent. hence, the alarm is never triggered in this case. – Nikhil Tambe Jan 05 '16 at 04:58
0

Try This

public void constructJob(){
Intent alertIntent = new Intent(this, AlarmManagerService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
        this, 0,
        alertIntent,
        PendingIntent.FLAG_UPDATE_CURRENT);

AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(
        AlarmManager.RTC_WAKEUP,
        GregorianCalendar.getInstance().getTimeInMillis(),
        1000*5,
        pendingIntent);

}
Kishan Soni
  • 816
  • 1
  • 6
  • 19
  • I have used setRepeating() already, makes no difference. It still fires the alarm after 1 min instead of 5 seconds. – Nikhil Tambe Jan 05 '16 at 08:55
0

I had exactly the same problem. I've spent a few hours debugging this, and finally I found out that if the repeating time is set to lower than one minute it always fires the alarm on one minute schedule !?

I followed this example: http://www.compiletimeerror.com/2015/02/how-to-make-alarm-repeat-in-android-code.html#.Vp5UrCorKM8

and it shows the alarm firing on 8 seconds, but in my case it wouldn't.

Than I tried with setting repeating time to few minutes and it worked fine. I also fond out that firing alarm from receiver gives more accurate repeat times (one receiver is for starting alarm manager and it is called by custom intent filter)

nmirkov
  • 59
  • 7