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