Android O中FLAG_SHOW_WHEN_LOCKED废弃后,如何实现亮屏并显示悬浮窗
Android O (API 27) 替代
FLAG_TURN_SCREEN_ON 和 FLAG_SHOW_WHEN_LOCKED 的方案 针对你在Android O上面临的悬浮窗亮屏问题,我来给你梳理下官方推荐的替代方案,以及如何修改你的代码:
1. 替代 FLAG_TURN_SCREEN_ON:使用 PowerManager.wakeUp()
从API 23开始,官方就推荐用PowerManager.wakeUp()来直接唤醒屏幕,而不是依赖Window的FLAG。这个方法需要在清单中声明WAKE_LOCK权限:
<uses-permission android:name="android.permission.WAKE_LOCK"/>
调用方式很简单,获取PowerManager实例后直接调用:
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); if (powerManager != null) { // 传入当前时间戳,唤醒屏幕 powerManager.wakeUp(System.currentTimeMillis()); }
2. 替代 FLAG_SHOW_WHEN_LOCKED 和 FLAG_TURN_SCREEN_ON:View级别的Setter方法
从API 27开始,Android提供了View的两个方法来替代对应的FLAG:
setShowWhenLocked(true):让View在锁屏状态下显示setTurnScreenOn(true):触发屏幕点亮(配合wakeUp效果更稳定)
这两个方法需要在你添加View到WindowManager之前调用。
修改后的完整代码示例
结合你的现有代码,调整后如下:
private void showView() { // 1. 唤醒屏幕(替代FLAG_TURN_SCREEN_ON) PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); if (powerManager != null && !powerManager.isInteractive()) { // 仅在屏幕未点亮时触发唤醒 powerManager.wakeUp(System.currentTimeMillis()); } // 2. 获取WindowManager并创建布局参数 windowManager = (WindowManager) context.getSystemService(WINDOW_SERVICE); final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 0, 0, WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, // 移除废弃的FLAG,保留其他必要的 WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, PixelFormat.RGBA_8888); // 3. 构建View并设置锁屏显示和亮屏属性 RelativeLayout layout = buildView(); // API 27+ 替代FLAG_SHOW_WHEN_LOCKED和FLAG_TURN_SCREEN_ON if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { layout.setShowWhenLocked(true); layout.setTurnScreenOn(true); } // 4. 添加并更新View windowManager.addView(layout, layoutParams); windowManager.updateViewLayout(layout, layoutParams); // 处理WakeLock(保持屏幕常亮) if (!wakeLockAcquired) { wakeLock.acquire(); wakeLockAcquired = true; // 修正了你原代码中的变量名拼写错误 } }
关键说明
- 为什么之前的代码不生效?因为Android O开始,
FLAG_TURN_SCREEN_ON和FLAG_SHOW_WHEN_LOCKED这两个FLAG对TYPE_APPLICATION_OVERLAY类型的窗口不再生效,必须使用View级别的Setter方法。 - 权限检查:确保你不仅申请了
SYSTEM_ALERT_WINDOW,还添加了WAKE_LOCK权限,并且在运行时已经获取了悬浮窗权限(Android 6.0+需要用户手动开启)。 - 变量名修正:你原代码里
wakeLockAquired拼写错误,示例中已经修正为wakeLockAcquired。
内容的提问来源于stack exchange,提问作者Elior
相关产品推荐
相关产品推荐

