基础知识
当我们在分析android的键盘记录的时候就不得不和input进行打交道,那么input在系统中是怎么进行实现的? Android手机中默认携带input子系统,并且开在机就会产生默认的mouse和keyboard事件,这样使得用户开机就可以触屏点击和使用按键。 android中键盘实现的系统源码位置\source\frameworks\base\cmds\input\src\com\android\commands\input\Input.java
关键代码实现解析:java层代码
Input类定义
public class Input {//用于定义打印调试信息private static final String TAG = "Input";private static final String INVALID_ARGUMENTS = "Error: Invalid arguments for command: ";//用map方式实现关键字和标识对应private static final Map<String, Integer> SOURCES = new HashMap<String, Integer>() {{put("keyboard", InputDevice.SOURCE_KEYBOARD);put("dpad", InputDevice.SOURCE_DPAD);put("gamepad", InputDevice.SOURCE_GAMEPAD);put("touchscreen", InputDevice.SOURCE_TOUCHSCREEN);put("mouse", InputDevice.SOURCE_MOUSE);put("stylus", InputDevice.SOURCE_STYLUS);put("trackball", InputDevice.SOURCE_TRACKBALL);put("touchpad", InputDevice.SOURCE_TOUCHPAD);put("touchnavigation", InputDevice.SOURCE_TOUCH_NAVIGATION);put("joystick", InputDevice.SOURCE_JOYSTICK);}};
sendKeyEvent 函数定义
//函数功能:发送键盘事件private void sendKeyEvent(int inputSource, int keyCode, boolean longpress) { //获取从开机到现在的毫秒数 long now = SystemClock.uptimeMillis(); //注入键盘事件injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 0, 0,KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, inputSource));if (longpress) {injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 1, 0,KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_LONG_PRESS,inputSource));}injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, keyCode, 0, 0,KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, inputSource));}
sendSwipe 函数定义
//函数功能:实现滑屏操作
private void sendSwipe(int inputSource, float x1, float y1, float x2, float y2, int duration) {if (duration < 0) {duration = 300;}//获取从开机到现在的毫秒数long now = SystemClock.uptimeMillis();//注入触摸事件injectMotionEvent(inputSource, MotionEvent.ACTION_DOWN, now, x1, y1, 1.0f);//计算开始时间和结束时间long startTime = now;long endTime = startTime + duration;while (now < endTime) {long elapsedTime = now - startTime;float alpha = (float) elapsedTime / duration;injectMotionEvent(inputSource, MotionEvent.ACTION_MOVE, now, lerp(x1, x2, alpha),lerp(y1, y2, alpha), 1.0f);now = SystemClock.uptimeMillis();}injectMotionEvent(inputSource, MotionEvent.ACTION_UP, now, x2, y2, 0.0f);}
injectKeyEvent 函数定义
//函数功能:注入事件的实现 private void injectKeyEvent(KeyEvent event) { //打印调试信息Log.i(TAG, "injectKeyEvent: " + event);//获取inputManager的实例事件InputManager.getInstance().injectInputEvent(event,InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);}
injectMotionEvent 函数定义
函数功能:注入触摸事件
private void injectMotionEvent(int inputSource, int action, long when, float x, float y, float pressure) {final float DEFAULT_SIZE = 1.0f;final int DEFAULT_META_STATE = 0;final float DEFAULT_PRECISION_X = 1.0f;final float DEFAULT_PRECISION_Y = 1.0f;final int DEFAULT_DEVICE_ID = 0;final int DEFAULT_EDGE_FLAGS = 0;MotionEvent event = MotionEvent.obtain(when, when, action, x, y, pressure, DEFAULT_SIZE,DEFAULT_META_STATE, DEFAULT_PRECISION_X, DEFAULT_PRECISION_Y, DEFAULT_DEVICE_ID,DEFAULT_EDGE_FLAGS);event.setSource(inputSource);Log.i(TAG, "injectMotionEvent: " + event);InputManager.getInstance().injectInputEvent(event,InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);}
sendMove 函数定义
//函数功能:发送移动事件 private void sendMove(int inputSource, float dx, float dy) {//获取时间long now = SystemClock.uptimeMillis();//调用注入触摸事件injectMotionEvent(inputSource, MotionEvent.ACTION_MOVE, now, dx, dy, 0.0f);}