Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android AlarmManager triggers every "round" 10 minutes

I use the AlarmManager in my app as follows:

alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), AlarmManager.INTERVAL_HALF_DAY, intent);

Which I'd expect to trigger the alarm somewhere between 12 and 24 hours from each trigger. However, the behavior specifically on HTC devices is rather weird:

Each time the alarm is triggered, we send an HTTP request to our servers. On all devices, we see requests coming to the server uniformly over time, but on HTC devices there are spikes every "round" 10 minutes (XX:10, XX:20, ...): enter image description here

What can be the cause for these spikes? And why would it only be on HTC devices?

like image 840
Ori Wasserman Avatar asked Apr 23 '17 17:04

Ori Wasserman


3 Answers

We can't see the rest of your code, but do you cancel the previous intent as below:

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(context, TimeAlarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);

alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), AlarmManager.INTERVAL_HALF_DAY, pendingIntent);

Otherwise it is probably a bad management of AlarmManager by HTC, try these different investigations (This may seem ridiculous, but it's better to challenge each item) :

  • Add a little delay to System.currentTimeMillis() rather than System.currentTimeMillis() alone
  • Use value 43200000 (constant value) rather than AlarmManager.INTERVAL_HALF_DAY
  • Try this with Calendar
  • Try other parameters for setInexactRepeating

I have not found any known and listed bugs on this subject. If your investigations don't give anything, you probably can't do anything. In this case, you will only have to set up a workaround for HTC that does not use AlarmManager in this way.

like image 80
compte14031879 Avatar answered Nov 12 '22 21:11

compte14031879


First of all cancel previous alaram

private void cancelAlarm(Context context, Class aClass) {
        Intent intent = new Intent(context, aClass);
        PendingIntent pintent = PendingIntent.getService(context, REQUEST_CODE, intent, FLAG_UPDATE_CURRENT);
        AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        alarm.cancel(pintent);
    }

Then Create new alarm Like that

public static void setAlarmManager(Context context, Class aClass, String time) {
        Intent intent = new Intent(context, aClass);
        PendingIntent pintent = PendingIntent.getService(context, REQUEST_CODE, intent, FLAG_UPDATE_CURRENT);
        AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

//        alarm.cancel(pintent);

//        "auto_sync":"1","sync_time":"04:05"
        String timeArr[] = time.split(":");
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeArr[0]));
        calendar.set(Calendar.MINUTE, Integer.parseInt(timeArr[1]));

        alarm.setRepeating(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis(), INTERVAL, pintent);
    }

On Devices alarm Manager not well managed. IN that case use SharedPreferences to save previous time when creating or updating new alarm manager. that saved value also useful when you will try to run your daily basis operation.

like image 29
Bharat singh Avatar answered Sep 22 '22 12:09

Bharat singh


I see you have tried AlarmManager.RTC_WAKEUP, could you try AlarmManager.ELAPSED_REALTIME_WAKEUP?

Boot you alarm since the phone turns on with

<receiver android:name=".YourBootReceiver"> 
    <intent-filter> 
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
        <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
        <action android:name="your.package.BOOT_FIRSTTIME"/>
    </intent-filter> 
</receiver>

Use your.package.BOOT_FIRSTTIME when the user activates the Alarm.

Then, configure your AlarmManager like this:

24 hours in Milliseconds is 86400000

alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 86400000, pendingIntent);

like image 1
jmarkstar Avatar answered Nov 12 '22 22:11

jmarkstar