You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 21:47:34