How do I prevent Android taking a screenshot when my app goes to the background?
Asked Answered
I

8

169

The app I'm currently building has the requirement that the app has to prevent the OS to take a screenshot of the app when it's being pushed into the background for security reasons. This way it won't be able to see the last active screen when switching between apps.

I'm planning to put this functionality in the application class's onPause method, but first I need to find out how I can achieve this functionality.

So is there anybody out there, that has a clue how to fix this?

Intelligentsia answered 22/3, 2012 at 12:14 Comment(0)
T
304

Try FLAG_SECURE:

public class FlagSecureTestActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

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

    setContentView(R.layout.main);
  }
}

This definitely secures against manual screenshots and automatic screenshots from the ICS recent-tasks history. It also secures against screen recording (e.g., apps using the media projection APIs).

UPDATE: it also secures against Now On Tap or other assistants on Android 6.0; they will not get access to the details of widgets and containers in your UI if the user brings up the assistant.

UPDATE #2: however, not everything in the activity will be protected. Any pop-up windows — Dialog, Spinner, AutoCompleteTextView, action bar overflow, etc. — will be insecure. You can fix the Dialog problem by calling getWindow() on it and setting FLAG_SECURE. The rest... gets tricky. See this blog post for more.

Tipster answered 22/3, 2012 at 12:48 Comment(33)
@Dany's: Actually, it has everything to do with the question. I just tested it on a Nexus S (4.0.3), and it works as expected -- the recent-tasks screenshot is suppressed. You still see the application name and icon, but the screenshot is black. You are welcome to try it on ICS hardware.Tipster
Thanks, will take a look, any idea if this will also work with the backwards compatibility package?Intelligentsia
@StingRay5: FLAG_SECURE has existed since the beginning -- it just had limited meaning until recently.Tipster
Interesting to note that there is a method called onCreateThumbnail ni the activity lifecycle, but it's never used.Lamellicorn
@Tipster How can I check if LayoutParams.FLAG_SECURE is set or not. Actually I set LayoutParams.FLAG_SECURE to restrict screen-capture, and I wrote a code to take screen shot, and I am able to take screenshot. So can you please tell that how can I verify that ?Forlini
@PankajKumar: If the "code to take screen shot" that you wrote is that classic "grab the framebuffer as root" trick, FLAG_SECURE won't defend against that, as that's too low-level. Similarly, if you took your own widget hierarchy and had it draw to a Bitmap-backed Canvas, FLAG_SECURE probably won't defend against that, as you are taking your own screenshots of your own widgets and therefore presumably wanted the "secure" ones in there. FLAG_SECURE is for system screenshots, such as the recent-tasks thumbnails.Tipster
Ok. I got the point. Is there any way where I can check if FLAG_SECURE is set or not?Forlini
@PankajKumar: For your own window, you should know if FLAG_SECURE is set or not, as you are the one setting it. If you are writing some framework and therefore do not know if a Window has FLAG_SECURE or not, in theory you should be able to find it in the getAttributes() result, though I have never tried this. And, if you are referring to a window from some other process, I doubt that an SDK app can find out if a window has FLAG_SECURE or not.Tipster
Wonderful and simple answer! I'm wondering why apps like snapchat don't use this to prevent someone taking a screenshot of the images sent.Apostrophize
@Tipster Hope you are doing well. I have one more issue related to secure flag. I set this flag as you given into answer, and it was working well before KitKat. In KitKat, if I press power+volumn_down and rotate device, able to take screen-shot. Is this bug into KitKat? Or there is another method to set secure flag? Please update me.Forlini
@Tipster Actually this issue doesn't come into 4.3. So is this a bug into KitKat? As per your given link its look like this is device specific, right?Forlini
@PankajKumar: I am saying that I have attempted to reproduce this issue and have been unable to do so (see comment #4 on the issue report).Tipster
Any idea how I can prevent Android from taking a screenshot when it goes to the background, but allow users to take a screenshot manually? I've posted another question: #28874133Galer
@Tipster Can i display custom photo instead of auto screenshots in recent application list?Rheum
@DhavalKhant: You can try onCreateThumbnail(), though I have not tried it personally: developer.android.com/reference/android/app/…Tipster
Just to add the package, because it took me a short while: WindowManager.LayoutParams.FLAG_SECURESudderth
This doesn't work reliably on Android 5.1, see code.google.com/p/android/issues/detail?id=169933Which
Yep, apparently there are some bugs, another ticket opened here: code.google.com/p/android-developer-preview/issues/…Waikiki
Is there a way to set this in Xamarin? I could not reach FLAG_SECURE parameter.Gulden
@EmrahAkgül: I can barely spell Xamarin. :-) You are better served asking a separate Stack Overflow question, with the appropriate Xamarin tag, asking how to use it.Tipster
Thank you for the "UPDATE #2", It would not occurred to me.Barra
@EmrahAkgül or anyone else wondering for Xamarin : Window.SetFlags(WindowManagerFlags.Secure, WindowManagerFlags.Secure);Lx
@AjayMistry: FLAG_SECURE is working as expected for me on a Samsung Galaxy S8 running Android 7.0, in landscape mode.Tipster
@Tipster :I triend it but it doesn't work...instead it works fine in portrait mode but when I change it to landscape mode it record the screen.. what i have to do to achieve this??Parcae
@AjayMistry: Contact the device manufacturer, as they have a bug.Tipster
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE); doesn't work for Android Pie.Efthim
@user1182217: It worked fine for me this morning, in a test on a Google Pixel running Android 9.0 (Pie). Feel free to provide a link to a sample project which can reproduce your problems on Android 9.0.Tipster
@CommonsWare: I tried in One Plus device having Android Pie (9.0). How ever FLAG_SECURE works fine below 9.0.Efthim
@user1182217: Then perhaps the problem is with that particular device model.Tipster
@CommonsWare: Yes, you are right. In pixel it's working fine. Problem is with One Plus device model. Thanks.Efthim
you could also look into some possible improvements over FLAG_SECUREPinky
just wanted to point out that that's not a full answer. There should also be an import at the top of the MainActivitiy.java file, -> import android.view.WindowManager; and you only need to add this part getWindow().setFlags( WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE );Aigrette
@Tipster Also have a look at my question too. https://mcmap.net/q/139097/-restrict-overlay-in-android/4134215Virtues
K
81

