欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android 模拟手柄摇杆输入,模拟MotionEvent

程序员文章站 2024-02-11 11:23:28
...

背景

需求是在系统应用模拟摇杆,达到对所有应用都能模拟输入的效果,所以一定会使用到InputManager。但是大多demo和文章 模拟摇杆和功能使用都是在同一个应用,所以可以自定义实现此类功能,不需要模拟构造MotionEvent给InputManager

相关代码和使用

  1. 建议先查看Google的对手柄处理文档,对手柄有一定的了解:https://developer.android.com/training/game-controllers/controller-input?hl=zh-cn

  2. 通过查看文档我们可以知道,手柄的摇杆输入其实是一个个MotionEvent,对于左摇杆,Android 会将水平方向移动报告为 AXIS_X 事件,将垂直方向移动报告为 AXIS_Y 事件。对于右摇杆,Android 会将水平方向移动报告为 AXIS_Z 事件,将垂直方向移动报告为 AXIS_RZ 事件。而每个方向的value值为-1.0(上/左)至 1.0(下/右)的float值。0为初始位置。

  3. 模拟代码

//构造MotionEvent 摇杆往下保留1s后还原到初始位置。
MotionEvent.PointerProperties[] properties = new MotionEvent.PointerProperties[1];
		properties[0] = new MotionEvent.PointerProperties();
		properties[0].id = 0;
		properties[0].toolType = 0;
		MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[1];
		pointerCoords[0] = new MotionEvent.PointerCoords();
		pointerCoords[0].clear();
		pointerCoords[0].setAxisValue(MotionEvent.AXIS_X,0f);
		pointerCoords[0].setAxisValue(MotionEvent.AXIS_Y,0.99f);
		//InputDevice.SOURCE_JOYSTICK为手柄摇杆
		MotionEvent event = MotionEvent.obtain(0,SystemClock.uptimeMillis(),MotionEvent.ACTION_MOVE,1,properties,pointerCoords,
				0,0,1.0f,1.0f,0,0,InputDevice.SOURCE_JOYSTICK,0);
		Log.d(TAG,"MotionEvent:"+event);
		InputManager.getInstance().injectInputEvent(event,
				InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
		mHandler.postDelayed(new Runnable() {
			@Override
			public void run() {
				pointerCoords[0].clear();
				pointerCoords[0].setAxisValue(MotionEvent.AXIS_X,0f);
				pointerCoords[0].setAxisValue(MotionEvent.AXIS_Y,0f);
				MotionEvent event = MotionEvent.obtain(0,SystemClock.uptimeMillis(),MotionEvent.ACTION_MOVE,1,properties,pointerCoords,
						0,0,1.0f,1.0f,0,0,InputDevice.SOURCE_JOYSTICK,0);
				Log.d(TAG,"MotionEvent2:"+event);

				InputManager.getInstance().injectInputEvent(event,
						InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
			}
		},1000);