Android 14 is coming very soon – if you haven’t had a chance yet to check out the changelog, there are a bunch of required changes and new APIs available in this Android release.
One of these new APIs is the Screenshot Detection API, which allows apps to reliably check when a screenshot has been captured. While this might sound like a bit of a niche scenario at first, there are several situations where this would be deemed useful. These may include:
- Messaging apps that might want to notify users when another user screenshots their conversation
- Paid content apps that need to detect when users are capturing screenshots of content
- Apps that need to track when screenshots are being captured of certain content to help drive product decisions
It’s important to note that this mechanism simply gives you awareness that a screenshot was captured, it doesn’t give you access to the screenshot itself.
To start here, we need to add a new permission to our application manifest file. When declaring this permission, you can declare the minSdkVersion as the permission will not be used by any Android version earlier than 34 (Upside Down Cake). This permission will allow our application to detect when screenshots are being captured.
<uses-permission android:minSdkVersion="34" android:name="android.permission.DETECT_SCREEN_CAPTURE" />
Now that we have this permission in place, we need to start by declaring the listener that will be used to detect when screenshots are captured. This takes the form of ScreenCaptureCallback which is a callback that will be triggered whenever a screenshot is captured, within the scope of where that callback has been registered.
private val screenCaptureCallback = ScreenCaptureCallback {
// handle screenshot
}
Now that we have this callback in place, we need to register it within the screen it is being used. In the case of an activity, we’re going to use the registerScreenCaptureCallback function within the startup of our activity. Remember that if targeting lower than API 34, this will need to be wrapped in an API level check.
override fun onStart() {
super.onStart()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
registerScreenCaptureCallback(mainExecutor, screenCaptureCallback)
}
}
Alongside registering this callback, we’ll also need to unregister this callback when finished with it. We’ll do this using the unregisterScreenCaptureCallback function during the teardown of our activity.
override fun onStop() {
super.onStop()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
unregisterScreenCaptureCallback(screenCaptureCallback)
}
}
With this above in place, we now have a mechanism that allows us to detect when screenshots are captured in our application. It’s important to remember that in the above example, this is on a per-activity basis, so screenshots are only being detected that this listener is being registered in. If you wish to capture screenshots in multiple places, then you will need to handle these additional places.
Alongside the above, if you wish to block screenshots in your app then you can simply use the following code to apply the secure flag to your activity, which will block screenshots from being taken.
When using this, it’s helpful to provide some kind of notice to the user when they do attempt to take a screen. Otherwise, it can be a confusing experience as to why the screenshot capture is not functioning.
window.setFlags(FLAG_SECURE, FLAG_SECURE)
In this post we’ve taken a look at one of the new APIs coming with Android 14, the screenshot detection API. Using this new API, we can learn more about our users behaviour and react accordingly. I’ll be taking a look at more of the Android 14 APIs soon, so stay tuned for more reading to help you keep up-to-date with changes coming in Android.