基於微信紅包插件的原理實現android任何APP自動發送評論(已開源)

背景

地址:https://github.com/huijimuhe/postmanhtml

核心就是android的AccessibilityService,回覆功能api須要23以上版本才行。java

其實很像在作單元測試。你能夠有n種方式實現發帖功能,這只是一個比較邪火的方式,親測過一次,可行。這裏我以網易新聞客戶端舉例。node

模擬你在手機端的物理動做:選擇新聞-》回覆-》退回新聞列表-》進入下一個新聞-》回覆-》退回新聞列表刷新-》進入-》回覆....android

作的不精細,只是探究到底可不可行。你能夠用在任何APP中自動發消息,只要沒有驗證碼。git

你要拿來玩,請抱着一顆開心的心情。github

原理

直接在github上開源的微信紅包插件改的,紅包插件項目和你須要瞭解的幾篇文章在這裏api

https://github.com/geeeeeeeeek/WeChatLuckyMoney微信

http://www.xuebuyuan.com/2061597.htmlapp

http://www.xuebuyuan.com/2061595.htmlide

http://developer.android.com/training/accessibility/service.html

package com.huijimuhe.pman.services;

import android.accessibilityservice.AccessibilityService;
import android.content.ComponentName;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;

import com.huijimuhe.pman.utils.PowerUtil;

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

public class PostService extends AccessibilityService implements SharedPreferences.OnSharedPreferenceChangeListener {

    private static final String TAG = "PostService";

    private static final String MAIN_ACT = "MainActivity";
    private static final String DETAIL_ACT = "NewsPageActivity";
    private static final String BASE_ACT = "BaseActivity";

    private static final int MSG_BACK = 159;
    private static final int MSG_REFRESH_NEW_LIST = 707;
    private static final int MSG_READ_NEWS = 19;
    private static final int MSG_POST_COMMENT = 211;
    private static final int MSG_REFRESH_COMPLETE = 22;
    private static final int MSG_FINISH_COMMENT = 59;

    private String currentActivityName = MAIN_ACT;
    private HandlerEx mHandler = new HandlerEx();

    private boolean mIsMutex = false;
    private int mReadCount = 0;
    private List<String> readedNews = new ArrayList<>();
    private PowerUtil powerUtil;
    private SharedPreferences sharedPreferences;

    /**
     * AccessibilityEvent
     *
     * @param event 事件
     */
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {

        if (sharedPreferences == null) return;

        setCurrentActivityName(event);
        watchMain(event);
        watchBasic(event);
        watchDetail(event);
    }

    private void watchMain(AccessibilityEvent event) {
        //新聞列表
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && currentActivityName.contains(MAIN_ACT)) {
            if (mReadCount > 4) {
                //若是讀取完了都沒有新的就刷新
                Log.d(TAG, "新聞已讀取完,須要刷新列表");
                //須要刷新列表了
                mHandler.sendEmptyMessage(MSG_REFRESH_NEW_LIST);
            } else {
                mHandler.sendEmptyMessage(MSG_READ_NEWS);
            }
        }
    }

    private void watchDetail(AccessibilityEvent event) {
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && currentActivityName.contains(DETAIL_ACT)) {
            //添加評論
            mHandler.sendEmptyMessage(MSG_POST_COMMENT);
        }
    }

    private void watchBasic(AccessibilityEvent event) {
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && currentActivityName.contains(BASE_ACT)) {
            Log.d(TAG, "進入非新聞頁,即將退出");
            mHandler.sendEmptyMessage(MSG_BACK);
            mHandler.sendEmptyMessage(MSG_BACK);
        }
    }

    private void refreshList() {
        List<AccessibilityNodeInfo> nodes = getRootInActiveWindow().findAccessibilityNodeInfosByViewId("android:id/list");
        for (AccessibilityNodeInfo node : nodes) {
            //頁面是否加載完成
            if (node == null) return;
            //執行刷新
            node.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
        }
        //從新開始讀取新聞
        mHandler.sendEmptyMessage(MSG_REFRESH_COMPLETE);
    }

    private void enterDetailAct() {

        //獲取列表items
        List<AccessibilityNodeInfo> nodes = getRootInActiveWindow().findAccessibilityNodeInfosByViewId("com.netease.newsreader.activity:id/perfect_item");

        for (AccessibilityNodeInfo node : nodes) {
            //頁面是否加載完成
            if (node == null) return;

            //獲取列表item的標題
            List<AccessibilityNodeInfo> titles = node.findAccessibilityNodeInfosByViewId("com.netease.newsreader.activity:id/title");

            for (AccessibilityNodeInfo title : titles) {

                //檢查是否已讀取
                if (!readedNews.contains(title.getText().toString())) {
                    //點擊讀取該新聞
                    readedNews.add(title.getText().toString());
                    node.getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    Log.d(TAG, "進入新聞:" + title.getText().toString());
                    mReadCount++;
                    //進入一個就中止
                    return;
                }
            }
        }
    }

    private void postComment() {
        //激活輸入框
        List<AccessibilityNodeInfo> nodes = getRootInActiveWindow().findAccessibilityNodeInfosByViewId("com.netease.newsreader.activity:id/mock_reply_edit");
        for (AccessibilityNodeInfo node : nodes) {

            //頁面是否加載完成
            if (node == null) return;

            node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
        }

        //輸入內容
        List<AccessibilityNodeInfo> editNodes = getRootInActiveWindow().findAccessibilityNodeInfosByViewId("com.netease.newsreader.activity:id/reply_edit");
        for (AccessibilityNodeInfo node : editNodes) {

            //頁面是否加載完成
            if (node == null) return;

            Bundle arguments = new Bundle();
            arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, "抽菸的人最討厭了");
            node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
        }

