背景
需求是在系统应用模拟摇杆,达到对所有应用都能模拟输入的效果,所以一定会使用到InputManager。但是大多demo和文章 模拟摇杆和功能使用都是在同一个应用,所以可以自定义实现此类功能,不需要模拟构造MotionEvent给InputManager
相关代码和使用
建议先查看Google的对手柄处理文档,对手柄有一定的了解:https://developer.android.com/training/game-controllers/controller-input?hl=zh-cn
通过查看文档我们可以知道,手柄的摇杆输入其实是一个个MotionEvent,对于左摇杆,Android 会将水平方向移动报告为 AXIS_X 事件,将垂直方向移动报告为 AXIS_Y 事件。对于右摇杆,Android 会将水平方向移动报告为 AXIS_Z 事件,将垂直方向移动报告为 AXIS_RZ 事件。而每个方向的value值为-1.0(上/左)至 1.0(下/右)的float值。0为初始位置。
模拟代码
//构造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);