Android Instrumentation 模拟点击、拖拽、发送keycode、焦点异常丢失。
    
  
      
      
     
    
      
        
Instrumentation模拟点击,拖拽,向系统发送keycode。
需要注意的几点: 
- Android系统坐标系,X轴正方向为右,Y轴正方向为下(与数学坐标系相反) 
- 所有事件在发送时均需要在Thread中执行,否则会报异常。 
- 模拟输入法种特殊符号时,需要带上shift,同正常键盘操作。 
| 12
 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));
 
 }
 
 | 
| 12
 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);
 }
 
 }
 
 | 
| 12
 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的焦点丢失,或者有异常情况。请参考如下代码。
| 12
 
 | Instrumentation instrumentation = new Instrumentation();instrumentation.setInTouchMode(false);
 
 | 
Android Instrumentation源码分析(附Activity启动流程)
移动测试基础 Android Instrumentation 框架简单说明