Android 23锁屏状态下闹钟界面闪屏且无法稳定显示的解决方案咨询
我之前在做闹钟应用的时候也踩过Android 6.0(API23)锁屏兼容的坑,和你遇到的现象一模一样——界面弹出后闪一下就没,解锁还会丢图案。结合你的代码来看,确实是API23下Window Flag组合的系统兼容问题,给你几个亲测有效的解决方案:
方案1:拆分Window Flag设置时机,针对API23延迟添加锁屏显示标记
API23下同时批量设置多个Window Flag会触发系统内部的冲突逻辑,导致界面被意外回收。我们可以拆分设置步骤,先完成亮屏、全屏的操作,再延迟添加锁屏显示的标记:
requestWindowFeature(Window.FEATURE_NO_TITLE); Window window = getWindow(); // 先设置全屏、亮屏、解锁核心标记 window.setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON, WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON ); if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) { // 针对API23延迟100ms添加锁屏显示标记,让系统先完成亮屏解锁流程 window.getDecorView().postDelayed(() -> { window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); }, 100); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { setShowWhenLocked(true); setTurnScreenOn(true); KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); if (keyguardManager != null && keyguardManager.isKeyguardLocked()) { keyguardManager.requestDismissKeyguard(this, null); } } else { // 其他版本正常添加锁屏显示标记 window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); }
方案2:改用API23旧版锁屏解锁API替代FLAG_DISMISS_KEYGUARD
API23下FLAG_DISMISS_KEYGUARD和FLAG_SHOW_WHEN_LOCKED的组合稳定性较差,我们可以用已废弃但仍能正常工作的disableKeyguard()方法来处理锁屏解锁:
requestWindowFeature(Window.FEATURE_NO_TITLE); Window window = getWindow(); // 先设置全屏、亮屏、锁屏显示标记 window.setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED, WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED ); if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) { KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); if (keyguardManager != null && keyguardManager.isKeyguardLocked()) { KeyguardManager.KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("AlarmLock"); keyguardLock.disableKeyguard(); // 记得在Activity销毁时重新启用锁屏,避免系统锁屏失效 window.getDecorView().addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { @Override public void onViewAttachedToWindow(View v) {} @Override public void onViewDetachedFromWindow(View v) { keyguardLock.reenableKeyguard(); } }); } } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { setShowWhenLocked(true); setTurnScreenOn(true); KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); if (keyguardManager != null && keyguardManager.isKeyguardLocked()) { keyguardManager.requestDismissKeyguard(this, null); } } else { window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); }
方案3:通过Manifest配置简化代码逻辑(优先推荐)
从API23开始,Android允许在Manifest中直接配置Activity的锁屏相关属性,这样可以减少代码中手动设置Flag的冲突,让逻辑更简洁:
首先在Manifest的AlarmActivity标签中添加以下属性:
<activity android:name=".AlarmActivity" android:showOnLockScreen="true" android:showWhenLocked="true" android:turnScreenOn="true" android:excludeFromRecents="true" android:launchMode="singleTop"/>
然后简化AlarmActivity中的代码:
requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) { KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); if (keyguardManager != null && keyguardManager.isKeyguardLocked()) { KeyguardManager.KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("AlarmLock"); keyguardLock.disableKeyguard(); // 销毁时恢复锁屏 getWindow().getDecorView().addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { @Override public void onViewAttachedToWindow(View v) {} @Override public void onViewDetachedFromWindow(View v) { keyguardLock.reenableKeyguard(); } }); } } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { // 这里可以重复设置,确保高版本兼容 setShowWhenLocked(true); setTurnScreenOn(true); KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); if (keyguardManager != null && keyguardManager.isKeyguardLocked()) { keyguardManager.requestDismissKeyguard(this, null); } }
以上三个方案都能解决API23下的闪屏和锁屏图案消失问题,优先推荐方案3,因为Manifest配置更符合Android的设计规范,代码也更简洁易维护。
内容的提问来源于stack exchange,提问作者beginner
相关产品推荐
相关产品推荐

