微信自動回復(fù)和自動搶紅包實(shí)現(xiàn)原理(三):自動搶紅包

閱讀該文章前,可以先閱讀我前兩篇文章
微信自動回復(fù)和自動搶紅包實(shí)現(xiàn)原理(一):AccessibilityService的介紹和配置
微信自動回復(fù)和自動搶紅包實(shí)現(xiàn)原理(二):自動回復(fù)


經(jīng)過前兩篇文章的閱讀,我相信大家應(yīng)該對AccessibilityService有一定的了解了爵卒,是不是已經(jīng)按捺不住侠仇,想自己動手試試从隆?先別急歉眷,可以再看完我這篇文章還不遲崇决,相信你另有收獲的材诽。接下來我們來探索一下自動搶紅包的實(shí)現(xiàn)原理底挫。

看了我第二篇微信自動回復(fù)文章的朋友應(yīng)該知道怎么做了,只是一些操作上不同:

  1. 監(jiān)聽TYPE_NOTIFICATION_STATE_CHANGED事件
  • 根據(jù)Notification打開會話人聊天界面
  • 搜索紅包控件
  • 點(diǎn)擊紅包控件脸侥,打開紅包建邓,如果紅包已被搶,跳至第6步湿痢,否則執(zhí)行第5步
  • 點(diǎn)擊紅包界面的“開”按鈕涝缝,搶紅包
  • 返回微信主界面

好吧扑庞,我們給測試手機(jī)微信發(fā)個紅包譬重,先打印log來看看,具體信息不貼了罐氨,直接看結(jié)果:

打開微信的界面
-------------------------------------------------------------
PackageName:com.tencent.mm
Source Class:com.tencent.mm.ui.LauncherUI
Description:null
Event Type(int):32
-------------------------------------------------------------
紅包接收界面(不管紅包還沒搶光還是已被搶光都會打開這個界面)
-------------------------------------------------------------
PackageName:com.tencent.mm
Source Class:com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI
Description:null
Event Type(int):32
-------------------------------------------------------------
紅包詳情界面(也就是搶到紅包以后的界面)
-------------------------------------------------------------
PackageName:com.tencent.mm
Source Class:com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI
Description:null
Event Type(int):32
-------------------------------------------------------------

經(jīng)我測試臀规,LauncherUI只有微信在后臺才會觸發(fā),但微信在前臺時也會有Notification栅隐,所以有LuckyMoneyReceiveUI塔嬉、LuckyMoneyDetailUI兩個界面我們已經(jīng)足夠了

接下來的工作是找到相應(yīng)的控件了。先找紅包這個控件租悄,給測試機(jī)微信發(fā)多幾次紅包谨究,找到每個紅包的相同點(diǎn)。

紅包.png

看到紅色框框沒泣棋,“領(lǐng)取紅包”這個控件每次都不變了胶哲,可以根據(jù)其找到其父控件,再點(diǎn)擊就可以打開紅包了潭辈!

接下來就是紅包界面的“開”按鈕了鸯屿。很遺憾,因?yàn)樵摪粹o即每文本信息把敢,也沒特別的子控件寄摆,沒辦法,只能直接用控件的id了(但這種方法不好修赞,因?yàn)閾?jù)了解婶恼,控件的id經(jīng)常會變,可能就會了防止這類插件的出現(xiàn)吧柏副,哈哈)熙尉,下面介紹如何獲取控件的id。
1.打開DDMS搓扯,連接手機(jī)检痰,打開一個紅包,進(jìn)入紅包界面锨推,點(diǎn)擊下面按鈕


DDMS.png

2.選中你需要的控件铅歼,例如這里我們是要查看“開”按鈕這控件


開紅包.png

3.在右邊就可以查看控件的信息了公壤,右下方可以查看id
QQ截圖20160809224615.png

嗯,對的椎椰,紅包的控件也可以這樣獲取厦幅,但我說過了,id是會變的慨飘,所以能不用就最好不要用确憨。還有如果有朋友知道不用id獲取“開”按鈕的話,請告訴我一聲哈瓤的。

好了休弃,所有難點(diǎn)都解決了,接下來只要寫代碼處理下邏輯就好了圈膏,直接上代碼吧塔猾。

**
 * 自動搶紅包服務(wù)
 */
public class AutoOpenLuckyMoneyService extends AccessibilityService{

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

