我正在为安全意识的雇主开发Android应用程序。他担心Overview Screen(也就是最近的任务列表)上出现的屏幕快照会泄漏敏感信息,并希望我在系统接收之前放置程序的启动画面图片。不幸的是,我还没有找到任何办法。
我尝试的事情:
onPause
功能中为启动画面的视图充气。 (即使使用bringToFront
和setVisibility(View.VISIBLE)
也无效。)onCreate
中展开启动画面的视图,并在bringToFront
中使用onPause
。 (再一次,没有效果。)setVisible(false)
中呼叫onPause
。 (似乎几乎可以工作,因为当切换到程序时,屏幕会瞬间闪烁为黑色,但在快照之前,系统显然会再次看到它。)setVisibility(View.INVISIBLE)
中的视图的最顶层项目上调用onPause
。 (看起来它会起作用,但快照显然是在它生效之前拍摄的。)我是一位经验丰富的Android开发人员,但我无法帮助,但我觉得这是一个我不知道的简单解决方案。
答案 0 :(得分:9)
就个人而言,我会go with FLAG_SECURE
,只是阻止在任何地方展示这些东西:
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);
}
}
但是,IIRC,您可以覆盖onCreateThumbnail()
以提供您自己的图像以用于最近任务列表。请注意,这可能已经在Android 5.0中发生了变化,因为他们已经彻底检查了最近的任务列表,因此请务必在5.0设备或模拟器上测试您的代码。
答案 1 :(得分:1)
您可以考虑使用ActivityManager.addAppTask(Activity, Intent, ActivityManager.TaskDescription, Bitmap)
启动应用任务,而不是启动活动,您传入的位图将用作概览/最近屏幕中的缩略图。
关于此api的文件是here,但是,它仅适用于Lollipop。
答案 2 :(得分:1)
这里是一种用于隐藏应用程序内容的解决方案,方法是在将应用程序置于后台时用启动屏幕将其覆盖。 这不是使用FLAG_SECURE技术,我只是重写屏幕的onPause和onResume方法,并修改视图以显示一个覆盖了背面的所有内容。
首先,我在一个单独的文件中创建我的启动屏幕,作为一个名为splash_screen_custom的相对布局,我还为该文件中的相对布局指定了一个id customSplash。请注意高程设置,我遇到了一个问题,即按钮具有预设的高程,因此通过将此封面设置为高海拔,它将覆盖所有按钮(当然,如果您不覆盖按钮,则不需要此按钮)。
<?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>
在此示例中,我要覆盖的屏幕是相对布局,因此我可以通过我要覆盖的view的addView和removeView方法简单地向其添加和删除初始屏幕。
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()
}
答案 3 :(得分:1)
我只想根据@D.Maul 的回答为 react-native android 提供另一个版本:
某些边缘情况下的错误:
代码
@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();
}
答案 4 :(得分:0)
基于@ D.Maul的答案,但是基于Java版本,我没有尝试添加视图,而是尝试添加视图。它可以正常工作,但是有时会显示对话框,但是最近的快照显示了应用内容,但不确定该怎么做。
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();
}