15. 如何请求忽略电池优化:REQUEST_IGNORE_BATTERY_OPTIMIZATIONS权限
嗯,这一节我们来聊聊一个让很多开发者又爱又恨的权限——REQUEST_IGNORE_BATTERY_OPTIMIZATIONS。说白了,它就是让App能绕过Doze模式限制的“通行证”。
我在项目中遇到过不少次,产品经理跑过来说:“我们的IM应用怎么收不到推送了?” 我一查,好家伙,被Doze模式给“掐断”了。这时候,这个权限就成了一个可能的解决方案。
15.1 这个权限到底是什么?
先别急着写代码。我们得搞清楚,这个权限的本质是什么。
Android从6.0(API 23)开始引入了Doze模式。系统会限制后台网络、延迟Alarm、禁止WakeLock。而REQUEST_IGNORE_BATTERY_OPTIMIZATIONS权限,就是让App告诉系统:“嘿,别优化我,我有特殊需求。”
核心要点:这个权限不是让你“禁用”Doze,而是让你的App被列入“白名单”。系统仍然会进入Doze,但你的App可以正常使用网络、Alarm和WakeLock。
15.2 权限声明与请求流程
好,我们来看看具体怎么操作。分两步走:声明权限 + 发起请求。
15.2.1 在Manifest中声明
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
这一步很简单,但要注意:这只是声明你有资格去请求,不代表系统会自动给你授权。
15.2.2 检查并请求权限
我个人习惯在App启动时或者关键功能入口处检查。比如,一个导航App,用户开始导航时,就应该请求这个权限。
// 检查是否已被忽略电池优化
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (pm != null && !pm.isIgnoringBatteryOptimizations(packageName)) {
// 需要请求权限
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivityForResult(intent, REQUEST_CODE_IGNORE_BATTERY_OPTIMIZATIONS);
}
小提示:请求时一定要带上intent.setData(Uri.parse("package:" + packageName))。如果不带,系统会弹出一个列表让用户自己选App,体验很差。我刚开始就踩过这个坑。
15.3 什么时候该用?什么时候不该用?
你想想看,Google设计Doze模式就是为了省电。如果每个App都请求忽略优化,那Doze就形同虚设了。所以,Google Play对使用这个权限有严格限制。
| 场景 | 是否推荐使用 | 说明 |
|---|---|---|
| 即时通讯/推送 | 谨慎使用 | 建议优先使用FCM(Firebase Cloud Messaging)高优先级推送 |
| 导航/地图 | 推荐使用 | 导航过程中需要持续定位和网络,Doze会严重影响体验 |
| 音乐/播客播放 | 不推荐 | 使用前台服务即可,不需要这个权限 |
| 运动/健康追踪 | 视情况而定 | 如果是后台持续记录,可以考虑;如果是前台运动,用前台服务即可 |
| 普通工具类App | 绝对不要用 | 滥用会导致应用被下架 |
警告:Google Play审核非常严格。如果你的App不属于“核心功能需要持续后台运行”的类型,提交审核时大概率会被拒。我曾经有一个项目,因为用了这个权限做后台数据同步,被Google Play打回来三次,最后不得不改用WorkManager。
15.4 核心逻辑流程图
下面这张图,我画的是整个请求流程的核心逻辑。你看一遍就能明白,从检查到请求,再到用户选择,每一步都环环相扣。
15.5 用户拒绝后怎么办?
这是很多开发者忽略的地方。用户点了“拒绝”,然后呢?
我曾经见过一些App,用户拒绝后就不停地弹窗请求,结果被用户直接卸载。这种做法非常不推荐。
我的建议是:
- 不要反复弹窗。用户拒绝后,至少等一周再考虑再次请求。
- 提供降级方案。比如,如果用户拒绝忽略电池优化,你可以引导用户使用前台服务,或者使用WorkManager的约束条件来保证任务执行。
- 做好用户教育。在请求前,先弹一个说明对话框,告诉用户为什么需要这个权限,以及不授权会有什么影响。
重要提醒:从Android 11开始,系统对ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS的响应做了调整。即使用户在系统设置中手动将App加入白名单,你的App也无法通过isIgnoringBatteryOptimizations()检测到。嗯,这一点坑了不少人,我在做Android 11适配时就发现了这个变化。
15.6 替代方案:不用权限也能干活
说实话,我个人不太建议轻易使用这个权限。能用替代方案,就尽量用替代方案。
| 需求场景 | 替代方案 | 优点 |
|---|---|---|
| 定时任务 | WorkManager + 约束条件 | 系统自动管理,省电且可靠 |
| 推送消息 | FCM高优先级推送 | 即使Doze也能唤醒设备短暂处理 |
| 后台定位 | 前台服务 + 通知 | 用户可见,系统不会限制 |
| 后台播放 | 前台服务 + 媒体会话 | 标准做法,兼容性好 |
| 短时后台任务 | JobScheduler | 系统会合并任务,减少唤醒次数 |
我的经验:在大多数情况下,前台服务 + 合适的通知,就能解决90%的“后台被限制”问题。只有像导航、VoIP通话这类真正需要持续后台运行的应用,才值得去请求这个权限。
15.7 总结一下
这个权限,说白了就是一把双刃剑。用好了,能保证核心功能正常运行;用不好,既费电又可能被应用商店下架。
我的建议是:先想清楚你的App是不是真的需要。如果确实需要,那就按照规范流程来请求,并且做好用户拒绝后的降级方案。如果不需要,千万别滥用。
嗯,关于这个权限的内容就讲到这里。记住,尊重用户的电池,就是尊重用户的选择。
公众号:蓝海资料掘金营,微信deep3321