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

Android全局禁用截图与录屏的正确实现方法咨询

Android全局禁用截图与录屏的正确实现方法咨询

嗨,我来帮你梳理下这个问题~

首先你提到的第一种方法:

getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);

确实只能作用于当前的Activity或者App,没办法覆盖全局,这是因为FLAG_SECURE本质上是给单个Window设置的标记,只对所属的Window生效。

然后你贴的那段用TYPE_SYSTEM_OVERLAY的代码,出现错误大概率是因为权限和系统版本的问题:

  • 首先,TYPE_SYSTEM_OVERLAY在Android 8.0(API 26)之后已经被废弃了,取而代之的是TYPE_APPLICATION_OVERLAY,如果还用旧的类型,在高版本系统上会直接抛出异常。
  • 其次,悬浮窗权限是必须的,你需要在Manifest里声明权限,而且在Android 6.0+(API 23)之后,还需要引导用户手动开启这个权限(跳转到应用设置页面让用户授权)。
  • 另外,那段代码里的View只是一个空的LinearLayout加View,还存在逻辑漏洞,比如没有正确处理WindowManager的生命周期,容易导致内存泄漏。

那全局禁用截图录屏的正确思路是什么呢?其实核心还是利用FLAG_SECURE,但要给覆盖整个屏幕的全局悬浮Window设置这个标记,这样整个屏幕都会受到保护。

下面是修正后的可行代码示例:

1. 声明权限

在AndroidManifest.xml里添加权限:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

2. 动态申请悬浮窗权限(针对API 23+)

在启动全局悬浮窗之前,先检查并申请权限:

private boolean checkOverlayPermission(Context context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (!Settings.canDrawOverlays(context)) {
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:" + context.getPackageName()));
            context.startActivity(intent);
            return false;
        }
    }
    return true;
}

3. 创建全局覆盖Window并设置FLAG_SECURE

private void createSecureOverlay(Context context) {
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    // 创建一个铺满屏幕的透明View
    View secureView = new View(context);
    secureView.setBackgroundColor(Color.TRANSPARENT);

    WindowManager.LayoutParams params;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
                WindowManager.LayoutParams.FLAG_SECURE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSPARENT
        );
    } else {
        params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                WindowManager.LayoutParams.FLAG_SECURE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSPARENT
        );
    }
    // 设置布局在屏幕最底层,不影响其他操作
    params.gravity = Gravity.TOP | Gravity.LEFT;
    try {
        wm.addView(secureView, params);
    } catch (Exception e) {
        e.printStackTrace();
        // 这里可以处理添加失败的情况,比如权限未授予
    }
}

额外注意事项

  • 这个透明的悬浮窗会覆盖整个屏幕,但我们设置了FLAG_NOT_TOUCHABLE和FLAG_NOT_FOCUSABLE,所以不会影响用户正常操作其他App。
  • 当你的App退出时,记得调用wm.removeView(secureView)来移除这个悬浮窗,避免内存泄漏。
  • 部分定制化ROM可能会限制这种全局悬浮窗的功能,需要做兼容性测试。

备注:内容来源于stack exchange,提问作者ANDuser

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 09:24:31