支付寶咻一咻自動無限快速點擊的實現

前段時間採用小米的開源代碼解決了自動搶紅包的bug,從而能淡定的搶微信紅包了。最近支付寶咻一咻搶紅包呵呵領福又火了一把,於是在業餘寫了一個自動咻一咻的輔助。這個輔助真的就解放了雙手,搶紅包不帶這麼累的,手指點的累死也不一定能咻出什麼東西來。廢話不多說,開始分析。

alipay_monkey_money
看咻一咻的界面,我通過Android Device Monitor外加代碼打印,發現的那個圓形按鈕是一個Button類型組件,界面其它部分都沒有Button,於是我想到最簡單的獲取要點擊的Node的方法就是如下:

//篩選出咻咻的button,進行不停的點擊
    private AccessibilityNodeInfo getButtonInfo(AccessibilityNodeInfo parent){
        if(parent != null && parent.getChildCount() > 0){
            for(int i = 0 ;i < parent.getChildCount() ;i++){
                AccessibilityNodeInfo node = parent.getChild(i);
                if("android.widget.Button".equals(node.getClassName())){
                    return node;
                }
            }
        }
        return null;
    }

然後在AccessibilityEvent的窗口狀態變化事件中實現按鈕的無限點擊:

if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED){
                //進入咻一咻界面
                if("com.alipay.android.wallet.newyear.activity.MonkeyYearActivity".equals(event.getClassName())){

                   isCanCyclingClick = true;
                    AccessibilityNodeInfo btn = getButtonInfo(getRootInActiveWindow());
                    if(btn != null){
                        dontStopClick(btn);
                        //wait(100);
                        //btn.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    }
                }else{
                    ...
                }

可以看到我在這裏通過發生事件的某個Activity類名(com.alipay.android.wallet.newyear.activity.MonkeyYearActivity)來判斷進入了咻一咻界面。然後在TYPE_WINDOW_STATE_CHANGED的事件中判斷,是進入這個activity才進行自動點擊的操作。
一開始我的無限自動點擊是採用while(true)的形式實現,後來發現了一個問題,就是Android中四大組件都是運行在UI線程的,這裏我們在AccessibilityService中運行無限點擊動作,其實也是發生在UI線程,這在Android中是很忌諱的,於是我輔助的App的Activity出現了白屏,也就是傳說的ANR,於是很多事情都發生的很詭異不正常了。
自然而然,解決方案是採用子線程,常見的操作是Thread+Handler模式,這裏我偷懶使用簡單的Timer定時器,這個在這裏很應景。於是就有了下面的自動點擊代碼:

  private static final int MSG_NODE_CLICK = 0x110;
//是否能夠不停點擊咻咻的開關
    private boolean isCanCyclingClick = false;


    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if(msg.what == MSG_NODE_CLICK){
                AccessibilityNodeInfo btnNode = (AccessibilityNodeInfo) msg.obj;
                btnNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
            }
        }
    };
//定時器
 private Timer timer;

    private void dontStopClick(final AccessibilityNodeInfo btn){
        if(timer == null){
            timer= new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    if(isCanCyclingClick){
                        Message m = mHandler.obtainMessage(MSG_NODE_CLICK, btn);
                        mHandler.sendMessage(m);
                    }
                }
            },100,100);
        }
    }

因爲子線程不能操作UI,所以使用了Handler幫忙傳輸數據(AccessibilityNodeInfo)。然後在Handler的handleMessage()方法中調用節點的點擊方法: btnNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);

講到這裏,就已經基本上實現了自動點擊了。
但是在點擊過程中,會出現一個彈框,比如下面的一種情況,而且彈框內容還是不停的隨機變化的:
alipay_luck_money_dialog
彈窗的出現會妨礙到自動點擊,因爲咻一咻的按鈕被遮住了。而且這個彈窗有可能是紅包或者是五福,需要領取的。因爲出現機率太小,我暫時沒法做測試。現在的處理方式,就是出現彈框,自動在1.5秒內(這樣自己可以手動領福或紅包)返回消失,然後自動繼續無限咻一咻:

if("android.app.Dialog".equals(event.getClassName())){//彈窗是Dialog

                    isCanCyclingClick = false;
                    wait(1500);
                    performGlobalAction(GLOBAL_ACTION_BACK);
  }

  private void wait(int microSeconds){
        try {
            Thread.sleep(microSeconds);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

上面這段代碼也是在AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED事件中處理的。

自此,基本實現好了支付寶自動咻一咻的功能。注意,在xml的配置中,要加上支付寶的包名,以讓它和微信一同成爲監控對象。同時咻一咻,同時搶微信紅包。
android:packageNames=”com.tencent.mm,com.eg.android.AlipayGphone”。
項目源碼地址:RedPack
開始玩Android Studio,開始更多的玩github,一起來玩吧!!

PS:
由於現在只在5.0上測試通過,多人反映4.x和5.1都無效,今天我找了很多方案,包括看了4.x和5.x的相關源碼,確實有一些改動。但對於爲什麼在其它地方無法點擊還是不甚清楚。不過發現使用adb 命令發送事件可以讓咻一咻的按鈕進行點擊,是在4.1的系統上測試的。命令是adb shell input keyevent 66(或者adb shell 之後,input keyevent 66),也就是發送回車按鍵KEYCODE_ENTER。
至於在代碼中的實現,大家可以嘗試下。權限問題也是蠻煩人的,赫赫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章