Android set () and setExact () settings work at wrong intervals

I am developing an application that needs to perform a specific task every 60 seconds. Since Android 4.4+ has problems with errors when all alarms are inaccurate, I chose the chain: A BroadcastReceiver triggers the first alarm, and each alarm, in turn, sets the next alarm.

The problem is that although I set alarms at intervals of 60 seconds (60,000 ms), alarms are triggered at intervals of 5 seconds, and sometimes even less. I tested the code on my Nexus 5 (Android 5.1.1) and on the Android 5.0.1 emulator, giving the same result. I must indicate that both receivers are registered in AndroidManifest, and my application has RECEIVE_BOOT_COMPLETED permission.

EDIT: setExact () causes exactly the same problem

StartupReceiver.java (BroadcastReceiver for BOOT_COMPLETED):

 public class StartupReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "Got the BOOT_COMPLETED signal"); // Get the first alarm to be invoked immediately AlarmReceiver.setNextScanAlarm(context, 0); } } 

AlarmReceiver.java

 public class AlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // Start the service Intent startServiceIntent = new Intent(context, BackgroundService.class); startServiceIntent.putExtra("interval", 60000); startServiceIntent.putExtra("action", "scan"); context.startService(startServiceIntent); // Schedule the next alarm setNextScanAlarm(context, 60000); } public static void setNextScanAlarm(Context context, int interval) { Intent scanIntent = new Intent(context, AlarmReceiver.class); scanIntent.putExtra("interval", interval); scanIntent.putExtra("action", "scan"); PendingIntent pendingIntent = PendingIntent.getBroadcast( context, 0, scanIntent, PendingIntent.FLAG_ONE_SHOT); AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); alarmManager.set( AlarmManager.ELAPSED_REALTIME_WAKEUP, interval, pendingIntent); } } 

What could be the problem?

+7
java android alarmmanager
source share
2 answers

I believe it because it’s an alarm when you call

 alarmManager.set( AlarmManager.ELAPSED_REALTIME_WAKEUP, interval, pendingIntent); 

The variable that you call interval is the time during which you want to skip the next alarm, but when you think about it, when does it know to start? Moreover, when is time actually zero?

When do you create it? Not. When do you call .set() ? Not.
In fact, it is zero on BOOT. Thus, you ask him to run 60 seconds after loading, and your request for this every time, this time has expired.

There is confusion here, and where you probably should just use a call like new Handler.postDelayed(Runnnable r, 60000) instead of the alarm manager. It will be much more accurate and will not be subject to some problems with understanding the Android operating system and its alarms / clock / etc / etc.

But for your specific case, I believe that you can solve it by referring to the calls / variables of the System function. Therefore, inside your setNextScanAlarm() function, I believe it will look like this:

  public static void setNextScanAlarm(Context context, int interval) { //create the intent the same way as before Intent scanIntent = new Intent(context, AlarmReceiver.class); scanIntent.putExtra("interval", interval); scanIntent.putExtra("action", "scan"); PendingIntent pendingIntent = PendingIntent.getBroadcast( context, 0, scanIntent, PendingIntent.FLAG_ONE_SHOT); //create new variables to calculate the correct time for this to go off long timeRightNow = System.elapsedRealTime() //use something else if you change AlarmManager type long timeWhenIShouldGoOff = timeRightNow + interval; //use the new timeWhenIShouldGoOff variable instead of interval AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); alarmManager.set( AlarmManager.ELAPSED_REALTIME_WAKEUP, timeWhenIShouldGoOff, pendingIntent); } 
0
source share

See my answer to a similar question. I use postDelayed() instead of AlarmManager for short time intervals (less than 1 minute) and AlarmManager for long time.

0
source share

All Articles