可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
My app uses AlarmManager and it has been working since 4 years ago. But I noticed it started failing in some devices.
I'm pretty sure code is right (I'm using WakefulBroadcastReceiver, and setExactAndAllowWhileIdle for devices with Doze) because it's working perfectly on Nexus devices, but it fails in devices of some manufacturers (Huawei, Xiaomi...).
Huawei devices, for example, have a kind of battery manager that kill apps, and when an app is killed, scheduled alarms are cancelled. So setting an app as "protected" in Huawei battery manager solves the problem.
But recently I noticed it's not working with more devices: Xiaomi, Samsung (maybe it's related to the new "Smart Manager"?)... It seems that this behavior is becoming a standard: to kill background apps.
Anyone know anything about it? Any way to ensure alarm is fired?
EDIT: This problem is caused by "battery savers" added by different manufacturers. More info here: https://dontkillmyapp.com/
回答1:
I'm trying to solve it several weeks already. I found nothing. Huawei just kill all the alarms after some time. If I put the app to the protected app in their battery saver it does't help. But If I change package name of my app to contain words like alarm, clock or calendar, it works absolutely normal like on any other devices. I don't understand how Google can give certification for this crap. I think that OEM should not modify core platform in such way. I understand that they have own batter saver which kill the app after some time, when user don't use it. But this killing alarms also of protected apps.
Also setAlarmClock() for exact timing alarms helps. But it is not possible to use this for thinks like widget update.
Update: Protection by package name keywords is already not working on current Huawei devices, it was true in 2017.
回答2:
The issue is Smart Manager. Samsung has a battery manager which at times disables certain apps from running in background. It tried to "resume" when going back to the app but completely disables the application or may resume every 5 mins or so (depending how Samsung has it).
This would work on stock versions of android as there is no Samsung Manager. You can also install custom version of android which has some features to enable SM (depending on the rom).
回答3:
Most of modern Android devices come with an app or mechanism, which automagically tries to figure out how to save battery and as a result might kill certain 3rd party apps. This might result in removing scheduled tasks and jobs, (e.g. alarms not going off, push notification not working, etc.). In many cases this happens completely independent from battery saving mechanisms of Android, in my case i couldn't make more battery optimization when i detect some devices model, i redirect user to the start up manager to whitelist my application
You found in this link for every model the intent that you should invoke
https://android-arsenal.com/details/1/6771
回答4:
Use AlarmManager for <5.0 devices, and JobScheduler for 5.0+ devices. I can't say for sure that JobScheduler will be unaffected by manufacturer shenanigans, but it would seem much less likely to me, given that Android is trying to move people away from AlarmManager and onto JobScheduler.
EDIT: Google has come out with a first-party solution to this problem called WorkManager. It abstracts multiple scheduling frameworks and uses the most appropriate one for the device.
回答5:
Are you listening for BOOT_COMPLETED? You need to set alarms again when a device is rebooted.
回答6:
I also have an app that sets alarms.The solution is to use AlarmManager.setAlarmClock() on api >= 21. This is unaffected by doze afaik and has the added bonus of putting an alarm clock icon in the system tray.
回答7:
most new phones nowadays are bundled with some kind of battery/power saving manager which do same thing you described. not counting duboosters and clean masters.
I think you need to put a disclaimer or faq in your app / play store listing stating that this app needs to be put into exception of your battery manager app in order to work properly.
回答8:
What version of Android are these devices running?
As of API 23, the OS itself will go into a low-power idle mode when it's been unused for a while, and in that mode alarms will not be delivered. There is a way for apps to explicitly say "I need this alarm to go off at this time regardless of battery usage," however; the new AlarmManager methods called setAndAllowWhileIdle()
and setExactAndAllowWhileIdle()
.
From your description it sounds like this might not be the particular cause of your issues on certain OEMs' devices, but this is something that all developers using the Alarm Manager ought to be aware of.
Finally, many usages of the Alarm Manager are better addressed using the Job Scheduler's mechanisms. For backwards compatibility the Play Services "GCM Network Manager" is actually very close to the Job Scheduler in functionality -- it uses the Job Scheduler internally on newer versions of Android -- and is not necessarily about networking, despite the class's name.
回答9:
I don't think killing the app will prevent the alarm manager from waking your app.
Its only when you "force stop" or disable the app you don't receive call backs from alarm manager.
The root cause might be something else.
Also on M... setExactAndAllowWhileIdle does throttling...that is if u schedule an alarm every 2 mins it won't be triggered. ..There needs to be 15 mins window. .
回答10:
For Xiaomi you may need to enable AutoStart for your app. I am trying do to a list of Android modifications(usually from phone's manufacturer) that may effect a background process. If you have something new please add an answer here List of Android task killers
回答11:
We need to enable our app in autostart manager in app manager, some handsets like vivo v5,
In vivo v5, We can find out this menu in iManager-->App Manager--> Auto Start Manager. Enable our app here.
Then your alarm/ alarmmanager will trigger alarm if the app is killed or closed.
回答12:
I were looking for an answer and after several hours I found this:
https://stackoverflow.com/a/35220476/3174791
In resume is way to know if your app was killed by 'Protected apps' and this only works on Huawei devices. let me know if there is any solution for other devices (Samsung,Sony,Xiaomi, etc).
回答13:
i stopped using AlarmManager a while ago... a better and more stable alternative
- create a service
- register a BroadcastReceiver for BOOT_COMPLETED
- fire your service from the receiver
- start a new Handler inside your service that loop itself every X minutes (Android - running a method periodically using postDelayed() call)
- check if time to execute the task has come: now - execution time > 0 (How to find the duration of difference between two dates in java?)
- if so.. execute the task and stop the handler
yes.. it's a pain..but the job get done NO MATTER WHAT