Detect a screenshot Android
Asked Answered
T

3

17

I program in recent years to Android and I wonder something : How to detect when user take a screenshot ? I want that when the user takes a screenshot , we move to the next activity . I tried the method of intercepting an event but there is a problem : when the device goes into sleep , for example, an event is intercepted . Do you have a solution for intercepts only the event of screenshot or ignore other event?

Thank you for your help !

Triable answered 9/4, 2015 at 7:34 Comment(0)
A
19

There is no direct Broadcast Intent to tell you that a screenshot has been taken. Some people here discuss possible options to do so ( like it's done on Snapchat ). One possible option would be to use FileObserver.

Ashtray answered 9/4, 2015 at 7:53 Comment(4)
I tried this method of intercepting an event but there is a problem : when the device goes into sleep , for example, an event is intercepted . Do you have a solution for intercepts only the event of screenshot or ignore other event?Triable
You're thinking about Intents. You have a list of all of them here But unfortunately there isn't one for screenshot detection. You should look into FileObserver like mentioned on the reddit link. I can't guaranty it works, but the idea would be to observe the folder where the screenshots are saved into.Ashtray
Could you elaborate on how to use the FileObserver to detect screenshots? The Reddit link suggests that there is not one uniform destination for screenshots. Also, I don't think the naming conventions are always the same. So, given that and my limited understanding of FileObserver, how exactly would one go about detecting a screenshot?Galangal
How does Tinder know when I'm taking a screnshot? I noticed that when you screenshot profile it pops share button. Tinder does not have access to files or mediafiles on my phone.Mcfarlane
A
12

Here is my hack to get notified when a screenshot is taken.

public void detectScreenShotService(final Activity activity){

   final Handler h = new Handler();
   final int delay = 3000; //milliseconds
   final ActivityManager am=(ActivityManager)activity.getSystemService(Context.ACTIVITY_SERVICE);

    h.postDelayed(new Runnable(){
        public void run(){

            List<ActivityManager.RunningServiceInfo> rs=am.getRunningServices(200);

            for(ActivityManager.RunningServiceInfo ar:rs){
                if(ar.process.equals("com.android.systemui:screenshot")){
                    Toast.makeText(activity,"Screenshot captured!!",Toast.LENGTH_LONG).show();
                }
            }
            h.postDelayed(this, delay);
        }
    }, delay);

}

Tested on Oneplus 2 and Moto E.

Update:

This finally didn't work for me and i ended up using a ContentObserver on screenshot type of entries.

Ascension answered 24/10, 2016 at 12:49 Comment(5)
ur code works but how to get the path of screenshot ?Babylonia
Theoretically, what you can do is set a watcher on screenshots folder and whenever this event triggers, get the list of files and see the last created file which should be your screenshot file.Ascension
@MizAkita The above code doesn't work always. It triggers screenshots event multiple times and so is inaccurate. I ended up using ContentObserver for media files and detect if the last file is screenshot or not and thus detecting it. Incase you want to use the above code, if you want to use this thing in an activity, then deploy it on the onResume method and stop its detection onPause method of activity lifecycle.Ascension
Yeah I confirm the code in the answer works 1/4 of the timeInspirit
getSystemService is deprecated as of Build.VERSION_CODES.O Any alternatives?Galangal
S
1

Since Android 14 (in beta at the time of writing this), you don't need any hack to detect screenshots, you can do so by using the ScreenCaptureCallback.

Implement a callback by overriding the onScreenCapture() function.

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

In the activity's onStart() method, register the screenshot callback.

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)
}

In the activity's onStop() method, unregister the screnshot callback:

override fun onStop() {
    super.onStop()
    unregisterScreenCaptureCallback(screenCaptureCallback)
}
Schwinn answered 17/4, 2023 at 18:13 Comment(1)
Here is a link to the Android documentation with this solution: developer.android.com/about/versions/14/features/…Ofay

© 2022 - 2025 — McMap. All rights reserved.