需要隐藏Android“概述屏幕”中的程序内容

时间:2014-12-04 01:33:34

标签: android

我正在为安全意识的雇主开发Android应用程序。他担心Overview Screen(也就是最近的任务列表)上出现的屏幕快照会泄漏敏感信息,并希望我在系统接收之前放置程序的启动画面图片。不幸的是,我还没有找到任何办法。

我尝试的事情:

  • onPause功能中为启动画面的视图充气。 (即使使用bringToFrontsetVisibility(View.VISIBLE)也无效。)
  • onCreate中展开启动画面的视图,并在bringToFront中使用onPause。 (再一次,没有效果。)
  • setVisible(false)中呼叫onPause。 (似乎几乎可以工作,因为当切换到程序时,屏幕会瞬间闪烁为黑色,但在快照之前,系统显然会再次看到它。)
  • setVisibility(View.INVISIBLE)中的视图的最顶层项目上调用onPause。 (看起来它会起作用,但快照显然是在它生效之前拍摄的。)

我是一位经验丰富的Android开发人员,但我无法帮助,但我觉得这是一个我不知道的简单解决方案。

5 个答案:

答案 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 提供另一个版本:

某些边缘情况下的错误:

  • [1] 对话框正在显示
  • [2] 打开相机时会显示一个非常快速的启动画面

代码

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