Answers:
尝试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的应用程序)。
更新:它还可以防止Now Tap或Android 6.0上的其他助手的攻击;如果用户调出助手,他们将无法访问UI中的小部件和容器的详细信息。
更新#2:但是,并非活动中的所有内容都会受到保护。任何弹出窗口- ,Dialog
,Spinner
,AutoCompleteTextView
行动起来吧溢出等-将是不安全的。您可以Dialog
通过调用getWindow()
并设置来解决问题FLAG_SECURE
。其余...变得棘手。有关更多信息,请参见此博客文章。
FLAG_SECURE
从一开始就存在-直到最近才具有有限的含义。
FLAG_SECURE
就别无所求,因为那太底层了。同样,如果您采用自己的窗口小部件层次结构并将其绘制为Bitmap
-backed Canvas
,则FLAG_SECURE
可能无法防御这一情况,因为您正在获取自己的窗口小部件的屏幕快照,因此大概在其中需要 “安全”的屏幕快照。FLAG_SECURE
用于系统屏幕截图,例如最近任务的缩略图。
在某些设备(在Samsung Galaxy ACE上验证,例如GT-S5830)上使用WindowManager.LayoutParams.FLAG_SECURE时要小心,这会使视图混乱。看起来像是三星特定的错误。我建议以下内容:
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
}
这是一个混乱的屏幕看起来像:
不过,这在ICS Samsung手机上可以正常工作,因此我假设问题仅存在于Gingerbread设备(或更旧的设备)上。
CommonsWare提供的解决方案在Lollipop中仍然有效。
只是注意,如果你想继续未发现近期列表快照为整个应用程序,所有的执行活动应在指定onCreate()
方法的标志getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
前setContentView();
否则,如果用户浏览最近的列表中的快照,则该快照将显示不带该标志的第一个活动。
这是一种通过将应用程序置于后台时用启动屏幕覆盖应用程序内容来隐藏应用程序内容的解决方案。这不是使用FLAG_SECURE技术,我只是重写屏幕的onPause和onResume方法并修改视图以显示一个覆盖了背面的所有内容。
将这些行添加到每个活动的setContentView之前的onCreate之后,这对我来说就是工作。
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE);
setContentView(R.layout.activity_notification);