    private static final int MSG_BACK_HOME = 0;
    private static final int MSG_BACK_ONCE = 1;
    boolean hasNotify = false;
    boolean hasLuckyMoney = true;


    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        int eventType = event.getEventType(); // 事件類型
        switch (eventType) {
            case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED: // 通知欄事件
                Log.i(TAG, "TYPE_NOTIFICATION_STATE_CHANGED");
                if(PhoneController.isLockScreen(this)) { // 鎖屏
                    PhoneController.wakeAndUnlockScreen(this);   // 喚醒點(diǎn)亮屏幕
                }

                openAppByNotification(event); // 打開微信
                hasNotify = true;
                break;


            default:
                Log.i(TAG, "DEFAULT");
                if(hasNotify) {
                    AccessibilityNodeInfo rootNode = getRootInActiveWindow();
                    clickLuckyMoney(rootNode); // 點(diǎn)擊紅包

                    String className = event.getClassName().toString();
                    if (className.equals(UI.LUCKY_MONEY_RECEIVE_UI)) { //紅包接收界面
                        if(!openLuckyMoney()) { // 如果紅包被搶光了,就返回主界面
                            backToHome();
                            hasNotify = false;
                        }
                        hasLuckyMoney = true;
                    } else if (className.equals(UI.LUCKY_MONEY_DETAIL_UI)) { // 搶到紅包
                        backToHome();
                        hasNotify = false;
                        hasLuckyMoney = true;
                    } else { // 處理沒紅包的情況稽坤,直接返回主界面
                        if(!hasLuckyMoney) {
                            handler.sendEmptyMessage(MSG_BACK_ONCE);
                            hasLuckyMoney = true;   // 防止后退多次
                        }
                    }
                }
                break;
        }
    }

    @Override
    public void onInterrupt() {
    }


    /**
     * 打開微信
     * @param event 事件
     */
    private void openAppByNotification(AccessibilityEvent event) {
        if (event.getParcelableData() != null  && event.getParcelableData() instanceof Notification) {
            Notification notification = (Notification) event.getParcelableData();
            try {
                PendingIntent pendingIntent = notification.contentIntent;
                pendingIntent.send();
            } catch (PendingIntent.CanceledException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 搜索并點(diǎn)擊紅包
     */
    private void clickLuckyMoney(AccessibilityNodeInfo rootNode) {
        if(rootNode != null) {
            int count = rootNode.getChildCount();
            for (int i = count - 1; i >= 0; i--) {  // 倒序查找最新的紅包
                AccessibilityNodeInfo node = rootNode.getChild(i);
                if (node == null)
                    continue;

                CharSequence text = node.getText();
                if (text != null && text.toString().equals("領(lǐng)取紅包")) {
                    AccessibilityNodeInfo parent = node.getParent();
                    while (parent != null) {
                        if (parent.isClickable()) {
                            parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                            break;
                        }
                        parent = parent.getParent();
                    }
                }

                clickLuckyMoney(node);
            }
        }
    }

    /**
     * 打開紅包
     */
    private boolean openLuckyMoney() {
        AccessibilityNodeInfo rootNode = getRootInActiveWindow();
        if(rootNode != null) {
            List<AccessibilityNodeInfo> nodes =
                    rootNode.findAccessibilityNodeInfosByViewId(UI.OPEN_LUCKY_MONEY_BUTTON_ID);
            for(AccessibilityNodeInfo node : nodes) {
                if(node.isClickable()) {
                    Log.i(TAG, "open LuckyMoney");
                    node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    return true;
                }
            }
        }

        return false;
    }

    private void backToHome() {
        if(handler.hasMessages(MSG_BACK_HOME)) {
            handler.removeMessages(MSG_BACK_HOME);
        }
        handler.sendEmptyMessage(MSG_BACK_HOME);
    }

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if(msg.what == MSG_BACK_HOME) {
                performGlobalAction(GLOBAL_ACTION_BACK);
                postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        performGlobalAction(GLOBAL_ACTION_BACK);
                        hasLuckyMoney = false;
                    }
                }, 1500);
            } else if(msg.what == MSG_BACK_ONCE) {
                postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        Log.i(TAG, "click back");
                        performGlobalAction(GLOBAL_ACTION_BACK);
                        hasLuckyMoney = false;
                        hasNotify = false;
                    }
                }, 1500);
            }
        }
    };
}

ok丈甸,到這里就全部講完了,小伙伴們可以自己去實(shí)現(xiàn)更多更有趣尿褪、更新奇的功能了睦擂。這里我只是作為技術(shù)探索,容我再啰嗦兩點(diǎn):

  • 朋友是很重要的杖玲,有空的話還是好好回復(fù)吧
  • 紅包只是一種噱頭顿仇,一種娛樂方式,別當(dāng)作謀財之道喔

源碼下載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末天揖,一起剝皮案震驚了整個濱河市夺欲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌今膊,老刑警劉巖些阅,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異斑唬,居然都是意外死亡市埋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進(jìn)店門恕刘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缤谎,“玉大人,你說我怎么就攤上這事褐着】涝瑁” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵含蓉,是天一觀的道長频敛。 經(jīng)常有香客問我项郊,道長,這世上最難降的妖魔是什么斟赚? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任着降,我火速辦了婚禮,結(jié)果婚禮上拗军,老公的妹妹穿的比我還像新娘任洞。我一直安慰自己,他們只是感情好发侵,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布交掏。 她就那樣靜靜地躺著,像睡著了一般器紧。 火紅的嫁衣襯著肌膚如雪耀销。 梳的紋絲不亂的頭發(fā)上楼眷,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天铲汪,我揣著相機(jī)與錄音,去河邊找鬼罐柳。 笑死掌腰,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的张吉。 我是一名探鬼主播齿梁,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼肮蛹!你這毒婦竟也來了勺择?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤伦忠,失蹤者是張志新(化名)和其女友劉穎省核,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體昆码,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡气忠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了赋咽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旧噪。...
    茶點(diǎn)故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖脓匿,靈堂內(nèi)的尸體忽然破棺而出淘钟,到底是詐尸還是另有隱情,我是刑警寧澤陪毡,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布米母,位于F島的核電站袱瓮,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏爱咬。R本人自食惡果不足惜尺借,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望精拟。 院中可真熱鬧燎斩,春花似錦、人聲如沸蜂绎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽师枣。三九已至怪瓶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間践美,已是汗流浹背洗贰。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留陨倡,地道東北人敛滋。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像兴革,于是被迫代替她去往敵國和親绎晃。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容