//        //回覆按鈕
//        List<AccessibilityNodeInfo> postNodes = getRootInActiveWindow().findAccessibilityNodeInfosByViewId("com.netease.newsreader.activity:id/reply");
//        for (AccessibilityNodeInfo node : postNodes) {
//           //頁面是否加載完成
//           if (node == null) return;
//           node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
//        }

        //退出
        mHandler.sendEmptyMessage(MSG_FINISH_COMMENT);

        Log.d(TAG, "評論已發表");
    }

    /**
     * 設置當前頁面名稱
     *
     * @param event
     */
    private void setCurrentActivityName(AccessibilityEvent event) {

        if (event.getEventType() != AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
            return;
        }

        try {
            ComponentName componentName = new ComponentName(event.getPackageName().toString(), event.getClassName().toString());

            getPackageManager().getActivityInfo(componentName, 0);
            currentActivityName = componentName.flattenToShortString();
            Log.d(TAG, "<--pkgName-->" + event.getPackageName().toString());
            Log.d(TAG, "<--className-->" + event.getClassName().toString());
            Log.d(TAG, "<--currentActivityName-->" + currentActivityName);
        } catch (PackageManager.NameNotFoundException e) {
            currentActivityName = MAIN_ACT;
        }
    }

    @Override
    public void onDestroy() {
        this.powerUtil.handleWakeLock(false);
        super.onDestroy();
    }

    @Override
    public void onInterrupt() {

    }

    @Override
    public void onServiceConnected() {
        super.onServiceConnected();
        this.watchFlagsFromPreference();
    }

    /**
     * 屏幕是否常亮
     */
    private void watchFlagsFromPreference() {
        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        sharedPreferences.registerOnSharedPreferenceChangeListener(this);

        this.powerUtil = new PowerUtil(this);
        Boolean watchOnLockFlag = sharedPreferences.getBoolean("pref_watch_on_lock", false);
        this.powerUtil.handleWakeLock(watchOnLockFlag);
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if (key.equals("pref_watch_on_lock")) {
            Boolean changedValue = sharedPreferences.getBoolean(key, false);
            this.powerUtil.handleWakeLock(changedValue);
        }
    }

    /**
     * 處理機
     */
    private class HandlerEx extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                //後退
                case MSG_BACK:
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            performGlobalAction(GLOBAL_ACTION_BACK);
                        }
                    }, 1000);
                    break;
                //結束評論
                case MSG_FINISH_COMMENT:
                    for (int i = 0; i < 4; i++) {
                        new Handler().postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                performGlobalAction(GLOBAL_ACTION_BACK);
                            }
                        }, 2000 +i*500);
                    }
                    break;
                //刷新列表
                case MSG_REFRESH_NEW_LIST:
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            refreshList();
                        }
                    }, 3000);
                    break;
                //結束刷新
                case MSG_REFRESH_COMPLETE:
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            mReadCount = 0;
                            enterDetailAct();
                        }
                    }, 3000);
                    break;
                //進入新聞頁
                case MSG_READ_NEWS:
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            enterDetailAct();
                        }
                    }, 3000);
                    break;
                //發送評論
                case MSG_POST_COMMENT:
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            postComment();
                        }
                    }, 3000);
                    break;
            }
        }
    }
}
複製代碼
package com.huijimuhe.pman.services;

