Android AlarmManager not working on some devices when the app is closed
Asked Answered
S

5

32

I am trying to run IntentService as such from AlarmManager setRepeating() for every half an hour. I want to send a to broadcast, from broad cast to intent service. In the service, some functionality will be done.

But, initially the AlarmManager in not triggering while the app is in closed state.

When my app is running or in background state the alarm is working fine and when I close the app the alarm is not working in some devices.

What should I do to run the alarm even if the app is closed?

Scudo answered 28/9, 2016 at 6:33 Comment(3)
be aware that the answer from user13 is absolutely correct, BUT some devices like Huawei also implement their own energy management and you can´t get rid of this programmatically. In my Huawei Ascend Mate 7 , no matter what I am doing (suggestions by developer guide for doze mode), it does not work. Instead I have to do some device settings and this is only possible manually...Palmerpalmerston
@Opiatefuchs: could you elaborate? (in my LTE blade, even manual warnings and battery saver settings did not help, but maybe there's more?)Towelling
@serv-inc: well, that´s hard to say, there are so much different implementations. I hope this will be unique in the future or better explained and more user friendly. On Huawei, there are also autostart settings. These settings I found in the "Telephony Manager".Palmerpalmerston
B
39

From the documentation of setRepeating():

As of API 19, all repeating alarms are inexact.

Moreover, setRepeating() does not work with Doze.

You should use exact alarms (set by the appropriate AlarmManager method based on the API level of the device):

if (Build.VERSION.SDK_INT >= 23) {
    alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
            triggerTime, pendingIntent);
} else if (Build.VERSION.SDK_INT >= 19) {
    alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
} else {
    alarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
}

And reschedule them every time they fire.

For the rescheduling you could add the original trigger time to the Intent:

intent.putExtra(KEY_TRIGGER_TIME, triggerTime);

Then retrieve this extra in onReceive(), add your desired interval to it and reschedule the alarm using the new value:

@Override
public void onReceive(Context context, Intent intent) {
    long triggerTime = intent
            .getLongExtra(KEY_TRIGGER_TIME, System.currentTimeMillis());

    // adding one day to the current trigger time
    triggerTime += TimeUnit.DAYS.toMillis(1);

    // set a new alarm using the new trigger time
    // ...
}

NOTE: As @Opiatefuchs mentioned in the comment above, some manufacturers (such as Xiaomi or Huawei) may implement certain battery saver functions that can prevent alarms from being fired and cannot be bypassed programmatically.

Barretter answered 28/9, 2016 at 6:45 Comment(3)
Why? Dear manufacturers, your phones used/sold heavily is because of our effort not of your app are being used by your users, and you are making it hard for us to tackle the situation. If Google is not taking any action on these stupid restrictions imposed by manufacturers, then it won't be too long before we switch to the Apple ecosystem.Sabrinasabsay
Even I add one to in receiver but the loop is started on alarm why? e.g notification is repeating one after another.Plosive
@Sabrinasabsay I totally agree and i have always said that cause these manufacturers are really making lot of changes for their benefit not caring about the hard work of developers who have to take the pain of finding solution for every little issue .. Google is not really careful about these practices and i'm already fed up everytime i have to deal with scheduling notification .Glaucescent
D
18

Nowadays devices are coming with more security in context of Battery power consumption. By default devices keep almost all apps in power saving mode. It means in some devices your background work (Location, Alarm manager) won't work as soon as you come out from the app. In other devices background tasks won't work after a battery threshold limit (like 13%). So you need to keep out your app from this battery saving mode to run your app smoothly even in background. The way to achieve that behavior in these two manufacturers is:

Xiaomi

  • Go to the Battery => Power => App battery Saver => select your app and choose No restrictions (for Background settings), then Allow option for Background location.

  • To AutoStart your app after Boot: Go to the Security app => Permissions => Auto start and check your app.

Samsung

Samsung Smart Manager App used to stop all background work after 3 days if you don't come to your app. So the way to disable this feature is:

  • Go to Battery in the Settings => Unmonitored apps => Add your app to the whitelist. Some other Samsung versions may differ the place to disable it, like Battery => Detail => Select the app and "Don't optimize".

For other devices there should be same power options either in settings option directly or some app are given to handle it.

Dinothere answered 6/12, 2016 at 9:41 Comment(1)
So, is there any way to by pass this, I mean even when the app goes under optimization ? so, android default alarm app how works ?Majesty
G
8

First, there is a bug with android studio. If you start the app from the android studio and then swipe it away from the recents, the alarms will be deleted. So after that, relaunch your app by clicking on the launcher Icon and then if you swipe it away, the alarm will be still there.

Second, on some devicrs with battery optimization stuff, you should start a foreground service and that works totally fine.

I could make it work using these two points and now it works like a charm.

Glucosuria answered 10/8, 2020 at 11:15 Comment(3)
I am facing the same problem. In my case, I stopped battery optimization for my app but after closing the app it seems like that it can not trigger my broadcast receiver at all. Please share your though in this case. I am facing this in Pixel 4XL os: 11.Shaughnessy
Thank you! I'd noticed the exact bug behavior you described and it was driving me crazy. I thought something was wrong with my code but now it makes sense.Gemmagemmate
I can't freaking believe this bug is still present!!! I've encountered it recently and thought exactly like @GemmagemmateNorval
T
4

The below behavior changed after a full charge. Previously, after disabling energy saving for this app, it displayed that there was no battery saving active etc, but only after a full charge (from very low battery state) did the device behave as it should. So change those settings for the app, then do a full recharge (maybe only after previously having low battery). This could fix it.


ZTE Blade L110

Even with the battery saver disabled (Settings -> Battery -> Options -> Battery Saver) and the app marked as important for messages (Settings -> Prompt & notification -> App notifications -> appname -> Priority) it seems like neither setExact nor setAlarmClock are triggering on time.

Towelling answered 31/10, 2017 at 19:46 Comment(0)
D
3

for Lenovo phone:-

you need to go in setting -> application->select app-> uncheck Restrict to launch

now it will be work in the background as killed state

Damalas answered 21/9, 2017 at 13:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.