21

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?

Ori Wasserman
  • 962
  • 1
  • 10
  • 24
  • On which specific API ? What does the graph represent, HTTP request on your servers ? – compte14031879 Apr 26 '17 at 14:23
  • @FrédéricLetellier API level 24. And yes, These are the HTTP requests. – Ori Wasserman Apr 26 '17 at 14:39
  • At what point(s) in the app is this alarm scheduled? – Tim Apr 26 '17 at 15:18
  • @TimCastelijns Only on reboot (I listen to BOOT_COMPLETE) – Ori Wasserman Apr 26 '17 at 15:30
  • @Ori Wasserman Do you cancel previous intent ? – compte14031879 Apr 27 '17 at 07:35
  • Why do you use inExactRepeating? – PEHLAJ Apr 27 '17 at 08:03
  • @Frédéric Letellier I update the intent – Ori Wasserman Apr 27 '17 at 08:14
  • @user12345 Because I want this alarm to be called daily and doesn't really care when exactly it does. – Ori Wasserman Apr 27 '17 at 08:21
  • @OriWasserman Testing this out on my HTC One M8 device, but haven't seen this issue yet. Where are you calling the AlarmManger at? Any chance you can post the code where this AlarmManager call is made at? – Pablo Baxter May 01 '17 at 20:20
  • @PabloBaxter I can't post the code itself but this is what I do: I have a service that schedules this alarm. As I said before I listen to BOOT_COMPLETE and calls this service on every boot to reschedule it. – Ori Wasserman May 02 '17 at 11:22
  • maybe the problem is with your service and it is repeated every 10 minutes and thus call setalarm on that matter. is your service binded or not? – Mehran Zamani May 03 '17 at 06:47
  • @MehranZamani You made me realize I might have not clearly stated what the problem was - The alarm still only happens 1-2 times a day, it just looks like on HTC the alarm "prefers" to wake up on "round" 10 minutes. The amount of the requests you see in the graph is not the anomaly, only the spread of those requests across the graph - the "spikes" - are weird. – Ori Wasserman May 03 '17 at 08:14
  • You mean all of HTC devices alarm will be goes off at same time and send request to your server at same exact time and make a spike? – Mehran Zamani May 03 '17 at 08:38
  • @MehranZamani as you can see in the graph, not *all* as there are still requests spread across the rest of the hour, but that's the main idea, yes. They are 2-3 times more likely to fire at those times. – Ori Wasserman May 03 '17 at 09:12

4 Answers4

2

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.

Community
  • 1
  • 1
compte14031879
  • 1,531
  • 14
  • 27
  • 4
    *We can't see the rest of your code* you could ask for it so you don't have to guess at solutions ;) – Tim Apr 26 '17 at 15:25
  • 1
    On the topic of looking for other solutions, consider using the JobScheduler for tasks like this instead of the AlarmManager. – Michael Celey Apr 26 '17 at 18:43
  • @Ori Wasserman: I agree with MCeley that instead of digging why alarm manager causing problems - try use instead job scheduler API's.. – Tal Kanel Apr 27 '17 at 07:00
  • 1
    @Tal Kanel In my opinion, it's better to debug the existing problem rather than immediately switch to a workaround with JobScheduler. It isn't impossible that JobScheduler is subject to other manufacturer-specific bugs on some devices. To ensure quality over the long term, it's better to correct a problem than to ignore it! – compte14031879 Apr 27 '17 at 07:33
  • @Frédéric Letellier - I use FLAG_UPDATE_CURRENT, not cancel. About the other options you suggested: 1 and 3 - I find it hard to believe this will solve anything, since this only affects the first alarm and the problem is mainly on the "repeating" part. 2 - This is a constant so it's compiled as this number into the APK. 4 - RTC_WAKEUP is the best suited parameter for my use-case, so changing it will affect the logic of the alarm. – Ori Wasserman Apr 27 '17 at 08:13
  • @OriWasserman Yes, sure but I was talking about an investigative process and not a solution. I suggest you try the different things in order to find the source. Once the source of the problem is found, it's easier to define a solution. As I said, my proposals might seem ridiculous, but we can not consider these elements to be reliable if the implementation of AlarmManager by the manufacturer HTC is bugged. – compte14031879 Apr 27 '17 at 09:52
1

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);

jmarkstar
  • 1,335
  • 14
  • 21
0

Adding interval to 2nd param i.e. triggerAtMillis helped me

alarm.setInexactRepeating(AlarmManager.RTC, calendar.getTimeInMillis()+interval, interval, pendingIntent);

check here for more details.

Community
  • 1
  • 1
rajesh
  • 199
  • 1
  • 11
0

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.

Bharat singh
  • 504
  • 7
  • 17