import android.accessibilityservice.AccessibilityService;
import android.content.ComponentName;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;

import com.huijimuhe.pman.utils.PowerUtil;

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

public class PostService extends AccessibilityService implements SharedPreferences.OnSharedPreferenceChangeListener {

    private static final String TAG = "PostService";

    private static final String MAIN_ACT = "MainActivity";
    private static final String DETAIL_ACT = "NewsPageActivity";
    private static final String BASE_ACT = "BaseActivity";

    private static final int MSG_BACK = 159;
    private static final int MSG_REFRESH_NEW_LIST = 707;
    private static final int MSG_READ_NEWS = 19;
    private static final int MSG_POST_COMMENT = 211;
    private static final int MSG_REFRESH_COMPLETE = 22;
    private static final int MSG_FINISH_COMMENT = 59;

    private String currentActivityName = MAIN_ACT;
    private HandlerEx mHandler = new HandlerEx();

    private boolean mIsMutex = false;
    private int mReadCount = 0;
    private List<String> readedNews = new ArrayList<>();
    private PowerUtil powerUtil;
    private SharedPreferences sharedPreferences;

    /**
     * AccessibilityEvent
     *
     * @param event 事件
     */
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {

        if (sharedPreferences == null) return;

        setCurrentActivityName(event);
        watchMain(event);
        watchBasic(event);
        watchDetail(event);
    }

    private void watchMain(AccessibilityEvent event) {
        //新聞列表
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && currentActivityName.contains(MAIN_ACT)) {
            if (mReadCount > 4) {
                //若是讀取完了都沒有新的就刷新
                Log.d(TAG, "新聞已讀取完,須要刷新列表");
                //須要刷新列表了
                mHandler.sendEmptyMessage(MSG_REFRESH_NEW_LIST);
            } else {
                mHandler.sendEmptyMessage(MSG_READ_NEWS);
            }
        }
    }

    private void watchDetail(AccessibilityEvent event) {
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && currentActivityName.contains(DETAIL_ACT)) {
            //添加評論
            mHandler.sendEmptyMessage(MSG_POST_COMMENT);
        }
    }

    private void watchBasic(AccessibilityEvent event) {
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && currentActivityName.contains(BASE_ACT)) {
            Log.d(TAG, "進入非新聞頁,即將退出");
            mHandler.sendEmptyMessage(MSG_BACK);
            mHandler.sendEmptyMessage(MSG_BACK);
        }
    }

    private void refreshList() {
        List<AccessibilityNodeInfo> nodes = getRootInActiveWindow().findAccessibilityNodeInfosByViewId("android:id/list");
        for (AccessibilityNodeInfo node : nodes) {
            //頁面是否加載完成
            if (node == null) return;
            //執行刷新
            node.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
        }
        //從新開始讀取新聞
        mHandler.sendEmptyMessage(MSG_REFRESH_COMPLETE);
    }

    private void enterDetailAct() {

        //獲取列表items
        List<AccessibilityNodeInfo> nodes = getRootInActiveWindow().findAccessibilityNodeInfosByViewId("com.netease.newsreader.activity:id/perfect_item");

        for (AccessibilityNodeInfo node : nodes) {
            //頁面是否加載完成
            if (node == null) return;

            //獲取列表item的標題
            List<AccessibilityNodeInfo> titles = node.findAccessibilityNodeInfosByViewId("com.netease.newsreader.activity:id/title");

            for (AccessibilityNodeInfo title : titles) {

                //檢查是否已讀取
                if (!readedNews.contains(title.getText().toString())) {
                    //點擊讀取該新聞
                    readedNews.add(title.getText().toString());
                    node.getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    Log.d(TAG, "進入新聞:" + title.getText().toString());
                    mReadCount++;
                    //進入一個就中止
                    return;
                }
            }
        }
    }

    private void postComment() {
        //激活輸入框
        List<AccessibilityNodeInfo> nodes = getRootInActiveWindow().findAccessibilityNodeInfosByViewId("com.netease.newsreader.activity:id/mock_reply_edit");
        for (AccessibilityNodeInfo node : nodes) {

            //頁面是否加載完成
            if (node == null) return;

            node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
        }

        //輸入內容
        List<AccessibilityNodeInfo> editNodes = getRootInActiveWindow().findAccessibilityNodeInfosByViewId("com.netease.newsreader.activity:id/reply_edit");
        for (AccessibilityNodeInfo node : editNodes) {

            //頁面是否加載完成
            if (node == null) return;

            Bundle arguments = new Bundle();
            arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, "抽菸的人最討厭了");
            node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
        }

