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


    从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 ;
        }
      }



            

     

  • 相关阅读:
    CentOS7 时间设置与网络同步
    CentOS7 系统升级,删除centos7开机界面多余选,升级至最新的内核
    Docker 编排工具Rancher 2.0
    Docker 编排工具Rancher 1.6.18
    通过WSL在Windows下安装子Linux系统
    Docker 使用Dockerfile构建redis镜像
    初探PHP多进程
    nginx转发
    mime类型
    socket php
  • 原文地址:https://www.cnblogs.com/udld/p/5746377.html
Copyright © 2020-2023  润新知