请问AccessibilityService如何识别webview内容(20180822解决)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/su749520/article/details/79726071

0.蚂蚁能量自动收集器

想做一个蚂蚁森林能量自动采集器,发现AccessibilityService无法识别webview内容,反正我是没招了,就看怎么实现,这里提出一个问题。

1.支付宝界面点击进入蚂蚁森林界面

这里写图片描述

public class AccessibilityServiceMonitor extends AccessibilityService {


    private static final String TAG = AccessibilityServiceMonitor.class.getSimpleName();

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate");
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        int eventType = event.getEventType();
        Log.i(TAG, "toString - " + event.toString());
            // 监听是否进入界面变化
            case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
                recycleInfo(getRootInActiveWindow());

                String className = event.getClassName().toString();
                Log.i(TAG, "window change text:"+className);
                if ("com.eg.android.AlipayGphone.AlipayLogin".equals(className)) {
                    openForest();
                } else if ("com.alipay.mobile.nebulacore.ui.H5Activity".equals(className)) {
                    getForestEnergy();
                }

                break;

    private void openForest() {
        AccessibilityNodeInfo rootNode  = getRootInActiveWindow();
        recycle(rootNode);
    }

    public void recycle(AccessibilityNodeInfo info) {
        if (info.getChildCount() == 0) {

            if(info.getText() != null){
                if("蚂蚁森林".equals(info.getText().toString())){
                    //这里有一个问题需要注意,就是需要找到一个可以点击的View
                    Log.i(TAG, "Click"+",isClick:"+info.isClickable());
                    info.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    AccessibilityNodeInfo parent = info.getParent();
                    while(parent != null){
                        Log.i(TAG, "parent isClick:"+parent.isClickable());
                        if(parent.isClickable()){
                            parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                            break;
                        }
                        parent = parent.getParent();
                    }

                }
            }

        } else {
            for (int i = 0; i < info.getChildCount(); i++) {
                if(info.getChild(i)!=null){
                    recycle(info.getChild(i));
                }
            }
        }
    }

2.蚂蚁森林界面时webview,发现数据都获取不到

03-28 12:28:04.305 18755-18755/com.fadi.forestautoget I/AccessibilityServiceMonitor: windowId:138
03-28 12:28:04.305 18755-18755/com.fadi.forestautoget D/AccessibilityServiceMonitor: rootNode = android.view.accessibility.AccessibilityNodeInfo@800b2ce5; boundsInParent: Rect(0, 0 - 96, 96); boundsInScreen: Rect(616, 48 - 712, 144); packageName: com.eg.android.AlipayGphone; className: android.widget.TextView; text: ; error: null; maxTextLength: -1; contentDescription: 更多; viewIdResName: null; checkable: false; checked: false; focusable: false; focused: false; selected: false; clickable: true; longClickable: false; contextClickable: false; enabled: true; password: false; scrollable: false; actions: [AccessibilityAction: ACTION_SELECT - null, AccessibilityAction: ACTION_CLEAR_SELECTION - null, AccessibilityAction: ACTION_CLICK - null, AccessibilityAction: ACTION_ACCESSIBILITY_FOCUS - null, AccessibilityAction: ACTION_NEXT_AT_MOVEMENT_GRANULARITY - null, AccessibilityAction: ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY - null, AccessibilityAction: ACTION_SET_SELECTION - null, AccessibilityAction: ACTION_SHOW_ON_SCREEN - null]
03-28 12:28:04.305 18755-18755/com.fadi.forestautoget I/AccessibilityServiceMonitor: window content text:android.webkit.WebView
03-28 12:28:04.337 18755-18755/com.fadi.forestautoget I/AccessibilityServiceMonitor: toString - EventType: TYPE_WINDOW_CONTENT_CHANGED; EventTime: 3591034; PackageName: com.eg.android.AlipayGphone; MovementGranularity: 0; Action: 0 [ ClassName: android.webkit.WebView; Text: []; ContentDescription: null; ItemCount: 0; CurrentItemIndex: 0; IsEnabled: true; IsPassword: false; IsChecked: false; IsFullScreen: false; Scrollable: true; BeforeText: null; FromIndex: -1; ToIndex: -1; ScrollX: 0; ScrollY: 17; MaxScrollX: 0; MaxScrollY: 1076; AddedCount: -1; RemovedCount: -1; ParcelableData: Bundle[mParcelledData.dataSize=488] ]; recordCount: 0
03-28 12:28:04.366 18755-18755/com.fadi.forestautoget I/AccessibilityServiceMonitor: child widget----------------------------com.uc.webview.export.WebView
03-28 12:28:04.366 18755-18755/com.fadi.forestautoget I/AccessibilityServiceMonitor: showDialog:false
03-28 12:28:04.366 18755-18755/com.fadi.forestautoget I/AccessibilityServiceMonitor: Text:null

这里写图片描述

3. 解决方案(繁星点点)

繁星点点的博客 https://blog.csdn.net/u012861467/article/details/81455619

4.代码优化

4.1 下载

https://github.com/sufadi/AccessibilityServiceMonitor

4.2 监听WebView的FLAG

serviceInfo.flags = serviceInfo.flags | AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY;

4.3 跳转支付宝登陆界面