//        //回覆按鈕
//        List<AccessibilityNodeInfo> postNodes = getRootInActiveWindow().findAccessibilityNodeInfosByViewId("com.netease.newsreader.activity:id/reply");
//        for (AccessibilityNodeInfo node : postNodes) {
//           //頁面是否加載完成
//           if (node == null) return;
//           node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
//        }

        //退出
        mHandler.sendEmptyMessage(MSG_FINISH_COMMENT);

        Log.d(TAG, "評論已發表");
    }

    /**
     * 設置當前頁面名稱
     *
     * @param event
     */
    private void setCurrentActivityName(AccessibilityEvent event) {

        if (event.getEventType() != AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
            return;
        }

        try {
            ComponentName componentName = new ComponentName(event.getPackageName().toString(), event.getClassName().toString());

            getPackageManager().getActivityInfo(componentName, 0);
            currentActivityName = componentName.flattenToShortString();
            Log.d(TAG, "<--pkgName-->" + event.getPackageName().toString());
            Log.d(TAG, "<--className-->" + event.getClassName().toString());
            Log.d(TAG, "<--currentActivityName-->" + currentActivityName);
        } catch (PackageManager.NameNotFoundException e) {
            currentActivityName = MAIN_ACT;
        }
    }

    @Override
    public void onDestroy() {
        this.powerUtil.handleWakeLock(false);
        super.onDestroy();
    }

    @Override
    public void onInterrupt() {

    }

    @Override
    public void onServiceConnected() {
        super.onServiceConnected();
        this.watchFlagsFromPreference();
    }

    /**
     * 屏幕是否常亮
     */
    private void watchFlagsFromPreference() {
        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        sharedPreferences.registerOnSharedPreferenceChangeListener(this);

        this.powerUtil = new PowerUtil(this);
        Boolean watchOnLockFlag = sharedPreferences.getBoolean("pref_watch_on_lock", false);
        this.powerUtil.handleWakeLock(watchOnLockFlag);
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if (key.equals("pref_watch_on_lock")) {
            Boolean changedValue = sharedPreferences.getBoolean(key, false);
            this.powerUtil.handleWakeLock(changedValue);
        }
    }

    /**
     * 處理機
     */
    private class HandlerEx extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                //後退
                case MSG_BACK:
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            performGlobalAction(GLOBAL_ACTION_BACK);
                        }
                    }, 1000);
                    break;
                //結束評論
                case MSG_FINISH_COMMENT:
                    for (int i = 0; i < 4; i++) {
                        new Handler().postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                performGlobalAction(GLOBAL_ACTION_BACK);
                            }
                        }, 2000 +i*500);
                    }
                    break;
                //刷新列表
                case MSG_REFRESH_NEW_LIST:
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            refreshList();
                        }
                    }, 3000);
                    break;
                //結束刷新
                case MSG_REFRESH_COMPLETE:
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            mReadCount = 0;
                            enterDetailAct();
                        }
                    }, 3000);
                    break;
                //進入新聞頁
                case MSG_READ_NEWS:
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            enterDetailAct();
                        }
                    }, 3000);
                    break;
                //發送評論
                case MSG_POST_COMMENT:
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            postComment();
                        }
                    }, 3000);
                    break;
            }
        }
    }
}
複製代碼

 

在開始寫代碼前,你應該至少閱讀了以前幾篇文章和微信紅包插件的代碼,而後還應該掌握用Android Device Monitor查看UI樹的工具使用。(最近開始研究iOS逆向,這個確實比reveal和cycript方便太多)

