Principle of Automatic Return and Red Packet Grabbing by Wechat (3): Red Packet Grabbing by Wechat

Before reading this article, you can read my first two articles first.
The Principle of Automatic Return and Red Packet Grabbing in Wechat (1): Introduction and Configuration of Accessibility Service
The Principle of Automatic Return and Red Packet Grabbing by Wechat (2): Automatic Return

After reading the first two articles, I believe that you should have a certain understanding of Accessibility Service. Can't you hold back and try it by yourself? Don't worry. It's not too late to finish my article. I'm sure you'll get something else. Next, let's explore the principle of automatic red envelope snatching.

Friends who read my second Wechat auto-reply article should know how to do it, but some operations are different:

  1. Listening for TYPE_NOTIFICATION_STATE_CHANGED events
  2. Open the conversation interface according to Notification
  3. Search Red Pack Control
  4. Click on the red envelope control, open the red envelope, if the red envelope has been robbed, jump to step 6, otherwise perform step 5
  5. Click on the "open" button of the red envelope interface to grab the red envelope
  6. Return to the Wechat main interface

Okay, let's send a red envelope to the test cell phone Wechat. First, print the log to see. The specific information is not posted. Look directly at the results.

Open the Interface of Wechat
-------------------------------------------------------------
PackageName:com.tencent.mm
Source Class:com.tencent.mm.ui.LauncherUI
Description:null
Event Type(int):32
-------------------------------------------------------------
Red Packet Receiving Interface (whether red Packet has not been grabbed or has been grabbed will open this interface)
-------------------------------------------------------------
PackageName:com.tencent.mm
Source Class:com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI
Description:null
Event Type(int):32
-------------------------------------------------------------
Red Packet Details Interface (that is, the interface after grabbing the red envelope)
-------------------------------------------------------------
PackageName:com.tencent.mm
Source Class:com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI
Description:null
Event Type(int):32
-------------------------------------------------------------

In my test, Launcher UI will only be triggered in the background by Wechat, but Wechat will also have Notification in the foreground, so we have Lucky Money Receive UI and Lucky Money Detail UI.

The next job is to find the appropriate controls. First, find the red envelope control, send the test machine micro-mail several times, find the same points of each red envelope.


Red envelope.png


See the red box does not exist, "get red envelope" this control is unchanged every time, you can find its parent control according to it, and then click to open the red envelope!

Next is the "open" button of the red envelope interface. Unfortunately, because the button is every text information, there is no special child control, there is no way to use the control's id directly (but this method is not good, because it is known that the control's id often changes, it may prevent the emergence of such plug-ins, haha). Here is how to get the control's id.
1. Open the DDMS, connect the phone, open a red envelope, enter the red envelope interface, click the button below.


DDMS.png


2. Select the control you need, for example, here we are going to look at the "Open" button control.


Open a red envelope.png


3. You can view the information of the control on the right and the id on the lower right.


QQ Section 2010 60809224615.png

Well, yes, red-envelope controls can also be obtained in this way, but as I said, IDS change, so it's better not to use them if you can't use them. And if a friend knows to get the "on" button without id, please let me know.

Well, all the difficulties have been solved. Next, just write the code to deal with the logic. Go straight to the code.

**
 * Automatic Red Pack Service
 */
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(); // Event type
        switch (eventType) {
            case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED: // Notification Bar Events
                Log.i(TAG, "TYPE_NOTIFICATION_STATE_CHANGED");
                if(PhoneController.isLockScreen(this)) { // Lock screen
                    PhoneController.wakeAndUnlockScreen(this);   // Wake up and light up the screen
                }

                openAppByNotification(event); // Open WeChat
                hasNotify = true;
                break;


            default:
                Log.i(TAG, "DEFAULT");
                if(hasNotify) {
                    AccessibilityNodeInfo rootNode = getRootInActiveWindow();
                    clickLuckyMoney(rootNode); // Click on the red envelope.

                    String className = event.getClassName().toString();
                    if (className.equals(UI.LUCKY_MONEY_RECEIVE_UI)) { //Red Packet Receiving Interface
                        if(!openLuckyMoney()) { // If the red envelope is stolen, return to the main interface
                            backToHome();
                            hasNotify = false;
                        }
                        hasLuckyMoney = true;
                    } else if (className.equals(UI.LUCKY_MONEY_DETAIL_UI)) { // Grab red packets
                        backToHome();
                        hasNotify = false;
                        hasLuckyMoney = true;
                    } else { // Deal with the situation without red envelope, return to the main interface directly
                        if(!hasLuckyMoney) {
                            handler.sendEmptyMessage(MSG_BACK_ONCE);
                            hasLuckyMoney = true;   // Prevent backsliding many times
                        }
                    }
                }
                break;
        }
    }

    @Override
    public void onInterrupt() {
    }


    /**
     * Open WeChat
     * @param event 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();
            }
        }
    }


    /**
     * Search and click on the red envelope
     */
    private void clickLuckyMoney(AccessibilityNodeInfo rootNode) {
        if(rootNode != null) {
            int count = rootNode.getChildCount();
            for (int i = count - 1; i >= 0; i--) {  // Looking for the latest red envelopes in reverse order
                AccessibilityNodeInfo node = rootNode.getChild(i);
                if (node == null)
                    continue;

                CharSequence text = node.getText();
                if (text != null && text.toString().equals("Receive a red envelope")) {
                    AccessibilityNodeInfo parent = node.getParent();
                    while (parent != null) {
                        if (parent.isClickable()) {
                            parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                            break;
                        }
                        parent = parent.getParent();
                    }
                }

                clickLuckyMoney(node);
            }
        }
    }

    /**
     * Open the red envelope
     */
    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, that's all for now. Little buddies can achieve more interesting and novel functions by themselves. Here I am just exploring technology, let me repeat two points:

  • Friends are very important. If you have time, please reply well.
  • Red envelope is just a gimmick, a way of entertainment, don't use it as a way to make money.

Source download

Source: http://www.jianshu.com/p/405330b2ecd8

Posted by jexx on Tue, 09 Apr 2019 23:39:31 -0700