Android使用MediaProjection截屏时如何检测应用SECURE_FLAG
检测目标应用窗口是否设置
FLAG_SECURE的实现方法 常见误区:不要尝试解析目标应用的AndroidManifest文件判断是否设置安全标记,
FLAG_SECURE是运行时通过Window.addFlags()动态给单个页面窗口设置的,多数应用仅在支付、隐私信息展示、版权视频播放等特定页面开启该标记,不存在全局静态配置可以读取。
受安卓跨进程窗口权限隔离限制,普通第三方应用无法直接读取其他应用的窗口布局参数,可根据自身持有的权限等级选择对应检测方案:
方案1:通过无障碍服务检测(普通应用推荐,准确率高)
该方案不需要root,仅需要用户授权无障碍服务权限即可,支持Android 5.1(API 22)及以上系统:
- 首先在应用内实现自定义
AccessibilityService,在配置文件中声明需要监听窗口状态变化事件 - 在服务的事件回调中,通过系统返回的
AccessibilityWindowInfo直接读取窗口的安全标记位,参考实现代码如下:
class ScreenCaptureDetectService : AccessibilityService() { override fun onAccessibilityEvent(event: AccessibilityEvent?) { event ?: return // 仅在窗口切换时检测 if (event.eventType != AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) return // 遍历当前所有窗口,找到聚焦的前台应用主窗口 val targetWindow = windows.firstOrNull { window -> window.isFocused && window.type == AccessibilityWindowInfo.TYPE_APPLICATION } ?: return // 检测FLAG_SECURE标记位 val isSecureWindow = (targetWindow.flags and AccessibilityWindowInfo.FLAG_SECURE) != 0 if (isSecureWindow) { // 业务逻辑:当前窗口不允许截屏,可提前终止截屏流程、弹出提示 } } override fun onInterrupt() {} }
- 注意:API 22以下的系统版本没有提供
AccessibilityWindowInfo.FLAG_SECURE字段,这部分版本占比极低,可直接做降级兼容处理。
方案2:无特殊权限兜底检测(零权限要求)
如果不想申请无障碍权限,可以基于截屏结果做内容检测,不需要任何额外权限,兼容性覆盖所有系统版本:
- 调用MediaProjection、VirtualDisplay完成截屏后,从
ImageReader中拿到输出的Image对象并转换为Bitmap - 对Bitmap做均匀采样,比如取横纵各10个共100个采样点,统计纯黑像素(ARGB值为
0xFF000000)的占比 - 如果采样点纯黑占比超过95%,排除当前系统为暗色模式、前台页面本身为纯黑设计的场景后,即可判定当前窗口设置了
FLAG_SECURE,截屏结果为黑屏 - 该方案缺点是存在小概率误判,适合对准确率要求不高的场景。
方案3:高权限场景检测(准确率100%)
如果你的应用拥有root权限,或者是经过系统签名的预装应用,可以直接通过以下方式拿到准确结果:
- 通过反射调用系统
WindowManagerGlobal的内部接口,跨进程获取前台窗口的WindowManager.LayoutParams - 直接检查布局参数的flags字段中
WindowManager.LayoutParams.FLAG_SECURE位是否置1
该方案不存在误判,但仅适合系统类应用使用,普通第三方应用无权限调用相关接口。
合规提示:所有绕过
FLAG_SECURE强制截取受保护页面内容的行为,都违反安卓平台的隐私保护规则,也可能触犯相关数据合规、版权保护的法规,检测到该标记后建议主动终止截屏流程,并向用户给出明确提示。
内容的提问来源于stack exchange,提问作者Divyang M
相关产品推荐
相关产品推荐

