您的位置:首页 > 其它

TV测试中的按键长按操作模拟

2016-02-24 20:58 274 查看
从UiAutomator在TV测试中的局限性说起:
智能TV的操作和手机的操作有很大不同,一般智能TV的操作为遥控器按键操作,来向TV OS发送 KeyCode,以完成指定操作。
UiAutomator在API中提供了控件和长按操作,也提供了点坐标的长按操作,但无法设置长按的时间。
UiAutomator在API中也提供了模拟发送KeyCode的方法,即UiDevice类中的pressKeyCode方法。
但TV遥控器按键的长按模拟方法,UiAutomator并没有直接提供,而电视中的视频快进等操作需要按 键长按,自动化测试有此方面的要求。

一. KeyCode按键长按操作通过Adb命令模拟

COMMAND: adb shell input keyevent --longpress 3
虽然可以实现长按操作,但长按只能实现简单的长按操作,长按时间较短,针对快进等需较长时间长按实现的操作无用。

二. Appium的KeyCode长按模拟
Appium里面实现了按键的长按操作,实现源码核心如下:
public AndroidCommandResult execute(final AndroidCommand command)
throws JSONException {
try {
InteractionController interactionController = UiAutomatorBridge.getInstance().getInteractionController();

final Hashtable<String, Object> params = command.params();
keyCode = (Integer) params.get("keycode");
metaState = params.get("metastate") != JSONObject.NULL ? (Integer) params
.get("metastate") : 0;
final long eventTime = SystemClock.uptimeMillis();
// Send an initial down event
final KeyEvent downEvent = new KeyEvent(eventTime, eventTime,
KeyEvent.ACTION_DOWN, keyCode, 0, metaState,
KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD);
if (interactionController.injectEventSync(downEvent)) {
// Send a repeat event. This will cause the FLAG_LONG_PRESS to be set.
final KeyEvent repeatEvent = KeyEvent.changeTimeRepeat(downEvent,
eventTime, 1);
interactionController.injectEventSync(repeatEvent);
// Finally, send the up event
final KeyEvent upEvent = new KeyEvent(eventTime, eventTime,
KeyEvent.ACTION_UP, keyCode, 0, metaState,
KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD);
interactionController.injectEventSync(upEvent);
}
return getSuccessResult(true);
} catch (final Exception e) {
return getErrorResult(e.getMessage());
}
}


核心主要是:injectEventSync方法,剖析其源码发现最终是调用了uiautomator JAR包中 com.android.uiautomator.core.InteractionController类的injectEventSync方法
只是在uiautomator JAR包中,上述类类型为default且上述方法private方法
若要调用需要使用反射技术

三. 自己实现的时间可控的长按操作模拟源码
public void execute(int keycode, int times) {

int keyCode = keycode;
int timeCount = times;
try {
// InteractionController interactionController = UiAutomatorBridge.getInstance().getInteractionController();
System.out.println("......ttt....");

UiDevice device = UiDevice.getInstance();

Class UiDevice_class = UiDevice.class;
Field field_UiD = UiDevice_class.getDeclaredField("mUiAutomationBridge");
field_UiD.setAccessible(true);
Object uiAutomatorBridge  =  field_UiD.get(device);

Class tmp = Class.forName("com.android.uiautomator.core.UiAutomatorBridge");
Field field = tmp.getDeclaredField("mInteractionController");
field.setAccessible(true);
Object interactionController = field.get(uiAutomatorBridge);

metaState = 0;
final long eventTime = SystemClock.uptimeMillis();
// Send an initial down event
final KeyEvent downEvent = new KeyEvent(eventTime, eventTime,
KeyEvent.ACTION_DOWN, keyCode, 0, metaState,
KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD);
System.out.println("......lll,....");
if (injectEventSync(downEvent,interactionController)) {
// Send a repeat event. This will cause the FLAG_LONG_PRESS to be set.
final KeyEvent repeatEvent = KeyEvent.changeTimeRepeat(downEvent,
eventTime, 1);
for(int i=0; i<timeCount; i++){

injectEventSync(repeatEvent,interactionController);

}

// Finally, send the up event
System.out.println("......lll,....");
final KeyEvent upEvent = new KeyEvent(eventTime, eventTime,
KeyEvent.ACTION_UP, keyCode, 0, metaState,
KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD);
injectEventSync(upEvent,interactionController);

}
return ;
} catch (final Exception e) {
return ;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: