我正在构建的应用程序要求应用程序必须阻止操作系统在出于安全原因将其推入后台时截取应用程序的屏幕截图。这样,在应用程序之间切换时,它将无法看到最后一个活动屏幕。
我打算将此功能放在应用程序类的onPause方法中,但首先我需要了解如何实现此功能。
那么有人在那里,有一个线索如何解决这个问题?
答案 0 :(得分:246)
尝试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或其他助手;如果用户打开助手,他们将无法访问用户界面中小部件和容器的详细信息。
更新#2 :但是,并非活动中的所有内容都会受到保护。任何弹出窗口 - Dialog
,Spinner
,AutoCompleteTextView
,操作栏溢出等 - 都将是不安全的。您可以通过调用Dialog
并设置getWindow()
来解决FLAG_SECURE
问题。剩下的......变得棘手。有关详情,请参阅this blog post。
答案 1 :(得分: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);
}
这就是扰乱屏幕的样子:
这在ICS三星手机上运行正常,所以我假设问题被隔离到姜饼设备(或更老)。
答案 2 :(得分:14)
CommonsWare提供的解决方案在Lollipop中仍然有效。
请注意,如果您想继续不在整个应用的最近列表中查看快照,则应在{{1}中指定所有已实施的活动标志onCreate()
在getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
之前
否则,如果用户浏览了该快照,则最近列表中的快照将显示没有该标志的第一个活动。
答案 3 :(得分:0)
这里是一种用于隐藏应用程序内容的解决方案,方法是在将应用程序置于后台时用启动屏幕将其覆盖。这不是使用FLAG_SECURE技术,我只是重写屏幕的onPause和onResume方法,并修改视图以显示一个覆盖了背面的所有内容。
答案 4 :(得分:0)
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE);
这对我有用,它可以防止从屏幕上截取屏幕快照以及任何内置或第三方录制应用程序。
答案 5 :(得分:0)
将这些行添加到每个活动的setContentView之前的onCreate之后,对我来说这是工作。
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE);
setContentView(R.layout.activity_notification);
答案 6 :(得分:0)
如果有人正在寻找一种解决方案,当应用程序是所有正在运行的应用程序的背景或棒时,应用程序必须保护(屏幕覆盖),并且应用程序内的应用程序应该允许屏幕截图。 尝试以下:-
@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);
}