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

来源:互联网 发布:php 自动化部署工具 编辑:程序博客网 时间:2024/04/28 07:33

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


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

看了我第二篇微信自动回复文章的朋友应该知道怎么做了,只是一些操作上不同:

  1. 监听TYPE_NOTIFICATION_STATE_CHANGED事件
  2. 根据Notification打开会话人聊天界面
  3. 搜索红包控件
  4. 点击红包控件,打开红包,如果红包已被抢,跳至第6步,否则执行第5步
  5. 点击红包界面的“开”按钮,抢红包
  6. 返回微信主界面

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

打开微信的界面-------------------------------------------------------------PackageName:com.tencent.mmSource Class:com.tencent.mm.ui.LauncherUIDescription:nullEvent Type(int):32-------------------------------------------------------------红包接收界面(不管红包还没抢光还是已被抢光都会打开这个界面)-------------------------------------------------------------PackageName:com.tencent.mmSource Class:com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUIDescription:nullEvent Type(int):32-------------------------------------------------------------红包详情界面(也就是抢到红包以后的界面)-------------------------------------------------------------PackageName:com.tencent.mmSource Class:com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUIDescription:nullEvent Type(int):32-------------------------------------------------------------

经我测试,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);            }        }    };}

ok,到这里就全部讲完了,小伙伴们可以自己去实现更多更有趣、更新奇的功能了。这里我只是作为技术探索,容我再啰嗦两点:

  • 朋友是很重要的,有空的话还是好好回复吧
  • 红包只是一种噱头,一种娱乐方式,别当作谋财之道喔

源码下载

Source: http://www.jianshu.com/p/405330b2ecd8
0 0
原创粉丝点击