Android 8(Oreo)锁屏且屏幕关闭时来电识别视图无法显示问题
解决Android 8锁屏下来电悬浮窗不显示的问题
我之前也碰到过一模一样的情况!这是Android 8.0(API Level 26)对系统窗口权限做了严格限制导致的——普通悬浮窗类型在锁屏+屏幕关闭的状态下,根本没法覆盖系统原生的来电锁屏界面。下面是我亲测有效的解决方案:
一、调整WindowManager的参数配置
这是最关键的一步!在创建WindowManager.LayoutParams的时候,必须针对Android 8及以上版本做特殊适配:
WindowManager.LayoutParams params = new WindowManager.LayoutParams( WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, // Android 8+要用TYPE_APPLICATION_OVERLAY替代旧的TYPE_SYSTEM_ALERT Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, // 这几个flags缺一不可,确保窗口能在锁屏显示、点亮屏幕 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT );
这里划重点:
TYPE_APPLICATION_OVERLAY是Android 8开始官方推荐的悬浮窗类型,旧的TYPE_SYSTEM_ALERT在锁屏场景下权限不够FLAG_SHOW_WHEN_LOCKED直接让窗口能穿透锁屏显示FLAG_TURN_SCREEN_ON必须加!不然屏幕处于关闭状态时,就算窗口创建了也看不到FLAG_DISMISS_KEYGUARD可以帮你自动解锁无密码的锁屏,或者引导用户解锁有密码的锁屏
二、补全权限申请流程
除了你已经申请的悬浮窗权限,Android 8及以上还需要单独申请TYPE_APPLICATION_OVERLAY对应的权限,代码里要引导用户去系统设置开启:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (!Settings.canDrawOverlays(context)) { Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + context.getPackageName())); context.startActivity(intent); } }
注意:这个权限没法自动获取,必须用户手动在设置里开启,我们只能做跳转引导。
三、避免Service被后台杀死
Android 8的后台限制很严格,如果你用来添加窗口的Service被系统杀死,那肯定没法显示视图。建议:
- 把这个Service设为前台服务,启动时调用
startForeground(),避免被系统回收 - 在接收来电广播的时候,用
startForegroundService()启动Service(Android 8+强制要求)
四、测试时要注意这些细节
测试的时候一定要模拟真实场景:
- 确保设备开启了锁屏(不管是图案、PIN还是密码锁屏都要测)
- 手动关闭屏幕,然后用另一台设备打进来,检查自定义视图是否能覆盖原生来电界面
补充一句:Android 8对系统窗口的层级管理比之前严格太多,原生来电界面属于系统级的锁屏窗口,只有参数和权限都配置到位,你的自定义视图才能显示在它上面。
内容的提问来源于stack exchange,提问作者Fivos
相关产品推荐
相关产品推荐

