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

Android 12下悬浮窗无法穿透点击遮挡下层界面问题修复

问题根因

Android 12(API 31)针对TYPE_APPLICATION_OVERLAY类型悬浮窗加了一套未写入公开开发文档的隐式安全拦截规则:当应用退到后台时,系统窗口管理服务会扫描所有应用持有的悬浮窗参数,如果窗口尺寸为全屏、同时携带FLAG_LAYOUT_NO_LIMITS/FLAG_LAYOUT_IN_SCREEN这类可突破显示边界的布局标记,会直接忽略FLAG_NOT_TOUCHABLE的触摸透传设置,把窗口标记为可接收触摸事件的阻塞层,拦截下层所有交互。这是Android12版本引入的已知AOSP实现缺陷,直到Android 12L、Android13才逐步修复。

你当前的代码刚好触发了这个拦截规则:应用在前台时系统不会触发后台安全扫描,交互完全正常;一旦最小化退到后台,扫描触发后触摸透传失效,就会出现全界面被拦截、只能重启设备的问题。

可直接落地的修复方案
  • 调整悬浮窗LayoutParams的flag组合,移除触发拦截的冗余标记,修改后的核心参数代码如下:
val params = WindowManager.LayoutParams(
    WindowManager.LayoutParams.MATCH_PARENT,
    WindowManager.LayoutParams.MATCH_PARENT,
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
        WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY
    else WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
    // 移除FLAG_LAYOUT_NO_LIMITS、FLAG_LAYOUT_IN_SCREEN两个触发拦截的标记
    WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
            or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
            or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
            or WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR,
    PixelFormat.TRANSLUCENT
)
  • 监听应用前后台切换状态,每次应用切到后台时,主动调用windowManager.updateViewLayout()重新给悬浮窗设置一遍包含FLAG_NOT_TOUCHABLE的参数,强制刷新系统记录的窗口标记,避免系统扫描时重置触摸透传属性。
  • 适配手势导航区域:Android12及以上版本,给悬浮窗设置24dp的底部margin,避开底部手势导航条的交互区域,视觉上几乎不会影响滤镜效果,同时能避免触发系统对全屏遮挡类悬浮窗的恶意行为检测。
开发建议
  • 配置常驻通知栏控制入口,提供一键关闭滤镜的按钮,既符合Google Play对悬浮窗类应用的合规要求,也能在极端异常场景下让用户无需重启就能关闭悬浮层。
  • Android12及以上版本不要给全屏悬浮窗加FLAG_LAYOUT_NO_LIMITS标记,这个标记会让系统直接把窗口判定为高风险遮挡类窗口,除了触摸拦截问题,还会触发系统反复弹出悬浮窗安全提醒。
  • 可以增加音量键快捷关闭逻辑:滤镜开启时监听音量键按下事件,用户按动音量键时自动关闭悬浮层,进一步降低异常场景下的用户操作成本。

内容的提问来源于stack exchange,提问作者faisal ur rehman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 17:12:29