Android中如何不受前台应用限制以编程方式获取屏幕触摸坐标
Android 全局无限制获取屏幕触摸坐标实现方案
核心负责系统类
全局触摸输入事件的采集、分发能力由系统服务InputManager(android.hardware.input.InputManager)提供,你之前使用的无障碍服务相关触摸事件由AccessibilityManager和InputManager协同调度。
AccessibilityService未获取到坐标的原因
是没有正确开启触摸探测权限和事件监听配置,并非无障碍服务不支持该能力。
可行实现方案
方案1:AccessibilityService 适配实现(全版本兼容,无需系统签名)
这是普通第三方应用最容易落地的方案,正确配置步骤如下:
- 在无障碍服务的配置XML文件中添加属性:
android:canRequestTouchExplorationMode="true" - 在服务
onServiceConnected回调中动态配置服务信息,添加触摸探测flag:
AccessibilityServiceInfo info = getServiceInfo(); info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE; info.eventTypes |= AccessibilityEvent.TYPE_TOUCH_INTERACTION | AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START | AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END; setServiceInfo(info);
- 重写服务的
onAccessibilityEvent方法,收到触摸事件后可直接从事件中获取getX()、getY()得到屏幕绝对坐标,也可通过event.getMotionEvent()拿到完整的MotionEvent对象获取多点触控、压力等全量触摸参数。
方案2:透明悬浮窗触摸拦截(适合Android 6.0-9.0版本)
- 申请
SYSTEM_ALERT_WINDOW悬浮窗权限,通过WindowManager添加全屏透明悬浮窗,给WindowManager.LayoutParams设置以下标记:
LayoutParams flags = LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | LayoutParams.FLAG_LAYOUT_IN_SCREEN;
- 重写悬浮窗View的
onTouchEvent方法,直接通过event.getRawX()、event.getRawY()获取全局触摸坐标,可根据业务需要决定是否将触摸事件透传给下层应用。
注意:Android 10及以上版本对悬浮窗的触摸事件透传做了限制,触摸事件在返回桌面、打开其他系统页面时可能被截断,无法全场景覆盖。
方案3:InputManager隐藏API调用(仅系统签名应用可用)
有系统签名权限的应用可直接通过反射调用InputManager的registerInputListener方法注册全局输入事件监听器,可拿到所有触摸、按键事件的原始数据,无需用户额外授权无障碍、悬浮窗权限。
- 需要申请系统级权限
android.permission.READ_INPUT_STATE - 该方案不受前台应用限制,所有场景下都可正常采集触摸坐标。
注意事项
所有全局触摸采集能力都涉及用户隐私操作,Android系统做了严格的权限限制,不存在无需用户授权即可静默获取触摸坐标的方案。
内容的提问来源于stack exchange,提问作者andreyprogrammer
相关产品推荐
相关产品推荐

