Android 13设置FLAG_SECURE后截屏提示Toast不显示如何解决
问题说明
你当前使用FLAG_SECURE实现屏幕捕获拦截的代码逻辑是正确的,该标记从Android Honeycomb版本开始生效,可正常阻止页面内容被截屏、录屏采集:
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE) }
Android 13(API 33)移除了拦截截屏时的系统默认Toast,仅生成黑色无效缩略图的问题,可以通过官方提供的截屏检测API实现自定义提示,不需要额外申请权限,适配成本极低。
具体实现方案
Android 13及以上版本适配
直接使用系统原生提供的ScreenCaptureCallback回调即可,该回调会在用户触发截屏操作时立即触发,与页面是否设置FLAG_SECURE无关,你可以在回调中弹出任意自定义提示(自定义Toast、Snackbar、轻量弹窗都可以)。
需要注意回调必须和Activity/Fragment生命周期绑定注册、注销,避免内存泄漏,实现代码如下:
public class SecureActivity extends AppCompatActivity { // 定义截屏捕获回调 private final ScreenCaptureCallback captureCallback = () -> { // 替换为你需要的自定义提示文案、样式即可 Toast.makeText(this, "当前页面涉及隐私内容,不允许截屏哦", Toast.LENGTH_SHORT).show(); }; @Override protected void onStart() { super.onStart(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { // 注册回调,绑定主线程执行器 getWindow().getDecorView().registerScreenCaptureCallback( getMainExecutor(), captureCallback ); } } @Override protected void onStop() { super.onStop(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { // 页面不可见时注销回调,防止内存泄漏 getWindow().getDecorView().unregisterScreenCaptureCallback(captureCallback); } } }
Android 12及以下版本兼容
该版本区间的系统在FLAG_SECURE生效拦截截屏时,会默认弹出系统自带的「无法捕获屏幕,内容受DRM保护」提示,不需要额外添加适配逻辑。
避坑说明
- 不推荐使用监听媒体存储目录新增文件的旧方案检测截屏:这类方案需要申请存储权限,适配分区存储逻辑复杂,同时存在检测延迟高、容易误判其他应用保存图片的问题,稳定性远低于官方回调。
ScreenCaptureCallback仅能检测用户按下物理按键、系统快捷方式触发的普通截屏行为,无法检测ADB命令、root环境下的强制截屏,但这类场景本身FLAG_SECURE已经可以保证截获的页面内容为纯黑色,不会泄露实际信息。
内容的提问来源于stack exchange,提问作者BryanB
相关产品推荐
相关产品推荐

