4

I'm making an app that needs to do some tasks repeteadly, usually between 1 and 5 minutes.

I have tried .setRepeating, setInexactRepeating and .set (the last one re-setting the alarm when the task is done)

When the alarm fires a service is started.

Usually it works well, but sometimes the alarm suddenly stops firing, no matter what method I use.

I have tested in Android 5.1 and 4.4.2.

Why is this happening? Is this a known bug or something?

Here is the method I use to set the alarm, the commented code is the other method I tried:

public void setAlarm(Context context) {
    alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context, AlarmReceiver.class);
    alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

    /*alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,
            System.currentTimeMillis() + 1000,
            PreferenceHelper.readLong(PreferenceHelper.PREF_TIME_TO_REFRESH), alarmIntent);*/
    alarmMgr.set(AlarmManager.RTC_WAKEUP,
            System.currentTimeMillis() + PreferenceHelper.readLong(PreferenceHelper.PREF_TIME_TO_REFRESH), alarmIntent);

    ComponentName receiver = new ComponentName(context, BootReceiver.class);
    PackageManager pm = context.getPackageManager();

    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);
}

As I said before, if I use .set I call the method again when the service finishes the asigned task. (This works too, but again the alarm suddenly stops firing after a few hours).

public class AlarmReceiver extends WakefulBroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    Intent service = new Intent(context, WifiCheckerService.class);
    startWakefulService(context, service);
}
Grender
  • 1,589
  • 2
  • 17
  • 44
  • 1
    also, are you 100% sure that your device isn't rebooting? because all alarms die when the phone is rebooted. – mawalker Jan 02 '16 at 16:13
  • It's not rebooting, although I have a BootReceiver listening and setting again the alarm. – Grender Jan 02 '16 at 16:15
  • What could be the approximate value of `PreferenceHelper.readLong(PreferenceHelper.PREF_TIME_TO_REFRESH)` in minutes? – Parag Kadam Jan 02 '16 at 16:22
  • Sorry, it depends, the users chooses that, between 1 minute and 1 hour (1m, 3m, 5m, 15m, 30m, 60m) no matter what value the users selects, as I said it will stop firing after a few hours. – Grender Jan 02 '16 at 16:23
  • Can you post your `BroadcastReceiver` code too. – Parag Kadam Jan 02 '16 at 16:29
  • What's your target sdk? – Parag Kadam Jan 02 '16 at 16:33
  • minSdkVersion 14, targetSdkVersion 23 – Grender Jan 02 '16 at 16:35
  • I am not sure but I suspect that it has something got to do with api level 23. Check this link - > http://stackoverflow.com/questions/34378707/alarm-manager-does-not-work-in-background-on-android-6-0 – Parag Kadam Jan 02 '16 at 16:37
  • The problem is also in pre-M devices (I haven't tested in M devices at all) – Grender Jan 02 '16 at 16:39
  • Can you also post the code of the service and the code where you call your setAlarm function. The code that triggers the alarm looks OK. Also add some logs and check that the function is being called correctly – Georgy Jan 02 '16 at 16:54
  • @Grender : Are you 100% sure the alarm stops triggering? It could be that it still does but the Service is failing to start. Have you put logging into `onReceive(...)` of the receiver to verify this? – Squonk Jan 02 '16 at 16:57
  • @Squonk, I haven't verified that, but why the service would be failing to start? Georgy, I first call the setAlarm function in the onCreate method of the app, lately I call it in the onStartCommand method of the service. – Grender Jan 02 '16 at 17:00
  • @Grender : I've no idea why the service might fail to start but you need to verify each stage. At the moment you're focussing on the assumption that the alarms stop presumably because you're not seeing the effect of the service starting. Unless you log the entry into `onReceive(...)` you won't truly know if the alarms really *DO* stop or if it's a fault in the service code. – Squonk Jan 02 '16 at 17:09

2 Answers2

1

I actually had the same problem and looking to transfer to SyncAdapter's instead, but having other issues with that. So not suggesting this will fix your problem.

Problem isn't the Alarm Manager at all. My application targets API > 23 and testing with API 24 phone and still getting this issue. Problem is that some manufacturers are creating their own Application Manager on top of Android and that is killing your application for resource/battery reasons which stops your application and any Alarms associated with it from triggering.

Check out this post to check if the application is in stopping mode. Android AlarmManager stops when activity die

I noticed on some phones this does not happen and on some phones it does...

If this is wrong and you do find out what is actually wrong, please let me know as Sync Adapters are killing me....

0

As a general principle, although you're running your app in devices with API < 23, as you target API 23 you should be using setExactAndAllowWhileIdle instead of set.

What you describe: alarm suddenly stops firing after a few hours sounds like what would happen in an M device. I wonder whether that behavior is also forced intentionally in pre-M devices when targeting API 23...I'd need to look at Android source code get an answer to that.

Aitor Viana
  • 933
  • 6
  • 15
  • But I can't use `setExactAndAllowWhileIdle` because the minimum SDK is 14, can I? – Grender Jan 02 '16 at 17:57
  • Yeah, I realized I was not clear enough. I meant checking the build version to use `setExactAndAllowWhileIdle` for M, `setExact` for pre-M including KitKat and `set` for pre-KitKat. I also see now that I didn't post the complete answer...O_o. Ok, I wanted to say, why are you using `0` as flag instead of for instance `PendingIntent.FLAG_UPDATE_CURRENT`? Also, what device are you testing on? I had similar problems in Huawai devices in the past. – Aitor Viana Jan 02 '16 at 18:45
  • I'll try that, thanks. I'm not using `PendingIntent.FLAG_UPDATE_CURRENT` because because the `PendingIntent` is always the same, I don't add extra data to it. – Grender Jan 02 '16 at 20:03