Skip to main content

Detecting Screenshots

warning

Screenshot detection is only available in API level 34 (Android 14) or higher.

Android 14 introduces a way to detect a screenshot performed by user.

Limitation

This method only detects specific combination of hardware button presses (most commonly Power and Volume-down buttons). Here's a table summarizing the limitation of this method:

Screenshot MethodSpecific MethodCan be detected?
Hardware button presses
With emulator⛔️
With logcat⛔️
With Android Debug Bridge (adb)screencap command⛔️
KEYCODE_SYSRQ keyevent
Programmatically⛔️
Within instrumented testingDeviceCapture API⛔️
captureToImage or captureToBitmap API⛔️

Basic Usage

First, you need to declare DETECT_SCREEN_CAPTURE install-time permission inside your AndroidManifest.xml file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

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

</manifest>

To start detecting screenshots, you need to utilize these 3 key components within your Activity:

  1. Activity.ScreenCaptureCallback: The screenshot detection callback that you need to define.
  2. registerScreenCaptureCallback: This method registers your screenshot detection callback.
  3. unregisterScreenCaptureCallback: This method unregisters your screenshot detection callback.

Here is a simple example of such Activity:

MainActivity.kt
package com.hanmajid.androidnotebook

import android.app.Activity.ScreenCaptureCallback
import android.os.Build
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import com.hanmajid.androidnotebook.ui.theme.AndroidNotebookTheme

class MainActivity : ComponentActivity() {
private val screenCaptureCallback = ScreenCaptureCallback {
Toast.makeText(this, "A screenshot is taken!", Toast.LENGTH_LONG).show()
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContent {
AndroidNotebookTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Text("Android")
}
}
}
}

override fun onStart() {
super.onStart()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
registerScreenCaptureCallback(
mainExecutor,
screenCaptureCallback
)
}
}

override fun onStop() {
super.onStop()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
unregisterScreenCaptureCallback(screenCaptureCallback)
}
}
}

Here's what happen when we take a screenshot:

You will notice that after the screenshot was taken, 2 things happen:

  1. My Application detected this screenshot. message appears below the screenshot preview. I believe this is the default behavior when an Activity uses the screen detection API.
  2. A screenshot is taken! toast appears. This is the callback that we define within our Activity. You can fill this callback with whatever you need in your app.

References