1 原理
通过input的inject方法对MotionEvent事件进行下发。关于input子系统如果想有更多的了解,可以关注input系列文章:
Android Framework 输入子系统(01)核心机制 inotify和epoll
Android Framework 输入子系统(02)核心机制 双向通信(socketpair+binder)
Android Framework 输入子系统(03)输入系统框架
Android Framework 输入子系统(04)InputReader解读
Android Framework 输入子系统(05)InputDispatcher解读
Android Framework 输入子系统(06)Global Key 一键启动 应用程序案例
Android Framework 输入子系统(07)APP建立联系
Android Framework 输入子系统(08)View基础(activity window decor view)
Android Framework 输入子系统(09)InputStage解读
Android Framework 输入子系统(10)Input命令解读
Android Framework 输入子系统(11)sendevent与getevent命令解读
2 解决方案(Android O)
在文件 frameworks/base/cmds/input/src/com/android/commands/input/Input.java 中做如下修改:
@@ -145,7 +145,19 @@ public class Input {
Float.parseFloat(args[index+2]));
return;
}
- } else {
+ } else if (command.equals("scroll")) {
+ System.out.println("scroll command effect");
+ inputSource = getSource(inputSource, InputDevice.SOURCE_MOUSE);
+ System.out.println("length = "+length);
+ if (length == 4) {
+ sendScroll(inputSource, MotionEvent.AXIS_VSCROLL,
+ Integer.parseInt(args[index+1]),
+ Float.parseFloat(args[index+2]),
+ Float.parseFloat(args[index+3]));
+ return;
+ }
+ }
+ else {
System.err.println("Error: Unknown command: " + command);
showUsage();
return;
@@ -156,6 +168,18 @@ public class Input {
showUsage();
}
+ private void sendScroll(int inputSource,int axis,int axisValue,float x,float y){
+/*
+ MotionEvent.PointerProperties[] pointerProperties = { new MotionEvent.PointerProperties() };
+ MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
+ coords.setAxisValue(axis, axisValue);
+ MotionEvent.PointerCoords[] pointerCoords = { coords };
+ long now = SystemClock.uptimeMillis();
+ injectMotionEventScroll(inputSource, MotionEvent.ACTION_SCROLL, now, 1, pointerProperties, pointerCoords);
+*/
+ injectMotionMouseScroll(inputSource,axis,axisValue,x,y);
+ }
+
/**
* Convert the characters of string text into key event's and send to
* device.*/
@@ -310,6 +334,33 @@ public class Input {
InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
+ private void injectMotionMouseScroll(int inputSource,int axis, int axisValue, float x,float y) {
+ MotionEvent.PointerProperties[] pointerProperties = { new MotionEvent.PointerProperties() };
+ MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
+ pointerProperties[0].clear();
+ pointerProperties[0].id = 0;
+ pointerProperties[0].toolType = MotionEvent.TOOL_TYPE_MOUSE;
+ coords.setAxisValue(axis, axisValue);
+ MotionEvent.PointerCoords[] pointerCoords = { coords };
+ pointerCoords[0].x = x;
+ pointerCoords[0].y = y;
+ float xPrecision = 1.0f;
+ float yPrecision = 1.0f;
+ int deviceId = 0;
+ int edgeFlags = 0;
+ int flags = 0;
+ System.out.println("InputSource:"+inputSource+" Axis:"+axis+" AxisValue:"+axisValue);
+ MotionEvent event = MotionEvent.obtain(0, System.currentTimeMillis(), MotionEvent.ACTION_SCROLL,
+ 1, pointerProperties, pointerCoords, 0, 0, xPrecision, yPrecision, deviceId,
+ edgeFlags, getInputDeviceId(inputSource), flags);
+ event.setSource(inputSource);
+ Log.i(TAG, "injectMotionEvent:"+event);
+ System.out.println("getAxisValue:"+event.getAxisValue(axis));
+ System.out.println("injectMotionEvent: " + event);
+ InputManager.getInstance().injectInputEvent(event,
+ InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
+ }
+
private static final float lerp(float a, float b, float alpha) {
return (b - a) * alpha + a;
}