当我的应用程序进入后台时,如何阻止Android获取屏幕截图?

Sti*_*ay5 139 security android android-lifecycle

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

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

所以有人在那里,有一个线索如何解决这个问题?

Com*_*are 251

试试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);
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

更新#2:但是,活动中的所有内容都不会受到保护.任何弹出窗口- ,Dialog,Spinner,AutoCompleteTextView行动起来吧溢出等-将是不安全的.您可以Dialog通过调用getWindow()和设置来解决问题FLAG_SECURE.剩下的......变得棘手.有关更多信息,请参阅此博文.

  • @Dany's:实际上,它与问题有关.我刚刚在Nexus S(4.0.3)上进行了测试,它按预期工作 - 最近的任务截图被抑制.您仍然可以看到应用程序名称和图标,但屏幕截图为黑色.欢迎您在ICS硬件上试用它. (6认同)
  • @ StingRay5:`FLAG_SECURE`从一开始就存在 - 它直到最近才有意义. (2认同)
  • @PankajKumar:如果您编写的“截取屏幕截图的代码”是经典的“以 root 身份获取帧缓冲区”技巧,那么`FLAG_SECURE` 将无法防御,因为这太低级了。类似地,如果您使用自己的小部件层次结构并将其绘制到支持“位图”的“画布”上,则“FLAG_SECURE”可能不会对此进行防御,因为您正在拍摄自己的小部件的屏幕截图,因此大概 *想要*那里的“安全”。`FLAG_SECURE` 用于*系统* 屏幕截图,例如最近任务缩略图。 (2认同)
  • 精彩而简单的答案!我想知道为什么像[snapchat](http://www.snadownload.com/)这样的应用程序不会使用此功能来防止有人截取发送图像的屏幕截图. (2认同)

gar*_*arh 77

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

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

这就是乱码屏幕的样子:

炒的屏幕图像

这在ICS三星手机上运行正常,所以我假设问题与姜饼设备(或更老)相关.

  • 你完全正确,我们遇到了这个问题,当然需要检查API级别.实际上忘了发布这个,所以感谢再次提起它.:) (8认同)
  • 即使在较新的Android版本上,FLAG_SECURE也可能会出现问题:在Android 4.3 FLAG_SECURE导致屏幕旋转动画出现动画问题,请参阅https://code.google.com/p/android/issues/detail?id=58632 - 此问题已修复Android 4.4 (7认同)

Dav*_*eas 13

CommonsWare提供的解决方案在Lollipop中也继续有效.

只是注意,如果你想继续发现近期列表快照为整个应用程序,所有的执行活动应在指定onCreate()方法的标志getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);setContentView();

否则,如果用户浏览了该快照,则最近列表中的快照将显示没有该标志的第一个活动.


小智 6

如果有人正在寻找一种解决方案,当应用程序处于后台或所有正在运行的应用程序的固定位置时,应用程序必须安全(屏幕覆盖),并且应用程序内应用程序应允许屏幕截图。尝试以下:-

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

    @Override
    protected void onPause() {
        super.onPause();
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
    }
Run Code Online (Sandbox Code Playgroud)


Lee*_*ang 5

从 Android 13 开始,有一种新方法可以防止对最近的应用程序列表进行屏幕截图,同时仍然允许用户在使用应用程序时进行屏幕截图。在您的主要活动中,致电setRecentsScreenshotEnabled(false).