粗略實現步驟

1.manifest中申明服務

 
 <service
                android:name=".services.PostService"
                android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
            <intent-filter>
                <action android:name="android.accessibilityservice.AccessibilityService"/>
            </intent-filter>
            <meta-data android:name="android.accessibilityservice"
                       android:resource="@xml/accessible_service_config"/>
        </service>
 

 2.設定你須要監控的app包名來過濾,在/res/xml/accessible_service_config.xml中

 
<accessibility-service
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/app_description"
    android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged"
    android:accessibilityFeedbackType="feedbackAllMask"
    android:packageNames="com.netease.newsreader.activity"
    android:notificationTimeout="10"
    android:settingsActivity="com.huijimuhe.pman.activities.SettingsActivity"
    android:accessibilityFlags="flagIncludeNotImportantViews|flagDefault"
    android:canRetrieveWindowContent="true"/>
 

好比網易的,android:packageNames="com.netease.newsreader.activity"

3.在AccessibleService中實現對事件的監聽 

 
  @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {

        if (sharedPreferences == null) return;

        setCurrentActivityName(event);
        watchMain(event);
        watchBasic(event);
        watchDetail(event);
    }
/**
 * 設置當前頁面名稱
 *
 * @param event
 */
private void setCurrentActivityName(AccessibilityEvent event) {

    if (event.getEventType() != AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
        return;
    }

    try {
        ComponentName componentName = new ComponentName(event.getPackageName().toString(), event.getClassName().toString());

        getPackageManager().getActivityInfo(componentName, 0);
        currentActivityName = componentName.flattenToShortString();
        Log.d(TAG, "<--pkgName-->" + event.getPackageName().toString());
        Log.d(TAG, "<--className-->" + event.getClassName().toString());
        Log.d(TAG, "<--currentActivityName-->" + currentActivityName);
    } catch (PackageManager.NameNotFoundException e) {
        currentActivityName = MAIN_ACT;
    }
}
 

4.監控是不是新聞列表,能夠設定個頁面刷新閥值

 

 
  //新聞列表
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && currentActivityName.contains(MAIN_ACT)) {
            if (mReadCount > 4) {
                //若是讀取完了都沒有新的就刷新
                Log.d(TAG, "新聞已讀取完,須要刷新列表");
                //須要刷新列表了
                mHandler.sendEmptyMessage(MSG_REFRESH_NEW_LIST);
            } else {
                mHandler.sendEmptyMessage(MSG_READ_NEWS);
            }
        }
 

 

5.監控是不是新聞詳情

    private void watchDetail(AccessibilityEvent event) {
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && currentActivityName.contains(DETAIL_ACT)) {
            //添加評論
            mHandler.sendEmptyMessage(MSG_POST_COMMENT);
        }
    }

6監控是否廣告或其餘專題,不作操做

 
    private void watchBasic(AccessibilityEvent event) {
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && currentActivityName.contains(BASE_ACT)) {
            Log.d(TAG, "進入非新聞頁,即將退出");
            mHandler.sendEmptyMessage(MSG_BACK);
            mHandler.sendEmptyMessage(MSG_BACK);
        }
    }
 

7.回覆評論

 
    private void postComment() {
        //激活輸入框
        List<AccessibilityNodeInfo> nodes = getRootInActiveWindow().findAccessibilityNodeInfosByViewId("com.netease.newsreader.activity:id/mock_reply_edit");
        for (AccessibilityNodeInfo node : nodes) {

            //頁面是否加載完成
            if (node == null) return;

            node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
        }

        //輸入內容
        List<AccessibilityNodeInfo> editNodes = getRootInActiveWindow().findAccessibilityNodeInfosByViewId("com.netease.newsreader.activity:id/reply_edit");
        for (AccessibilityNodeInfo node : editNodes) {

            //頁面是否加載完成
            if (node == null) return;

            Bundle arguments = new Bundle();
            arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, "抽菸的人最討厭了");
            node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
        }

        //退出
        mHandler.sendEmptyMessage(MSG_FINISH_COMMENT);

        Log.d(TAG, "評論已發表");
    }
 

整體思路是經過postDelay來實現操做的間隔,其餘的請本身閱讀代碼,我只測試了下思路是否可行就沒有繼續延伸下去了。

相關文章
相關標籤/搜索