如何在 Android 中防止截屏

How to prevent Screen Capture in Android

是否可以在Android应用程序中阻止屏幕录制?

我想开发一个 Android 安全应用程序。因为我需要检测 运行 后台的屏幕录制软件并杀死它们。我使用 SECURE FLAG 来防止截屏。但我不知道是否也可以阻止 Android 屏幕的视频捕获。让我知道如何防止截屏(视频/屏幕截图)。

我要说的是不可能完全阻止screen/video通过支持的方式捕获任何android应用程序。但是,如果您只想为 普通 android 设备阻止它,则 SECURE FLAG 是重要的。

1) 安全标志确实阻止了正常的屏幕截图和视频捕获。

Also documentation at this link says that

Window flag: treat the content of the window as secure, preventing it from appearing in screenshots or from being viewed on non-secure displays.

以上解决方案肯定会阻止应用程序捕获您的应用程序的视频

查看答案

2) 有多种捕获屏幕内容的方法。

可以在已获取 root 权限的设备上或通过使用 SDK 捕获另一个应用程序的屏幕,

which both offer little to no chance of you either blocking it or receiving notification of it.

例如:存在可通过 SDK 将您的 phone 屏幕镜像到您的计算机的软件,因此可以在那里使用屏幕捕获软件,而您的应用无法发现它。

查看答案here

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

只需添加这一行:

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

在您的 setContentView() 方法之前。

试试这个:

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

您可以将您的应用设置为 device/profile 所有者并调用 setScreenCaptureDisabled()。从 docs 开始,此 api 执行以下操作:

public void setScreenCaptureDisabled (ComponentName admin, boolean disabled) Added in API level 21

Called by a device/profile owner to set whether the screen capture is disabled. Disabling screen capture also prevents the content from being shown on display devices that do not have a secure video output. See FLAG_SECURE for more details about secure surfaces and secure displays.

The calling device admin must be a device or profile owner. If it is not, a security exception will be thrown. Parameters admin Which DeviceAdminReceiver this request is associated with. disabled Whether screen capture is disabled or not.

或者您可以成为 MDM(Mobile Device Management) 合作伙伴 app.OEMs 为他们的 MDM 合作伙伴应用程序提供额外的 API 来控制 device.For 示例三星提供 api 来控制屏幕录制将设备发送给他们的 MDM 合作伙伴。

目前这是您可以强制执行屏幕捕获限制的唯一方法。

根据此 official guide,您可以将 WindowManager.LayoutParams.FLAG_SECURE 添加到您的 window 布局,它将禁止屏幕截图。

要禁用屏幕捕获:

onCreate() 方法中添加以下代码行:

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

启用屏幕截图:

查找 LayoutParams.FLAG_SECURE 并删除代码行。

关于照片截图, FLAG_SECURE root 设备不工作。

但是如果你监控截图文件,你可以防止获取原始文件。

试试这个 one

1. 使用 android 远程服务监控截图(文件监控)
2.删除原来的截图图片。
3.交付位图实例,以便您修改。

对于 Java 用户 将此行写在 setContentView(R.layout.activity_main);

上方
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);

对于 kotlin 用户

window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)

我使用此解决方案允许在应用程序中手动快照,同时在应用程序进入后台时禁止屏幕捕获,希望它能有所帮助。

@Override
protected void onResume() {
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
    super.onResume();
}

@Override
protected void onPause() {
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
    super.onPause();
}

我看到了所有仅适用于单个 activity 的答案,但我的解决方案将阻止所有活动的屏幕截图,而无需向 activity 添加任何代码。首先制作一个自定义应用程序 class 并添加一个 registerActivityLifecycleCallbacks。然后在您的清单中注册它。

MyApplicationContext.class

public class MyApplicationContext extends Application {
    private  Context context;
    public void onCreate() {
        super.onCreate();
        context = getApplicationContext();
        setupActivityListener();
    }

    private void setupActivityListener() {
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);            }
            @Override
            public void onActivityStarted(Activity activity) {
            }
            @Override
            public void onActivityResumed(Activity activity) {

            }
            @Override
            public void onActivityPaused(Activity activity) {

            }
            @Override
            public void onActivityStopped(Activity activity) {
            }
            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
            }
            @Override
            public void onActivityDestroyed(Activity activity) {
            }
        });
    }



}

清单

 <application
        android:name=".MyApplicationContext"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

在 MainActivity (Xamarin) 的 OnCreate 事件中添加此行

Window.SetFlags(WindowManagerFlags.Secure, WindowManagerFlags.Secure);
public class InShotApp extends Application {
    
        @Override
        public void onCreate() {
            super.onCreate();
            registerActivityLifecycle();
        }
    
        private void registerActivityLifecycle() {
    
            registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
                @Override
                public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
                    activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);            }
    
                @Override
                public void onActivityStarted(@NonNull Activity activity) {
    
                }
    
                @Override
                public void onActivityResumed(@NonNull Activity activity) {
    
                }
    
                @Override
                public void onActivityPaused(@NonNull Activity activity) {
    
                }
    
                @Override
                public void onActivityStopped(@NonNull Activity activity) {
    
                }
    
                @Override
                public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
    
                }
    
                @Override
                public void onActivityDestroyed(@NonNull Activity activity) {
    
                }
            });
    
        }
    }

关于阻止在应用程序中截图的可能性:

Window window = requireActivity().getWindow();
window.addFlag(WindowManager.LayoutParams.FLAG_SECURE);

记得清除此标志(f.e。在 onDestroy 中)- 在应用程序的其他安全位置启用屏幕截图:

window.clearFlags(WWindowManager.LayoutParams.FLAG_SECURE);