Android Instrumentation 模拟点击、拖拽、发送keycode、焦点异常丢失。

Instrumentation模拟点击,拖拽,向系统发送keycode。

需要注意的几点:

  1. Android系统坐标系,X轴正方向为右,Y轴正方向为下(与数学坐标系相反)

  2. 所有事件在发送时均需要在Thread中执行,否则会报异常。

  3. 模拟输入法种特殊符号时,需要带上shift,同正常键盘操作。

1
2
3
4
5
6
7
8
9
10
public void simulateClick() {

final float clickX = mPositionX + mHalfScreenWidth;
final float clickY = mPositionY + mHalfScreenHeight;

long downTime = SystemClock.uptimeMillis();
inst.sendPointerSync(MotionEvent.obtain(downTime, downTime + 100, MotionEvent.ACTION_DOWN, clickX, clickY, 0));
inst.sendPointerSync(MotionEvent.obtain(downTime, downTime + 100, MotionEvent.ACTION_UP, clickX, clickY, 0));

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public void simulateTouch(int event, float x, float y) {

mPositionX += x;
mPositionY += y;


if (mPositionX > mHalfScreenWidth) {
mPositionX = mHalfScreenWidth;
} else if (mPositionX < (-mHalfScreenWidth)) {
mPositionX = -mHalfScreenWidth;
}

if (mPositionY > mHalfScreenHeight) {
mPositionY = mHalfScreenHeight;
} else if (mPositionY < (-mHalfScreenHeight)) {
mPositionY = -mHalfScreenHeight;
}


float moveX = mPositionX + mHalfScreenWidth;
float moveY = mPositionY + mHalfScreenHeight;

long downTime = SystemClock.uptimeMillis();
MotionEvent motionEvent = MotionEvent.obtain(downTime, downTime + 100, event, moveX, moveY, 0);

try {
inst.sendPointerSync(motionEvent);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Exception = " + e);
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private static boolean simulateKeystroke(int KeyCode) {

try {
Instrumentation inst = new Instrumentation();

if (shift) {
inst.sendKeySync(new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyCode, 0, KeyEvent.META_SHIFT_ON));
inst.sendKeySync(new KeyEvent(0, 0, KeyEvent.ACTION_UP, KeyCode, 0, KeyEvent.META_SHIFT_ON));
// shift = false;
} else {
inst.sendKeyDownUpSync(KeyCode);
}

return true;
} catch (Exception e) {
// TODO: handle exception
return false;
}
}

Android 设备启动后,会默认为Touch模式。如果你做过Android TV开发,发现开机后launcher的焦点丢失,或者有异常情况。请参考如下代码。

1
2
Instrumentation instrumentation = new Instrumentation();
instrumentation.setInTouchMode(false);

Android Instrumentation源码分析(附Activity启动流程)

移动测试基础 Android Instrumentation 框架简单说明