请教一下,我是用“am start --display display_id package/activityName”方式直接把应用启动到display_id的VirtualDisplay上的,
VirtualDisplay由TextureView+Surface的方式创建到屏幕上。这种怎么使用injectMotion去发射触摸事件?目前点击事件都通过onTouch获取点击坐标,
想请教你一下,只有VirtualDisplay,TextureView,Surface的情况下,怎么把event传递给VirtualDisplay上显示的Activity?
VirtualDisplay交互方法
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
3条回答 默认 最新
码界奇点 2026-01-22 13:54关注通过
injectMotionEvent将触摸事件传递到 VirtualDisplay 上的 Activity,需要获取 VirtualDisplay 的InputMonitor并注入事件。以下是关键步骤和代码示例:核心步骤
- 获取 VirtualDisplay 的 Display:通过
DisplayManager获取目标 Display 对象。 - 创建 InputMonitor:使用
InputManager为 Display 创建InputMonitor。 - 注入触摸事件:通过
InputMonitor的injectInputEvent方法注入事件。
代码示例
// 1. 获取 DisplayManager 和 InputManager DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); InputManager inputManager = (InputManager) context.getSystemService(Context.INPUT_SERVICE); // 2. 获取目标 Display(假设 displayId 已知) Display targetDisplay = displayManager.getDisplay(displayId); // 3. 创建 InputMonitor InputMonitor inputMonitor = inputManager.monitorGestureInput("VirtualDisplayTouch", targetDisplay.getDisplayId()); // 4. 构造并注入触摸事件(以 ACTION_DOWN 为例) long downTime = SystemClock.uptimeMillis(); MotionEvent event = MotionEvent.obtain( downTime, downTime, MotionEvent.ACTION_DOWN, x, // 触摸坐标 x(相对于 VirtualDisplay 的坐标) y, // 触摸坐标 y 0 // 元状态 ); event.setSource(InputDevice.SOURCE_TOUCHSCREEN); // 5. 注入事件 inputMonitor.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); event.recycle(); // 释放资源 // 后续事件(如 ACTION_MOVE、ACTION_UP)类似构造并注入注意事项
- 坐标转换:确保触摸坐标已转换为 VirtualDisplay 的坐标系(相对于其左上角)。
- 权限要求:需要
INJECT_EVENTS权限(系统或签名级权限),普通应用可能无法使用。 - 事件序列:注入完整的事件序列(DOWN → MOVE... → UP),避免应用状态异常。
- 资源释放:及时调用
event.recycle()防止内存泄漏。
如果无法使用系统权限,可考虑通过辅助功能服务(AccessibilityService)模拟点击,但仅限于有限交互场景。
评论 打赏 举报解决 1无用- 获取 VirtualDisplay 的 Display:通过