安卓AccessibilityService实现蚂蚁森林自动收集能量 最新 多线程 + 手势 + 深搜webView(续)

前言

蚂蚁森林自动收集能量(上)

紧接上期,这期主要解释这个项目中的一些小挫折以及如何解决。

蚂蚁森林自动收集能量这个项目并不大,喜欢玩它的人也不多,但是核心的一些实现方式很有推广意义。


本文主要解决三个问题

1. 如何准确的点击能量球

2. 如何判断好友是否有能量

3. 如何通过代码打开无障碍服务


一、如何准确地点击能量球

如图所示
安卓AccessibilityService实现蚂蚁森林自动收集能量 最新 多线程 + 手势 + 深搜webView(续)_第1张图片
通过UI Automator Viewer工具我们能看到能量球的文本信息类名包名、以及其他属性包括在屏幕中的坐标bounds[左,右][上,下]

我们创建一个矩形储存这个bounds

Rect rect = new Rect();
BtnNode.getBoundsInScreen(rect);

//为了准确点击,我们模拟点击中心点
手势点击(rect.centerX(),rect.centerY());

但是这是针对已知的能量球按钮才能用啊

1.怎么判断按钮是不是可以点击的能量球呢

好的,让我们来分析一下这个view结点
安卓AccessibilityService实现蚂蚁森林自动收集能量 最新 多线程 + 手势 + 深搜webView(续)_第2张图片
通过结点树,我们可以看到它是webView下的某个子view节点,这个view结点中包含了能量球Button(1个)左方“雨水”Button右方其中两个Button下方四个Button共八个Button结点。当然这是我们自己蚂蚁森林的情况。在好友的界面中,按钮情况会变化,但是依然包含能量球Button。

在大量的样本中总结出,能量球Button中心点的坐标都在一个矩形范围内

//界定能量球的范围
private int RIGHT = 900;
private int LEFT = 150;
private int BOTTOM = 850;
private int TOP = 200;

安卓AccessibilityService实现蚂蚁森林自动收集能量 最新 多线程 + 手势 + 深搜webView(续)_第3张图片
对于那些不能再收取或者还没到收取时间的Button,依然在这个范围内,我们依然会点击它,但是不会影响什么。如果要更精确,可以利用后文的方法判断颜色,来筛选点击。我觉得多一两个也不会影响什么时间复杂度。

/**
* @param nowNode:webView节点
* role 收取能量
*/
private void getEnergy(AccessibilityNodeInfo nowNode ){

   if(nowNode==null) return;

   //切换到只包含能量球的View节点,加快处理速度
   nowNode = nowNode.getChild(0).getChild(0).getChild(2);

   int resultCount = 0;
//        dfs(nowNode);
   //获得Button节点的个数,因为该节点只包含Button
   int buttonCount = nowNode.getChildCount();

   debug("按钮数量:"+buttonCount);
   //下标从1开始,第0个Button必然不是能量球Button

   AccessibilityNodeInfo nowButtonNode;
   Rect corr = new Rect();
   for(int i=0;i<buttonCount;i++) {
       //遍历 所有能量球
       nowButtonNode = nowNode.getChild(i);

       debug("该Button:" + nowButtonNode.getText().toString() + "_   长度:" + nowButtonNode.getText().toString().length());
       nowButtonNode.getBoundsInScreen(corr);

       //如果在范围之内,就是按钮,就点。
       if(checkInBound(corr.centerX(),corr.centerY())){

           debug("能量球坐标" + "(" + corr.centerX() + "," + corr.centerY() + ")");
           dispatchGestureView(1, corr.centerX(), corr.centerY());
           debug("收集了能量");
           sleep(500);
           resultCount++;

       }
   }
   debug("点击了"+resultCount+"个能量球");//点击的能量球个数
}

二、怎么判断该好友是否有可收取的能量球

安卓AccessibilityService实现蚂蚁森林自动收集能量 最新 多线程 + 手势 + 深搜webView(续)_第4张图片
我们知道,可收取的好友在列表中很可能是间断出现的,好友比较多,我们如果每个好友都进去观察观察,那时间复杂度会退化到O(N),收取的周期就会很长。这肯定是不能使用户满意的。

怎么判断是否可收取

看图
安卓AccessibilityService实现蚂蚁森林自动收集能量 最新 多线程 + 手势 + 深搜webView(续)_第5张图片
相信你已经想到了,没错,判断颜色!而且只能这么做!

怎么判断颜色呢

我们需要一个接口,这个接口通过屏幕截图获得像素信息。

public class GBData {
    static ImageReader reader;
    private static Bitmap bitmap;

    public static int getColor(int x, int y) {
        if (reader == null) {
            Log.d("", "getColor: reader is null");
            return -1;
        }

        Image image = reader.acquireLatestImage();

        if (image == null) {
            if (bitmap == null) {
                Log.d("", "getColor: image is null");
                return -1;
            }
            return bitmap.getPixel(x, y);
        }
        int width = image.getWidth();
        int height = image.getHeight();
        final Image.Plane[] planes = image.getPlanes();
        final ByteBuffer buffer = planes[0].getBuffer();
        int pixelStride = planes[0].getPixelStride();
        int rowStride = planes[0].getRowStride();
        int rowPadding = rowStride - pixelStride * width;
        if (bitmap == null) {
            bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
        }
        bitmap.copyPixelsFromBuffer(buffer);
        image.close();

        return bitmap.getPixel(x, y);
    }
}

调用很方便

    int color = GBData.getColor(x坐标,y坐标);
    int red = Color.red(color);
    int green = Color.green(color);
    int blue = Color.blue(color);

根据坐标获得RGB值,如果是白色,就说明没有。用这个判断准确率非常高,但是要不停更新webView结点,因为滚动中,坐标都在变化。

怎么启用截图功能呢
网上有就不说了。


三、怎么通过代码打开无障碍服务(免root)

只是需要一点骚操作,先看效果
安卓AccessibilityService实现蚂蚁森林自动收集能量 最新 多线程 + 手势 + 深搜webView(续)_第6张图片
可以看到打开应用后就直接打开了。
1.配置Manifests文件

<uses-permission android:name="android.permission.WRITE_SETTINGS"
    tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"
    tools:ignore="ProtectedPermissions" />

2.打开无障碍服务的代码

Settings.Secure.putString(getContentResolver(),
        Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "包名/类名");
Settings.Secure.putString(getContentResolver(),
        Settings.Secure.ACCESSIBILITY_ENABLED, "1");//1表示开启

3.通过ADB赋予权限

安装应用后,手机连上电脑,打开USB调试
打开ADB目录,shift+鼠标右键,打开powerShell

ADB下载

针对本应用,输入以下命令即可
安卓AccessibilityService实现蚂蚁森林自动收集能量 最新 多线程 + 手势 + 深搜webView(续)_第7张图片

.\adb shell pm grant com.example.automayiforest android.permission.WRITE_SECURE_SETTINGS

你可能感兴趣的:(安卓)