在 Telegram 进行截图时会遇到下面的报错:

扩展阅读:关于 Telegram 的一些事

原因是 Telegram 利用了 Android 提供的 API,拿到 Window 对象,对其添加了一个 FLAG_SECURE 的 flag。

完整的代码如下:

1 getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);

这里的 window 对象,可以是 Activity.getWindow() 获取的,也可以是 Dialog.getWindow() 获取的,获取 Window 的方式很多。使用不同对象获取到的 Window 对象,禁用截屏的区域也不同。

大部分情况下,Android 官方都推荐使用这种方法禁用掉系统截屏的功能。

FLAG_SECUREWindowManager.LayoutParams 的一个属性,从文档可以看出,它标记当前 Window 是安全的,不允许有一些非安全的操作,例如截屏功能。

FLAG_SECURE 基本上可以保证我们显示的内容的安全性。但是有一些情况下,FLAG_SECURE 依然会有一些截屏泄露的情况。

因为 FLAG_SECURE 是应用在 Window 对象上的,如果在 Activity 中有一些弹窗或者突出的 UI 元素,都是不受 Activity 的 Window 对象保护的。例如:在 Activity 中弹出对话框,虽然 Activity 被设置为 FLAG_SECURE,但是如果有一个 Dialog 弹窗,对于弹窗的内容,依然需要单独设置 FLAG_SECURE

这些会出现截屏泄露的地方包括:

AutoCompleteTextView
Spinner(下拉菜单或者对话框模式中)
PopupWindow
ShareActionProvider
Toast

这些只是一部分,可能还有其他的地方也会造成截屏泄露。

下面展示一个在 @CommonsWare 博客中找到的 gif 图,可以清晰表明在这些情况下,依然是可以截取到内容的,所以我们在有重要信息需要隐藏的时候,要特别注意这些场景下也别暴露重要信息。

可以看到,在一个被设置为 FLAG_SECURE 的页面中,有些设备上依然会截取出黑色的画面,而这些导致截屏泄露的点,依然是可以截取到图像的。

破解截图

解决方法是刷入 Xposed 然后安装 DisableFlagSecure 模块。

BlockSecureFlag 模块 v1.4 在 MIUI 开发版测试无效。