判断是否有悬浮窗遮挡在当前应用。可能误导用户点击
1. 重写View#onFilterTouchEventForSecurity() 进行拦截
FLAG_WINDOW_IS_OBSCURED 或
FLAG_WINDOW_IS_PARTIALLY_OBSCURED API 29以上支持
@Override
public boolean onFilterTouchEventForSecurity(MotionEvent event) {
if ((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) == MotionEvent.FLAG_WINDOW_IS_OBSCURED){
// show error message
return false;
}
return super.onFilterTouchEventForSecurity(event);
}
2. 或着参照chrome实现
private void setupFilterTouchForSecurity() {
Button positiveButton = getButton(ModalDialogProperties.ButtonType.POSITIVE);
Button negativeButton = getButton(ModalDialogProperties.ButtonType.NEGATIVE);
View.OnTouchListener onTouchListener = (View v, MotionEvent ev) -> {
// Filter touch events based MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED which is
// introduced on M+.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false;
boolean shouldBlockTouchEvent = false;
try {
Field field = MotionEvent.class.getField("FLAG_WINDOW_IS_PARTIALLY_OBSCURED");
if ((ev.getFlags() & field.getInt(null)) != 0) {
shouldBlockTouchEvent = true;
}
if (ev.getAction() == MotionEvent.ACTION_DOWN && !mFilteredTouchResultRecorded) {
mFilteredTouchResultRecorded = true;
RecordHistogram.recordEnumeratedHistogram(UMA_SECURITY_FILTERED_TOUCH_RESULT,
shouldBlockTouchEvent ? SecurityFilteredTouchResult.BLOCKED
: SecurityFilteredTouchResult.HANDLED,
SecurityFilteredTouchResult.NUM_ENTRIES);
}
if (shouldBlockTouchEvent && mOnTouchFilteredCallback != null
&& ev.getAction() == MotionEvent.ACTION_DOWN) {
mOnTouchFilteredCallback.run();
}
} catch (NoSuchFieldException | IllegalAccessException e) {
Log.e(TAG, "Reflection failure: " + e);
}
return shouldBlockTouchEvent;
};
positiveButton.setFilterTouchesWhenObscured(true);
positiveButton.setOnTouchListener(onTouchListener);
negativeButton.setFilterTouchesWhenObscured(true);
negativeButton.setOnTouchListener(onTouchListener);
}