检测用户何时截取设备屏幕截图

Message reads 'Pay app detected this screenshot'
图 1. 当用户截取支持屏幕截图检测 API 的应用屏幕截图时,系统提供的浮动消息示例。

为了创建更标准化的屏幕截图检测体验,Android 14 引入了保护隐私的屏幕截图检测 API。此 API 允许应用针对每个 Activity 注册回调。当用户在该 Activity 可见时截取屏幕截图,这些回调将被调用,并且用户会收到通知。

支持的用例

在 Android 14 中,系统 API 仅在用户执行特定的硬件按钮组合时检测屏幕截图。此 API 不会检测在运行与屏幕截图相关的测试命令(包括 ADB)时,或在 捕获设备当前屏幕内容 的插桩测试中截取的屏幕截图。

实现步骤

要添加屏幕截图检测功能,请声明新的 DETECT_SCREEN_CAPTURE 安装时权限

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

然后,为应用中用户可能截取屏幕截图的每个 Activity 完成以下步骤

  1. 通过重写 onScreenCapture() 函数来实现回调。在此回调中,您的应用可以执行操作,例如警告其他用户有人截取了消息对话的屏幕截图。

    Kotlin

    val screenCaptureCallback = Activity.ScreenCaptureCallback {
        // Add logic to take action in your app.
    }

    Java

    final Activity.ScreenCaptureCallback screenCaptureCallback =
        new Activity.ScreenCaptureCallback() {
            @Override
            public void onScreenCaptured() {
                // Add logic to take action in your app.
            }
        };
  2. 在 Activity 的 onStart() 方法中,注册屏幕截图回调。

    Kotlin

    override fun onStart() {
        super.onStart()
        // Pass in the callback created in the previous step 
        // and the intended callback executor (e.g. Activity's mainExecutor).
        registerScreenCaptureCallback(mainExecutor, screenCaptureCallback)
    }

    Java

    @Override
    protected void onStart() {
        super.onStart();
        // Pass in the callback created in the previous step 
        // and the intended callback executor (e.g. Activity's mainExecutor).
        registerScreenCaptureCallback(executor, screenCaptureCallback);
    }
  3. 在 Activity 的 onStop() 方法中,取消注册屏幕截图回调

    Kotlin

    override fun onStop() {
        super.onStop()
        unregisterScreenCaptureCallback(screenCaptureCallback)
    }

    Java

    @Override
    protected void onStop() {
        super.onStop();
        unregisterScreenCaptureCallback(screenCaptureCallback);
    }

控制截取屏幕截图的能力

如果您不希望应用 Activity 的内容出现在屏幕截图或非安全显示器上,请设置 FLAG_SECURE 显示标志。

Kotlin

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

Java

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