为毛一到下班公司周边的摩拜单车都没有!约不到! 作为 IT dog 不甘心! 写个自动约车程序吧,公司测试机器闲着也是闲着😏 跑起来~

本来想通过抓接口,找找漏洞,搞不定呀😭 那就 UI 模拟吧。。。
UiAutomator Viewer 打开看一看,地图上单车坐标点抓不到😢 肿么办,如何才能约到离我最近的单车呢??突然发现定位后我的坐标总是在屏幕正中间,嘿嘿~ 那就以屏幕正中为中心,画一个矩形,做一个坐标点的 NXN 阶矩阵,从中心点向外层傻瓜式遍历得了~~反正不是我点点点😂

主测试类


import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.util.Log;

import com.le.framework.uitl.Constant;
import com.le.framework.uitl.UiAutomatorUtil;
import com.le.uitest.testcase.base.Base;

import org.junit.BeforeClass;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by fj on 16/11/29.
 * 摩拜单车自动约车 havefun^_^
 */
public class AutoMobike extends Base {

    private static final String resourcePackage = "com.mobike.mobikeapp";
    private static final int select_area = 0;//筛选范围:0 全部单车;1 Mobike;2 Mobike Lite
    private static final int N = 20;//遍历坐标点密度 10~100

    @BeforeClass
    public static void init() throws Exception {
        //亮屏解锁
//        Launcher.unlock(mDevice);
        //进入摩拜单车app
        UiAutomatorUtil.goToApp(resourcePackage);
    }

    @Test
    public void reserve() throws Exception {
        //选择单车类型
        List<UiObject2> list = mDevice.wait(Until.findObjects(By.res(resourcePackage, "id_index_gallery_item_text")), 10000);//10s
        list.get(select_area).click();
        Thread.sleep(2000);

        //定位当前位置到屏幕中心点
        mDevice.findObject(By.res(resourcePackage, "map_location_button")).click();
        Thread.sleep(1000);
        List<String> points = this.getPoints();
        Log.e(Constant.Tags.uitest, Arrays.toString(points.toArray()));

        //从中心点向外逆序遍历坐标集合
        for (int i = points.size() - 1; i >= 0; i--) {
            String point = points.get(i);
            //如果预约成功了,就等待取消预约或保留时间到期后重新刷新坐标点;否则继续遍历坐标点
            if (bikeExist(point) && reserveOne()) {
                while (mDevice.hasObject(By.res(resourcePackage, "booking_cancel_button"))) {
                    Thread.sleep(1000);
                }
                reserve();
            }
        }

    }


    //判断坐标点point是否有单车
    private boolean bikeExist(String point) throws Exception {
        String[] xy = point.split(",");
        UiAutomatorUtil.clickByPoint(mDevice, Integer.parseInt(xy[0]), Integer.parseInt(xy[1]));
        return mDevice.wait(Until.hasObject(By.res(resourcePackage, "request_booking_button")), 500);
    }

    //预约15分钟
    private boolean reserveOne() {
        mDevice.findObject(By.res(resourcePackage, "request_booking_button")).click();
        if (mDevice.wait(Until.hasObject(By.res(resourcePackage, "booking_cancel_button")), 1000)) {
            return true;
        } else {
            return false;
        }


    }

    private List<String> getPoints() {
        //获取屏幕长宽
        int height = mDevice.getDisplayHeight();
        int width = mDevice.getDisplayWidth();
        Log.e(Constant.Tags.uitest, width + ":" + height);
        //取height(1/4~3/4)  width(0~width)区域,生成NXN矩阵坐标点
        int width_start = 0;
        int height_start = height / 4;
        int width_cut = width / N;
        int height_cut = (height * 3 / 4 - height_start) / N;
        Log.e(Constant.Tags.uitest, width_cut + ":" + height_cut);
        String[][] points = new String[N][N];
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                points[i][j] = width_start + "," + height_start;
                width_start += width_cut;
            }
            height_start += height_cut;
            width_start = 0;
        }

        //获取从外向内顺时针遍历后的矩阵
        return everyLap(points, 0, points.length - 1);
    }

    /**
     * 遍历一圈
     *
     * @param startPoint 起点
     * @param endPoint   终点
     */
    private static List<String> oneLap(String[][] data, List<String> res, int startPoint, int endPoint) {
        for (int i = startPoint; i <= endPoint; i++) {
            res.add(data[startPoint][i]);
            if (i == endPoint) {
                for (int j = startPoint + 1; j <= endPoint; j++) {
                    res.add(data[j][endPoint]);
                    if (j == endPoint) {
                        for (int i2 = endPoint - 1; i2 >= startPoint; i2--) {
                            res.add(data[endPoint][i2]);
                            if (i2 == startPoint) {
                                for (int j2 = endPoint - 1; j2 > startPoint; j2--) {
                                    res.add(data[j2][startPoint]);
                                }
                            }
                        }
                    }
                }
            }
        }
        return res;
    }

    /**
     * 遍历每一圈
     **/
    private static List<String> everyLap(String[][] data, int startPoint, int endPoint) {
        List<String> res = new ArrayList<String>();
        while (startPoint <= endPoint) {
            System.out.println("start= " + startPoint + " end= " + endPoint);
            res = oneLap(data, res, startPoint++, endPoint--);
        }
        return res;
    }
}

工具类



import android.content.Context;
import android.content.Intent;
import android.support.test.InstrumentationRegistry;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;

/**
 * Created by fj on 16/11/29.
*/
public class UiAutomatorUtil {

    /**
     * 获取测试程序自身的packageName
     */
    public static String getTargetPackageName() {
        return InstrumentationRegistry.getTargetContext().getPackageName();
    }

    public static Context getContext() {
        return InstrumentationRegistry.getTargetContext();
    }

    /**
     * 根据packageName启动一个应用
     */
    public static boolean goToApp(String packageName) {
        Context context = InstrumentationRegistry.getContext();
        final Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        context.startActivity(intent);

        UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
        return device.wait(Until.hasObject(By.pkg(packageName).depth(0)), 5000);

    }



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