How to prevent Screen Capture in Android
Asked Answered
B

16

192

Is it possible to prevent the screen recording in Android Application?

I would like to develop an Android Secure Application. In that I need to detect screen recording software which are running background and kill them. I have used SECURE FLAG for prevent screenshots. But I dont know is it possible to prevent Video capturing of Android Screen also. Let me know how to prevent screen capturing (video / screenshots).

Brewery answered 19/2, 2015 at 12:40 Comment(2)
- You should remember one can always point a camera on the screen to steal the content - There some techniques used in the DRM field but they are pretty complex and I don't really know what's going on under the hoodPlacer
The concept that @ShaiLevy explains, is usually called Analog Hole en.wikipedia.org/wiki/Analog_hole which explains the innevitable security hole of media transmission.Lipetsk
N
207

I'm going to say that it is not possible to completely prevent screen/video capture of any android app through supported means. But if you only want to block it for normal android devices, the SECURE FLAG is substantial.

1) The secure flag does block both normal screenshot and video capture.

Also documentation at this link says that

Window flag: treat the content of the window as secure, preventing it from appearing in screenshots or from being viewed on non-secure displays.

Above solution will surely prevent applications from capturing Video of your app

See the answer here.

2) There are alternative means of capturing screen content.

It may be possible to capture the screen of another app on a rooted device or through using the SDK,

which both offer little to no chance of you either blocking it or receiving notification of it.

For example: there exists software to mirror your phone screen to your computer via the SDK and so screen capture software could be used there, undiscoverable by your app.

See the answer here.

getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
Normally answered 14/7, 2015 at 12:15 Comment(6)
or one can simply click image with handheld camera.Undersell
small hint WindowManager.LayoutParams.FLAG_SECURE is full signature as there are multiple LayoutParamsMismanage
hi, where we can add this lineTwiddle
Whats about to mute audio also because it stop only video recording not audio of video.Mahican
Anything that can be seen can be recorded. But the first solution is good enough for 90% of the cases.Fourdimensional
is there any possibility of allowing screenshot capturing and disabling screen recordingDispassionate
F
103

Just add this line:

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

Before your setContentView() method.

Figural answered 16/7, 2015 at 13:17 Comment(3)
Question : [quote]I have used SECURE FLAG[unquote] Your "answer" : [quote]You can use FLAG_SECURE[unqote] Can you spot a problem here ?Choking
Hi,I am developing a web based portal application. The users may use any kind of browsers to reach this portal. The users of this portal should not take the screenshots when they are using mobile devices. Can I use the same precautions (etWindow().setFlags(LayoutParams.FLAG_SECURE,LayoutParams.FLAG_SECURE);) for the web application. Does it work for IOS? If I can use the same type of precautions where should I call this line?Entertaining
There is no need to do this before setContentView()Hessler
M
41

I saw all of the answers which are appropriate only for a single activity but there is my solution which will block screenshot for all of the activities without adding any code to the activity. First of all make an Custom Application class and add a registerActivityLifecycleCallbacks.Then register it in your manifest.

MyApplicationContext.class

public class MyApplicationContext extends Application {
    private  Context context;
    public void onCreate() {
        super.onCreate();
        context = getApplicationContext();
        setupActivityListener();
    }

    private void setupActivityListener() {
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);            }
            @Override
            public void onActivityStarted(Activity activity) {
            }
            @Override
            public void onActivityResumed(Activity activity) {

            }
            @Override
            public void onActivityPaused(Activity activity) {

            }
            @Override
            public void onActivityStopped(Activity activity) {
            }
            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
            }
            @Override
            public void onActivityDestroyed(Activity activity) {
            }
        });
    }



}

Manifest

 <application
        android:name=".MyApplicationContext"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
Mauldin answered 10/6, 2019 at 10:49 Comment(3)
I tried of of my project then it worked for all activitys. @gopalanrcMauldin
Very good Salution...Its generic way ..coolWillard
If you need to do something for all activities in the app, better solution is creating BaseActivity and inherit other activities from it.Skinner
S
38

To disable Screen Capture:

Add following line of code in onCreate() method:

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

To enable Screen Capture:

Find for LayoutParams.FLAG_SECURE and remove the line of code.

Sphalerite answered 13/10, 2016 at 10:5 Comment(0)
B
30

For Java users write this line above your setContentView(R.layout.activity_main);

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

For kotlin users

window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
Bouffard answered 25/11, 2018 at 14:55 Comment(3)
for kotlin, depending on the context, that should be window?.set... because on Dialogs, you don't know if you're going to have a Window.Myiasis
The original question already said they've used secure flag and your answer is to use secure flag. This doesn't really answer the question posted.Despotic
i added like this in mainActivity.java but not working @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Window.SetFlags(WindowManagerFlags.Secure, WindowManagerFlags.Secure);Youngstown
R
12

You can make your app as device/profile owner and call setScreenCaptureDisabled(). From the docs, this api does the following:

public void setScreenCaptureDisabled (ComponentName admin, boolean disabled) Added in API level 21

Called by a device/profile owner to set whether the screen capture is disabled. Disabling screen capture also prevents the content from being shown on display devices that do not have a secure video output. See FLAG_SECURE for more details about secure surfaces and secure displays.

The calling device admin must be a device or profile owner. If it is not, a security exception will be thrown. Parameters admin Which DeviceAdminReceiver this request is associated with. disabled Whether screen capture is disabled or not.

