Android 系统锁屏监听与悬浮窗实现指南
在 Android 应用开发中,有时需要在用户锁屏状态下执行特定任务,例如闹钟响铃、安全监控或紧急通知。这涉及到两个核心技术点:如何准确监听系统的屏幕状态变化,以及如何在不干扰用户正常解锁流程的前提下弹出悬浮窗口。本文将详细解析这两个环节的实现原理、代码实践及注意事项。
一、如何监听系统屏幕锁屏
监听屏幕状态是基础,主要有两种方式:通过系统 API 直接轮询判定,或通过广播接收器被动接收系统事件。推荐优先使用广播方式,因为它更省电且响应及时。
1. 代码直接判定
通过系统服务获取当前屏幕状态,适用于需要即时判断的场景。
a) PowerManager 检测
PowerManager 提供了 isScreenOn() 方法,用于判断屏幕是否处于点亮状态。
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
// 如果为 true,则表示屏幕'亮'了,否则屏幕'暗'了。
boolean isScreenOn = pm.isScreenOn();
状态说明:
- 屏幕'亮':包含两种情况,a) 未锁屏(桌面可见);b) 已解锁但屏幕保持开启。这两种状态下
isScreenOn均为true。 - 屏幕'暗':表示屏幕熄灭,通常意味着设备进入休眠或锁屏界面显示前。
b) KeyguardManager 检测
KeyguardManager 提供了 inKeyguardRestrictedInputMode() 方法,专门用于判断是否处于锁屏输入模式。
KeyguardManager mKeyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
boolean flag = mKeyguardManager.inKeyguardRestrictedInputMode();
状态说明:
- flag 为 true:表示屏幕是黑的,或者正处于锁屏密码/图案输入界面。
- flag 为 false:表示目前未锁屏,用户可以自由操作。
注意:上述方法在不同 Android 版本中表现一致,但在高版本系统中,建议结合广播使用以提高准确性。部分旧代码可能涉及反射调用,现代开发中应直接使用公开 API。
2. 接收广播
当安卓系统发生锁屏、屏幕亮起或解锁时,会发送相应的广播。这是最标准且推荐的方式。
注册广播的伪代码如下:
private ScreenBroadcastReceiver mScreenReceiver;
{
;
{
action = intent.getAction();
(Intent.ACTION_SCREEN_ON.equals(action)) {
} (Intent.ACTION_SCREEN_OFF.equals(action)) {
} (Intent.ACTION_USER_PRESENT.equals(action)) {
}
}
}
{
();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
context.registerReceiver(mScreenReceiver, filter);
}


