通过悬浮窗监听窗口以外的单击和触摸事件
创建悬浮窗服务
悬浮窗配置
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
monitorView = new PressScreenView(this);
backParams = new WindowManager.LayoutParams(
10,
10,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL //必须 设置窗口不拦截窗口范围之外事件
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,// 必须 设置在有FLAG_NOT_TOUCH_MODAL属性时,窗口之外事件发生时自己也获取事件
PixelFormat.TRANSLUCENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
backParams.type = WindowManager.LayoutParams
.TYPE_APPLICATION_OVERLAY;
} else {
backParams.type = WindowManager.LayoutParams.TYPE_PHONE;
}
backParams.gravity = Gravity.LEFT | Gravity.TOP;
//这是一个接口回调,当触摸屏幕时会执行下面方法
monitorView.setPressScreenListener(() -> {
Log.d(TAG, "dispatchTouchEvent: 摇晃手势");
});
windowManager.addView(monitorView, backParams);
AndroidManifest.xml中注册悬浮窗服务
//在application标签下添加服务配置
<service android:name=".PressScreenService"
android:enabled="true"
android:exported="true"
/>
在AndroidManifest.xml中添加悬浮窗权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/><!--悬浮窗权限-->
创建悬浮窗视图并处理分发的事件
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
Log.d(TAG, "dispatchTouchEvent: 事件分发");
Log.d(TAG, "dispatchTouchEvent: 上一次时间:"+lastTime);
Log.d(TAG, "dispatchTouchEvent: 当前时间:"+event.getEventTime());
mHandler = new Handler(Looper.getMainLooper());
mRunnable = () -> {
if (mPressScreenListener != null) {
Log.d(TAG, "dispatchTouchEvent: 执行多线程");
mPressScreenListener.userPressScreen();
}
}
if (event.getEventTime() - lastTime > INTERVAL_TIME) {
Log.d(TAG, "dispatchTouchEvent: 对监听到的触摸事件进行处理");
mHandler.post(mRunnable);
lastTime = event.getEventTime();
}
return super.dispatchTouchEvent(event);
}
/**
* 悬浮窗监听屏幕触摸事件,一个接口
*/
public interface PressScreenListener {
void userPressScreen();
}
最后,进行调用测试
if(isFloating(MainActivity.this)){//判断是否具有悬浮窗权限
Intent intent = new Intent(MainActivity.this, PressScreenService.class);
startService(intent);
}else {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
折磨我几天的烦恼终于解决了,下面贴上完整项目地址:
https://download.csdn.net/download/qq_44023485/21940093
注意:本项目是在将API30降至API26之后运行的