Detect when users take device screenshots

Message reads 'Pay app detected this screenshot'
Figure 1. An example of the system-provided toast message that appears when the user takes a screenshot of an app that supports the screenshot detection API.

To create a more-standardized experience for detecting screenshots, Android 14 introduces a privacy-preserving screenshot detection API. This API lets apps register callbacks on a per-activity basis. These callbacks are invoked, and the user is notified, when the user takes a screenshot while that activity is visible.

Supported use cases

In Android 14, the system API only detects a screenshot if the user performs a specific combination of hardware button presses. The API doesn't detect screenshots that are taken when running test commands related to screenshots, including ADB, or within instrumentation tests that capture the device's current screen contents.

Implementation steps

To add screenshot detection, declare the new DETECT_SCREEN_CAPTURE install-time permission:

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

Then, complete these steps for each activity in your app where users might capture screenshots:

  1. Implement a callback by overriding the onScreenCapture() function. In this callback, your app can take action, such as warning another user that someone took a screenshot of a messaging conversation.

    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. In the activity's onStart() method, register the screenshot callback.

    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. In the activity's onStop() method, unregister the screenshot callback:

    Kotlin

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

    Java

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

Control ability to capture screenshots

If you don't want the contents of an app's activity to appear in screenshots, or on non-secure displays, set the FLAG_SECURE display flag.

Kotlin

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

Java

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