Android 11+设备TapJacking防护失效问题求助
Android 11+ 设备的TapJacking防护问题
我使用以下代码来防止TapJacking:
@Override public boolean onFilterTouchEventForSecurity(MotionEvent event) { if (((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) == MotionEvent.FLAG_WINDOW_IS_OBSCURED) || (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) == MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) { //Showing popup return false; } return true; }
该代码在Android 10及以下设备中可正常工作,但在Android 11及以上设备中失效,请问如何在Android 11+设备中实现TapJacking防护?
解决方案
1. 通过WindowInsets检测窗口遮挡状态
Android 11(API 30)开始,MotionEvent.FLAG_WINDOW_IS_OBSCURED和MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED已被废弃,需改用WindowInsets判断窗口是否被非系统必要窗口遮挡:
@Override public boolean onFilterTouchEventForSecurity(MotionEvent event) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { WindowInsets insets = getWindow().getDecorView().getRootWindowInsets(); if (insets != null) { // 仅保留系统必要元素的可见性判断,若存在其他遮挡则拦截事件 boolean onlySystemVisible = insets.isVisible(WindowInsets.Type.systemBars()) || insets.isVisible(WindowInsets.Type.displayCutout()) || insets.isVisible(WindowInsets.Type.ime()); if (!onlySystemVisible) { // 显示弹窗提示并拦截触摸 return false; } } } else { // 兼容Android 10及以下的原有逻辑 if (((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) == MotionEvent.FLAG_WINDOW_IS_OBSCURED) || (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) == MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) { //Showing popup return false; } } return true; }
2. 启用系统自带的触摸过滤机制
直接通过系统属性自动拦截被遮挡窗口的触摸事件,无需手动实现判断逻辑:
- 布局文件配置:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:filterTouchesWhenObscured="true"> <!-- 布局内容 --> </LinearLayout>
- 代码配置:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FILTER_TOUCHES_WHEN_OBSCURED, WindowManager.LayoutParams.FLAG_FILTER_TOUCHES_WHEN_OBSCURED);
3. 增强防护:添加FLAG_SECURE标记
若需防范屏幕录制、截图类衍生风险,可添加该标记禁止应用内容被捕获,同时强化窗口遮挡防护:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
内容的提问来源于stack exchange,提问作者Vijayadhas Chandrasekaran
相关产品推荐
相关产品推荐