Be careful about using WindowManager.LayoutParams.FLAG_SECURE, on some devices (verified on Samsung Galaxy ACE, e.g. GT-S5830) this will make the view scrambled. Looks like a Samsung specific bug. I recommend the following:

if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
}

This is what a scrambled screen looks like:

Scrambled Screen Image

This is working properly on ICS Samsung phones though, so I'm assuming problem is isolated to Gingerbread devices (or older).

Krum answered 20/6, 2012 at 14:33 Comment(6)
You're totally right, we came across this issue, and it certainly was needed to check for the API level. Actually forgot to post this, so thanks for bringing it up again. :)Intelligentsia
It also occurs on Samsung Gio (Gingerbread) but on Froyo its ok - so it occurs only on 2.3Clap
We noticed this problem as well. You can verify in the Emulator on Gingerbread devices.Trottier
I can also confirm that this problem appears on Samsung Gingerbread devices.Romano
Even on newer Android versions FLAG_SECURE can be problematic: on Android 4.3 FLAG_SECURE causes animation problems in screen rotation animation, see code.google.com/p/android/issues/detail?id=58632 - this has been fixed on Android 4.4Proser
Hi... i need to block screenshot for particular activity. but your code suppress the screenshot for whole app.Crinkleroot
P
13

The solution provided by CommonsWare continues to be valid also in Lollipop.

Just a note, if you want to continue to not see snapshots in recent list for the entire app, ALL the implemented activities should specify in the onCreate() method the flag getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); before setContentView();

Otherwise a snapshot in the recent list will show the first activity without the flag if the user navigated through it.

Plaudit answered 20/3, 2015 at 10:39 Comment(4)
In my app, I have functionality of setting/clearing FLAG_SECURE based on a user preference. It worked fine till KITKAT and black screen can be seen in task switcher. In Lollipop, the Overview displays the last snapshot of my app, the time when FLAG_SECURE was not set(cleared).Runic
@Runic i think we can't do so much in that case, but you can advice the user that, the change needs App to be restarted to take fully effect ;-) and you are done.Plaudit
Anyone found a way to inflate a custom view before snapshot is taken so it's not just a black screen? I've tried inflating a view on window manager in onPause, but it seems by then it's too late.Granniah
Hi @Granniah Have you found any solution? I want inflate the Launcher View before the OS take the screenshotSpline
A
6

In case if someone is looking for a solution in which the app must secure (screen overlay) when the app is background or stick of all running app and the in-app app should allow screenshot. Try Below:-

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

    @Override
    protected void onPause() {
        super.onPause();
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
    }
Amboina answered 31/5, 2021 at 10:18 Comment(1)
Exactly what I was looking for, thanks! One can also call addFlags() instead of setFlags(), which makes it even easier.Clavicembalo
S
5

As of Android 13, there is a new way to prevent a screenshot being taken for the recent apps list, while still allowing the user to take screenshots while using the app. In your main activity, call setRecentsScreenshotEnabled(false).

Sanatorium answered 10/10, 2022 at 19:17 Comment(0)
J
3

Here is a solution for hiding content of an app by covering it with a splash screen when the app is put into the background. This is not using the FLAG_SECURE technique, I simply override the onPause and onResume methods of the screens and modify the view to show one that covers everything in the back.

https://mcmap.net/q/139098/-need-to-hide-content-of-program-from-android-quot-overview-screen-quot

Jailhouse answered 24/10, 2018 at 18:50 Comment(0)
O
2
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
            WindowManager.LayoutParams.FLAG_SECURE);

this worked for me, it prevents from taking screenshot and also any inbuilt or third party recording application from recording screen.

Oe answered 19/10, 2019 at 4:48 Comment(0)
S
1

This is work for me after adding these line into the onCreate before setContentView of every activity.

getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,     
WindowManager.LayoutParams.FLAG_SECURE);
setContentView(R.layout.activity_notification);
Starstarboard answered 25/1, 2020 at 6:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.