Alternatively you can become an MDM(Mobile Device Management) partner app.OEMs provides additional APIs to their MDM partner apps to control the device.For example samsung provides api to control screen recording on the device to their MDM partners.

Currently this is the only way you can enforce screen capture restrictions.

Rubicon answered 20/7, 2015 at 15:56 Comment(2)
any example in java or xamarin please ?Linnlinnaeus
Please help sir https://mcmap.net/q/136713/-how-to-use-setscreencapturedisabled-xamarin/11390822Linnlinnaeus
T
11

Try this:

getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
Thermo answered 17/7, 2015 at 10:20 Comment(3)
Question : [quote]I have used SECURE FLAG[unquote] Your "answer" : [quote]You can use FLAG_SECURE[unqote] Can you spot a problem here ?Choking
Window flag: treat the content of the window as secure, preventing it from appearing in screenshots or from being viewed on non-secure displays. See FLAG_SECURE for more details about secure surfaces and secure displays. Constant Value: 8192 (0x00002000) Read more from here developer.android.com/reference/android/view/…Thermo
Please don't deface your post by rolling back our improvementsKyrakyriako
N
8

I used this solution to allow manual snapshot in app while disallowing screen capture when the app goes in background, hope it helps.

@Override
protected void onResume() {
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
    super.onResume();
}

@Override
protected void onPause() {
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
    super.onPause();
}
Nayarit answered 4/2, 2019 at 9:43 Comment(0)
R
3

According to this official guide, you can add WindowManager.LayoutParams.FLAG_SECURE to your window layout and it will disallow screenshots.

Rotorua answered 21/7, 2015 at 1:36 Comment(0)
D
3

Ad this line inside the OnCreate event on MainActivity (Xamarin)

Window.SetFlags(WindowManagerFlags.Secure, WindowManagerFlags.Secure);
Draft answered 13/11, 2020 at 1:59 Comment(0)
G
3

Kotlin users can add following code in Application class to prevent app screenshots

    class MyApplication : Application() {
    
    override fun onCreate() {
      
        super.onCreate()
       
        registerActivityLifecycle()
       
    }

    private fun registerActivityLifecycle() {
        registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
            override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
                activity.window.setFlags(
                    WindowManager.LayoutParams.FLAG_SECURE,
                    WindowManager.LayoutParams.FLAG_SECURE
                )
            }

            override fun onActivityStarted(activity: Activity) {}
            override fun onActivityResumed(activity: Activity) {}
            override fun onActivityPaused(activity: Activity) {}
            override fun onActivityStopped(activity: Activity) {}
            override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
            override fun onActivityDestroyed(activity: Activity) {}
        })
    }
}
Glottic answered 9/2, 2023 at 12:12 Comment(0)
G
2
public class InShotApp extends Application {
    
        @Override
        public void onCreate() {
            super.onCreate();
            registerActivityLifecycle();
        }
    
        private void registerActivityLifecycle() {
    
            registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
                @Override
                public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
                    activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);            }
    
                @Override
                public void onActivityStarted(@NonNull Activity activity) {
    
                }
    
                @Override
                public void onActivityResumed(@NonNull Activity activity) {
    
                }
    
                @Override
                public void onActivityPaused(@NonNull Activity activity) {
    
                }
    
                @Override
                public void onActivityStopped(@NonNull Activity activity) {
    
                }
    
                @Override
                public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
    
                }
    
                @Override
                public void onActivityDestroyed(@NonNull Activity activity) {
    
                }
            });
    
        }
    }
Gringo answered 12/2, 2021 at 16:23 Comment(0)
T
2

Regarding to blocking the possibility of taking a screenshot in the application:

Window window = requireActivity().getWindow();
window.addFlag(WindowManager.LayoutParams.FLAG_SECURE);

remember to clean this flag (f.e. in onDestroy) - to enable screenshots in other safe places of the app:

window.clearFlags(WWindowManager.LayoutParams.FLAG_SECURE);
Thorton answered 4/2, 2022 at 12:26 Comment(0)
I
1

about photo screenshot, FLAG_SECURE not working rooted device.

but if you monitor the screenshot file, you can prevent from getting original file.

try this one.

1. monitoring screenshot(file monitor) with android remote service
2. delete original screenshot image.
3. deliver the bitmap instance so you can modify.

Inevasible answered 17/2, 2017 at 2:55 Comment(0)
U
0

For those that have to disable screenshots and are using Jetpack Compose this is what you need:

fun Activity.disableScreenshots() {
  window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
}

fun Activity.enableScreenshots() {
  window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
}

@Composable
fun DisableScreenshots() {
  val context = LocalContext.current
  DisposableEffect(Unit) {
    context.getActivity()?.disableScreenshots()
    onDispose {
      context.getActivity()?.enableScreenshots()
    }
  }
}

Then just invoke DisableScreenshots from your composable function ;)

Udale answered 7/9, 2022 at 11:27 Comment(0)
T
0

Easy and elegant:

import android.view.WindowManager.LayoutParams;

// ...

@Override
public void onWindowFocusChanged(boolean isFocused) {
  if (isFocused) {
    getWindow().clearFlags(LayoutParams.FLAG_SECURE);
  } else {
    getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
  }
  super.onWindowFocusChanged(isFocused);
}
Tunny answered 29/12, 2022 at 12:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.