|
|
用户提问:调研安卓防止息屏的方案,一般方案可以了,但是红米小米手机无论怎么弄都没有效果,全网深度调研一下。有没有人解决过这个问题
AI深度调研回复:
一、通用方案(标准Android)
方案1:FLAG_KEEP_SCREEN_ON(最推荐)
// Activity中
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// 或XML布局
android:keepScreenOn="true"
- 优点:不需要WAKE_LOCK权限,系统自动管理生命周期
- 缺点:仅Activity前台有效
方案2:View.setKeepScreenOn(true)
view.setKeepScreenOn(true);
某个View可见时生效,不需要权限
方案3:WakeLock(PowerManager)
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "MyApp:Tag");
wl.acquire();
// 使用完毕
wl.release();
- 需要权限:<uses-permission android:name="android.permission.WAKE_LOCK"/>
- 注意:SCREEN_BRIGHT_WAKE_LOCK 已被标记deprecated
方案4:Settings.System.STAY_ON_WHILE_PLUGGED_IN
Settings.Global.putInt(getContentResolver(), Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB);
- 需要WRITE_SETTINGS权限,影响全局
方案5:前台服务 + WakeLock组合
适用于后台场景保持屏幕亮。
二、小米/红米(MIUI/HyperOS)核心问题
为什么小米/红米上所有标准方案都无效?
根因:MIUI的激进省电策略(神隐模式/应用冻结)
MIUI在以下层面覆盖了标准Android的电源管理行为:
1. MIUI应用启动管理:即使APP在前台,如果MIUI判定该应用"不重要",会忽略FLAG_KEEP_SCREEN_ON
2. 省电模式:即使关闭系统省电模式,MIUI的"应用智能省电"仍会独立生效
3. 神隐模式(Ghost Mode):后台限制极其激进,甚至影响前台行为
4. 开发者选项中的"MIUI优化":开启状态下会修改标准API行为
小米/红米专用解决方案
方案A:关闭MIUI优化(关键!)
这是被最多开发者验证有效的方案:
1. 设置 -> 我的设备 -> 全部参数信息 -> 连续点击"MIUI版本/HyperOS版本"7次 -> 开启开发者选项
2. 设置 -> 更多设置 -> 开发者选项
3. 关闭"启用MIUI优化"(Turn off MIUI Optimization)
4. 重启手机
5. 重启后FLAG_KEEP_SCREEN_ON和WakeLock恢复正常
注意:关闭MIUI优化会弹出警告,但不会变砖。可能影响小米钱包等极少数功能。
方案B:修改应用的省电策略(不关闭MIUI优化)
1. 设置 -> 应用设置 -> 应用管理 -> 找到你的APP
2. 省电策略 -> 选择"无限制"(无限制/不限制)
3. 自启动 -> 开启
4. 后台弹窗 -> 允许
方案C:代码层面多重保险(组合拳)
针对小米设备,建议叠加使用:
// 1. FLAG_KEEP_SCREEN_ON
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// 2. View级别
View rootView = findViewById(android.R.id.content);
rootView.setKeepScreenOn(true);
// 3. WakeLock(虽然官方说不需要,但MIUI需要)
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "MyApp:KeepScreenOn");
wakeLock.acquire(60 * 60 * 1000L); // 1小时超时保护
// 4. 关键:写入Settings(如果用户授权)
if (Settings.System.canWrite(this)) {
Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, Integer.MAX_VALUE);
}
方案D:前台服务 + Full WakeLock(终极方案)
对于必须在小米设备上常亮的场景:
// AndroidManifest.xml
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
// 启动前台服务,持有WakeLock
PowerManager.WakeLock fullWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "MyApp:FullScreen");
fullWakeLock.acquire();
注意:SCREEN_BRIGHT_WAKE_LOCK虽然已deprecated,但在MIUI上比FLAG_KEEP_SCREEN_ON更有效,因为WakeLock走的是底层PowerManager,MIUI更难拦截。
方案E:引导用户手动设置(兜底)
在APP中检测到小米设备后,弹窗引导用户:
1. 开发者选项 -> 关闭"MIUI优化"
2. 或者:设置 -> 应用设置 -> 你的APP -> 省电策略 -> 无限制
3. 或者:设置 -> 锁屏 -> 自动锁屏 -> 设为"永不"
三、各方案成功率对照表
FLAG_KEEP_SCREEN_ON -> 普通安卓:有效 / 小米MIUI:经常无效 / 备注:MIUI会忽略
View.setKeepScreenOn -> 普通安卓:有效 / 小米MIUI:经常无效
WakeLock SCREEN_BRIGHT -> 普通安卓:有效 / 小米MIUI:部分有效 / 备注:比FLAG好一些
关闭MIUI优化 + FLAG_KEEP_SCREEN_ON -> 小米MIUI:有效 / 备注:最可靠
前台服务 + WakeLock组合 -> 普通安卓:有效 / 小米MIUI:较有效
四、结论和建议
有人解决过这个问题吗?—— 有。 核心就两点:
1. 关闭MIUI优化是最被广泛验证的解决方案(XDA论坛、GitHub Issues、StackOverflow均有讨论)
2. 代码层面要做多重保险:FLAG_KEEP_SCREEN_ON + WakeLock + 前台服务,不能只用单一方案
对于App Inventor 2应用场景,建议:
- 在Screen.Initialize中同时设置FLAG_KEEP_SCREEN_ON和WakeLock
- 如果是给少儿教学用,建议在开课时引导家长关闭MIUI优化(最可靠)
- 如果不方便引导用户,用前台服务+WakeLock组合方案的成功率最高
--- App Inventor 2 中文网
|
|