微信自动回复和自动抢红包实现原理(三):自动抢红包

阅读该文章前,可以先阅读我前两篇文章 
微信自动回复和自动抢红包实现原理(一):AccessibilityService的介绍和配置 
微信自动回复和自动抢红包实现原理(二):自动回复


经过前两篇文章的阅读,我相信大家应该对AccessibilityService有一定的了解了,是不是已经按捺不住,想自己动手试试?先别急,可以再看完我这篇文章还不迟,相信你另有收获的。接下来我们来探索一下自动抢红包的实现原理。

看了我第二篇微信自动回复文章的朋友应该知道怎么做了,只是一些操作上不同: 
1. 监听TYPE_NOTIFICATION_STATE_CHANGED事件 
2. 根据Notification打开会话人聊天界面 
3. 搜索红包控件 
4. 点击红包控件,打开红包,如果红包已被抢,跳至第6步,否则执行第5步 
5. 点击红包界面的“开”按钮,抢红包 
6. 返回微信主界面

好吧,我们给测试手机微信发个红包,先打印log来看看,具体信息不贴了,直接看结果:

打开微信的界面
-------------------------------------------------------------
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
-------------------------------------------------------------
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

经我测试,LauncherUI只有微信在后台才会触发,但微信在前台时也会有Notification,所以有LuckyMoneyReceiveUI、LuckyMoneyDetailUI两个界面我们已经足够了

接下来的工作是找到相应的控件了。先找红包这个控件,给测试机微信发多几次红包,找到每个红包的相同点。

红包.png 
看到红色框框没,“领取红包”这个控件每次都不变了,可以根据其找到其父控件,再点击就可以打开红包了!

接下来就是红包界面的“开”按钮了。很遗憾,因为该按钮即每文本信息,也没特别的子控件,没办法,只能直接用控件的id了(但这种方法不好,因为据了解,控件的id经常会变,可能就会了防止这类插件的出现吧,哈哈),下面介绍如何获取控件的id。 
1.打开DDMS,连接手机,打开一个红包,进入红包界面,点击下面按钮 
DDMS.png 
2.选中你需要的控件,例如这里我们是要查看“开”按钮这控件 
开红包.png 
3.在右边就可以查看控件的信息了,右下方可以查看id 
QQ截图20160809224615.png

嗯,对的,红包的控件也可以这样获取,但我说过了,id是会变的,所以能不用就最好不要用。还有如果有朋友知道不用id获取“开”按钮的话,请告诉我一声哈。

好了,所有难点都解决了,接下来只要写代码处理下逻辑就好了,直接上代码吧。

**
 * 自动抢红包服务
 */
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);   // 唤醒点亮屏幕
                }

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


            default:
                Log.i(TAG, "DEFAULT");
                if(hasNotify) {
                    AccessibilityNodeInfo rootNode = getRootInActiveWindow();
                    clickLuckyMoney(rootNode); // 点击红包

                    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();
            }
        }
    }


    /**
     * 搜索并点击红包
     */
    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("领取红包")) {
                    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);
            }
        }
    };
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159

ok,到这里就全部讲完了,小伙伴们可以自己去实现更多更有趣、更新奇的功能了。这里我只是作为技术探索,容我再啰嗦两点: 
1. 朋友是很重要的,有空的话还是好好回复吧 
2. 红包只是一种噱头,一种娱乐方式,别当作谋财之道喔

扫描二维码关注公众号,回复: 1518350 查看本文章

源码下载

猜你喜欢

转载自blog.csdn.net/qq_21051503/article/details/80582997