160

我当前正在构建的应用程序要求应用程序必须阻止操作系统在出于安全原因将其推入后台时截取应用程序的屏幕截图。这样,在应用程序之间切换时,它将无法看到最后一个活动屏幕。

我打算将此功能放在应用程序类的 onPause 方法中,但首先我需要了解如何实现此功能。

那么那里有没有人知道如何解决这个问题?

4

7 回答 7

288

尝试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);
  }
}

这绝对可以防止来自 ICS 最近任务历史记录的手动屏幕截图和自动屏幕截图。它还可以防止屏幕录制(例如,使用媒体投影 API 的应用程序)。

更新:它还可以保护 Android 6.0 上的 Now On Tap 或其他助手;如果用户调出助手,他们将无法访问 UI 中小部件和容器的详细信息。

更新#2:但是,并非活动中的所有内容都会受到保护。任何弹出窗口—— DialogSpinnerAutoCompleteTextView、操作栏溢出等——都将是不安全的。您可以Dialog通过调用getWindow()它并设置来解决问题FLAG_SECURE。其余的......变得棘手。有关更多信息,请参阅此博客文章

于 2012-03-22T12:48:45.167 回答
79

小心使用 WindowManager.LayoutParams.FLAG_SECURE,在某些设备上(已在 Samsung Galaxy ACE 上验证,例如 GT-S5830)这会使视图混乱。看起来像三星特定的错误。我推荐以下内容:

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

这是一个加扰的屏幕的样子:

加扰的屏幕图像

不过,这在 ICS 三星手机上可以正常工作,所以我假设问题与 Gingerbread 设备(或更旧的设备)隔离。

于 2012-06-20T14:33:04.057 回答
13

CommonsWare 提供的解决方案在 Lollipop 中仍然有效。

请注意,如果您想继续在整个应用程序的最近列表中看不到快照则所有已实现的活动都应在方法中指定 之前的标志onCreate()getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);setContentView();

否则,如果用户浏览它,最近列表中的快照将显示不带标志的第一个活动。

于 2015-03-20T10:39:40.437 回答
2

这是一个隐藏应用程序内容的解决方案,当应用程序进入后台时,它会用启动屏幕覆盖。这不是使用 FLAG_SECURE 技术,我只是覆盖屏幕的 onPause 和 onResume 方法,并修改视图以显示覆盖后面所有内容的视图。

https://stackoverflow.com/a/52976001/6686912

于 2018-10-24T18:50:31.257 回答
2

如果有人正在寻找一个解决方案,当应用程序是所有正在运行的应用程序的背景或棒并且应用程序内应用程序应该允许屏幕截图时,应用程序必须保护(屏幕覆盖) 。试试下面: -

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

    @Override
    protected void onPause() {
        super.onResume();
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
    }
于 2021-05-31T10:18:59.087 回答
0
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
            WindowManager.LayoutParams.FLAG_SECURE);

这对我有用,它可以防止屏幕截图以及任何内置或第三方录制应用程序录制屏幕。

于 2019-10-19T04:48:05.757 回答
0

在每个活动的 setContentView 之前将这些行添加到 onCreate 之后,这对我有用。

getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,     
WindowManager.LayoutParams.FLAG_SECURE);
setContentView(R.layout.activity_notification);
于 2020-01-25T06:49:34.960 回答