    /**
     * 启动支付宝界面
     * adb shell am start com.eg.android.AlipayGphone/com.eg.android.AlipayGphone.AlipayLogin
     */
    public static void startAlipay(Context mContext) {
        Intent intent = new Intent();
        intent.setPackage("com.eg.android.AlipayGphone");
        intent.setClassName("com.eg.android.AlipayGphone", "com.eg.android.AlipayGphone.AlipayLogin");
        mContext.startActivity(intent);
    }

4.4 跳转蚂蚁森林界面

    /**
     * 自动点击进入蚂蚁森林界面
     */
    public static void enterForestUI(AccessibilityNodeInfo nodeInfo) {
        Log.d(Config.TAG, "enterForestUI ");
        if (nodeInfo != null) {
            // 找到界面中蚂蚁森林的文字
            List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText("蚂蚁森林");

            if (list == null) {
                Log.d(Config.TAG, "enterForestUI finding no");
                return;
            } else {
                Log.d(Config.TAG, "enterForestUI finding yes");
            }

            for (AccessibilityNodeInfo item : list) {
                /**
                 *  蚂蚁森林本身不可点击,但是他的父控件可以点击
                 */
                AccessibilityNodeInfo parent = item.getParent();
                if (null != parent && parent.isClickable()) {
                    parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    Log.d(Config.TAG, "item = " + item.toString() + ", parent click = " + parent.toString());
                    break;
                }
            }
        }
    }

4.5 采集蚂蚁森林能量

好友的能量不能收取,因为支付宝在onTouch事件中return true,导致不会触发OnClick方法,但是支付宝中的蚂蚁森林可以收取自己的能量

   public static void policy(AccessibilityNodeInfo nodeInfo, String packageName, String className) {
        /**
         * 蚂蚁森林界面
         */
        if (packageName.equals("com.eg.android.AlipayGphone") &&
                ("com.alipay.mobile.nebulacore.ui.H5Activity".equals(className)
                || "com.uc.webkit.bf".equals(className))) {

            if (nodeInfo != null) {
                for (int i = 0; i < nodeInfo.getChildCount(); i++) {
                    AccessibilityNodeInfo child =  nodeInfo.getChild(i);
                    if ("com.uc.webview.export.WebView".equals(child.getClassName())) {
                        Log.d(Config.TAG, "找到蚂蚁森林的 webView count = " + child.getChildCount());

                        findEveryViewNode(child);
                        break;
                    }
                }
            } else {
                Log.d(Config.TAG, "alipayPolicy = null");
            }
        }

    }

    public static void findEveryViewNode(AccessibilityNodeInfo node) {
        if (null != node && node.getChildCount() > 0) {
            for (int i = 0; i < node.getChildCount(); i++) {
                AccessibilityNodeInfo child =  node.getChild(i);
                // 有时 child 为空
                if (child == null) {
                    continue;
                }

                //Log.d(TAG, "findEveryViewNode = " + child.toString());

                String className = child.getClassName().toString();
                if ("android.widget.Button".equals(className)) {
                    Log.d(Config.TAG, "Button 的节点数据 text = " + child.getText() + ", descript = " + child.getContentDescription() + ", className = " + child.getClassName() + ", resId = " + child.getViewIdResourceName());

                    boolean isClickable = child.isClickable();
                    boolean isResIdNull = child.getViewIdResourceName() == null ? true:false;

                    /**
                     * 好友的能量不能收取,因为支付宝在onTouch事件中return true,导致不会触发OnClick方法
                     *
                     * 但是支付宝中的蚂蚁森林可以收取自己的能量
                     */
                    if ( isClickable && isResIdNull) {
                        child.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                        Log.d(Config.TAG, "能量球 成功点击");
                    }
                }

                // 递归调用
                findEveryViewNode(child);
            }
        }
    }
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页