九宫格解锁是很多 app 测试都会遇到的,解锁九宫格的原理就是用 appium 的 actions 的 moveto 方法连续移动坐标偏移量,由于九宫格都是标准的,九个点,所以通过九宫格第一个起点坐标就可以计算出偏移量。因此我封装了一个通用解锁九宫格的方法,简单便捷,特分享出来避免重复造轮子。方法支持 ANDROID,和 IOS(9.1),由于 IOS9.1 以上采用 XCUTESTDRIVER,底层不支持连续移动坐标的手势操作,故暂不支持 IOS 9.1 以上的设备解锁。还不清楚是 APPIUM 底层 XCUTESTDRIVER 不支持还是 WDA 不提供连续移动坐标手势支持。

/**
    * 输入格式 {(300,500,100,200)/(1,3,5,7,9)}
    * 300,500 :第一个点的x,y坐标,100,200 是横竖点坐标相对间隔
    * 1,3,5,7,9是Z子解锁路径
    * 起点坐标和横竖点坐标,均可通过webdriver  webelement API webElement.getLocation()计算出。
    * @param inputData
    */
   public void drawScreenLockPassWd(String inputData,WebDriver driver){
       try {
           if (!inputData.contains("/")){
               log.error("格式不正确");
           }else {
               log.info("开始解锁");
               String[] strArray=inputData.split("/")[0].replace("{","").replace("(","").replace(")","").split(",");
               int x=Integer.parseInt(strArray[0]);
               int y=Integer.parseInt(strArray[1]);
               int spaceX=Integer.parseInt(strArray[2]);
               int spaceY=Integer.parseInt(strArray[3]);

               String[] strArray2=inputData.split("/")[1].replace("}","").replace("(","").replace(")","").split(",");
               int[] dot=new int[strArray2.length];
               for (int i=0;i<strArray2.length;i++){
                   dot[i]=Integer.parseInt(strArray2[i]);
               }
               drawScreenLockPassWd(x,y,spaceX,spaceY,dot,driver);
           }
       }catch (Exception e){
           log.error("解锁失败");
           throw  e;
       }

   }
   /**
    *
    * @param x
    * @param y
    * @param spaceX
    * @param spaceY
    * @param dotPos 点位置列表
    */
   private   void drawScreenLockPassWd(int x, int y, int spaceX,int spaceY,int[] dotPos,WebDriver driver){
       try {
           List<Position> positionList=new ArrayList<>();
           for (int i=0;i<dotPos.length;i++){
               Position position=getPositionToLockScreenPassWd(x,y,spaceX,spaceY,dotPos[i]);
               positionList.add(position);
           }
           TouchAction touchAction=null;
           if (driver instanceof AndroidDriver){
               touchAction=new TouchAction((AndroidDriver)driver);
           }else if (driver instanceof IOSDriver){
               touchAction=new TouchAction((IOSDriver)driver);
           }
           TouchAction touchAction1=touchAction.press(positionList.get(0).getX(),positionList.get(0).getY()).waitAction(500);
           for (int i=1;i<positionList.size();i++){
               switch (dotPos[i]-dotPos[i-1]){
                   case 1://恒向右
                       x=spaceX;
                       y=0;
                       break;
                   case -1://恒向左
                       x=-spaceX;
                       y=0;
                       break;
                   case 3://竖向下
                       x=0;
                       y=spaceY;
                       break;
                   case -3://竖向上
                       y=-spaceY;
                       x=0;
                       break;
                   case 2://斜对角左向下
                       x=-spaceX;
                       y=spaceY;
                       break;
                   case 4://斜对角右向下
                       x=spaceX;
                       y=spaceY;
                       break;
                   case -2://斜对角右向上
                       x=spaceX;
                       y=-spaceY;
                       break;
                   case -4://斜对角左向上
                       x=-spaceX;
                       y=-spaceY;
                       break;
               }
               log.info("第"+i+"次按坐标偏移量("+x+","+y+")"+"滑动");
              if (driver instanceof IOSDriver){//ios滑动模式
                  IOSDriver iosDriver=(IOSDriver)driver;
                  TouchAction touchAction2=null;
                  String uiautomationName=iosDriver.getAutomationName();
                  if (uiautomationName!=null){//Xcuitest模式 适用于ios9.3以上手机
                       touchAction1=touchAction1.moveTo(x,y).waitAction(500);
                      if (i==positionList.size()-1){
                          touchAction1.release().perform();
                          break;
                      }
                  }else {
                       touchAction2=touchAction1.moveTo(x,y).waitAction(500);
                      if (i==positionList.size()-1){
                          touchAction2.release().perform();
                          break;
                      }
                  }
              }else {
                  TouchAction touchAction2=touchAction1.moveTo(x,y).waitAction(500);
                  if (i==positionList.size()-1){
                      touchAction2.release().perform();
                      break;
                  }
              }
           }
       }catch (Exception e){
           log.info("没有找到解锁控件");
           throw e;
       }
   }
   /**
    * 获取锁屏密码坐标
    * @param x  x轴
    * @param y  y轴
    * @param spaceX  横向间隔
    *@param spaceX  纵向间隔
    * @param pos 第几个点
    * @return
    */
   private Position getPositionToLockScreenPassWd(int x, int y, int spaceX, int spaceY, int pos){
       Position position=new Position();
       switch (pos){
           case 1:case 2:case 3://第一行
               x=x+(pos-1)*spaceX;
               position.setX(x);
               position.setY(y);//恒向纵坐标相同
               break;
           case 4:case 5:case 6://第二行
               y=y+spaceY;
               x=x+(pos-3-1)*spaceX;
               position.setX(x);
               position.setY(y);
               break;
           case 7:case 8:case 9://第三行
               y=y+2*spaceY;
               x=x+(pos-6-1)*spaceX;
               position.setX(x);
               position.setY(y);
               break;
       }
       return position;
   }


↙↙↙阅读原文可查看相关链接,并与作者交流