基础知识
当我们在分析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);
}