
本文详解如何通过配置 AndroidManifest.xml、使用 PowerManager.WakeLock 唤醒屏幕,并结合 Window 标志与 KeyguardManager,实现在锁屏状态下无缝展示自定义 Activity(如 Firebase 推送触发的来电界面)。
本文详解如何通过配置 `androidmanifest.xml`、使用 `powermanager.wakelock` 唤醒屏幕,并结合 `window` 标志与 `keyguardmanager`,实现在锁屏状态下无缝展示自定义 activity(如 firebase 推送触发的来电界面)。
在 Android 开发中,当应用需在设备锁屏时立即响应高优先级事件(例如 VoIP 来电、紧急通知),仅靠普通 Intent 启动 Activity 是不够的——系统默认会阻止前台界面覆盖锁屏。要实现“锁屏即显”的效果,需协同完成三方面配置:清单声明、唤醒控制、窗口权限适配。
✅ 1. 清单文件配置(必备)
在 AndroidManifest.xml 中为目标 Activity(如 IncomingCall)添加关键属性:
<activity android:name=".IncomingCall" android:exported="false" android:launchmode="singleInstance" android:showonlockscreen="true">
android:screenOrientation="sensorPortrait" /></activity>
⚠️ 注意:android:showOnLockScreen="true" 是 Android 5.0+ 的推荐方式,替代已废弃的 FLAG_SHOW_WHEN_LOCKED,但需配合代码层逻辑才能可靠生效。
✅ 2. 唤醒设备并启动 Activity
在接收 Firebase 消息(如 onMessageReceived())或后台服务中,执行以下操作:
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
"myalarmapp:alarm"
);
wl.acquire(5000); // 保持唤醒 5 秒,确保 Activity 完全启动
Intent intent = new Intent(this, IncomingCall.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
wl.release(); // 及时释放 WakeLock,避免耗电
? ACQUIRE_CAUSES_WAKEUP 是关键:它不仅维持 CPU 运行,还会点亮屏幕并解锁锁屏(需用户已设置“允许在锁屏显示通知”)。
✅ 3. 目标 Activity 内部适配锁屏状态
在 IncomingCall.java 的 onCreate() 中,根据 SDK 版本选择兼容方案:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true); // 允许在锁屏显示
setTurnScreenOn(true); // 自动点亮屏幕
KeyguardManager km = getSystemService(KeyguardManager.class);
if (km != null && km.isKeyguardLocked()) {
km.requestDismissKeyguard(this, null); // 解锁锁屏(需声明 USE_KEYGUARD 权限)
}
} else {
Window window = getWindow();
window.addFlags(
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
);
}
setContentView(R.layout.activity_incoming_call);
}
? 权限补充说明:
需在 AndroidManifest.xml 中声明:
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission><uses-permission android:name="android.permission.DISABLE_KEYGUARD"></uses-permission><uses-permission android:name="android.permission.POST_NOTIFICATIONS"></uses-permission><!-- Android 13+ -->
⚠️ 注意事项与最佳实践
- 电池优化豁免:部分厂商(华为、小米等)会限制后台唤醒,需引导用户手动关闭电池优化。
-
通知渠道优先级:Firebase 高优先级通知(
priority=high,notification_priority=max)更易触发前台行为。 -
Android 12+ 限制:自 Android 12 起,
FLAG_SHOW_WHEN_LOCKED和setShowWhenLocked()在部分场景下被进一步限制,建议搭配NotificationCompat.Builder的setFullScreenIntent()使用(需用户授予“全屏通知”权限)。 - 用户体验:务必提供明确的挂断/接听控件,并支持音量键、电源键响应,避免用户误触无法退出。
通过以上三步整合,即可稳定实现锁屏状态下的 Activity 弹出,适用于实时通信、安防告警等强交互场景。











