Need to hide content of program from Android "Overview Screen"

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.

First I create my splash screen in a separate file as a relative layout called splash_screen_custom, I also give the relative layout in the file an id customSplash. Note the elevation setting, I ran into an issue where buttons have a preset elevation, so by setting this cover screen to have a high elevation it will cover any buttons(of course you don't need this if you are not covering buttons).

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
     android:id="@+id/customSplash"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@color/backgroundColor"
     android:elevation="5dp"
         >

     <ImageView
         android:id="@+id/imageView"
         android:layout_width="202dp"
         android:layout_height="157dp"
         android:layout_centerInParent="true"
         app:srcCompat="@drawable/yourImage" />
</RelativeLayout>

In this example my screen I am trying to cover is a relative layout so I am able to simply add and delete my splash screen to it via the addView and removeView methods of view I am trying to cover.

override fun onPause() {

    var parentView = findViewById<RelativeLayout>(R.id.parentView)
    var splashScreen = layoutInflater.inflate(R.layout.splash_screen_custom, null)
    parentView.addView(splashScreen, parentView.width, parentView.height)

    super.onPause()

}

override fun onResume() {
    var parentView = findViewById<RelativeLayout>(R.id.parentView)
    parentView.removeView(findViewById<RelativeLayout>(R.id.customSplash))
    super.onResume()

}

Personally, I would go with FLAG_SECURE, and simply block display of this stuff everywhere:

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

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

    setContentView(R.layout.main);
  }
}

However, IIRC, you can override onCreateThumbnail() to supply your own image to use for the recent-tasks list. Note that this might have changed with Android 5.0, as they have overhauled that recent-tasks list, so be sure to test your code on a 5.0 device or emulator.


Based on @D.Maul 's answer but the Java version, instead of adding a view, I have tried this. It works fairly but sometimes the recent snapshot shows the app content not sure what to do about it.

private Dialog dialog = null;

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  dialog = new Dialog(this, android.R.style.Theme_Light);
  dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
  dialog.setContentView(R.layout.customlaunch);
}

@Override
protected void onPause() {
    dialog.show();
    super.onPause();
}
    
@Override
protected void onResume() {
     dialog.hide();
     super.onResume();
}

I just want to provide another version for react-native android based on @D.Maul 's answer:

Bug on some edge cases:

  • [1] Dialog is showing
  • [2] A very quick SplashScreen is shown when open Camera

Code

@Override
protected void onPause() {
  try {
    // Hide app preview with SplahScreen
    FrameLayout parentView = findViewById(android.R.id.content);
    if (parentView != null && parentView.findViewById(R.id.splash_activity) == null) {
      View splashScene = this.getLayoutInflater().inflate(R.layout.splash_activity, null);
      parentView.addView(splashScene, parentView.getWidth(), parentView.getHeight());
    }
  } catch (Exception e) {
    // do nothing
  }

  super.onPause();
}

@Override
protected void onResume() {
  try {
    // Remove SplashScreen
    FrameLayout parentView = findViewById(android.R.id.content);
    if (parentView != null) {
      parentView.removeView(this.findViewById(R.id.splash_activity));
    }
  } catch (Exception e) {
    // do nothing
  }

  super.onResume();
}

Tags:

Android