Android微信抢红包服务源码

Android微信抢红包服务源码

基于Android AccessibilityService,配套微信7.0.9版本,主要使用控件ID来获取AccessibilityNodeInfo,亲测好用!

RedPacketService.java 实现抢红包功能

package com.example.snatch;

import android.accessibilityservice.AccessibilityService;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.PowerManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.Toast;

import java.util.List;

/**
 * 抢红包Service,继承AccessibilityService
 */
public class RedPacketService extends AccessibilityService {
    /**
     * 微信几个页面的包名+地址。用于判断在哪个页面
     * LAUCHER-微信聊天界面
     * LUCKEY_MONEY_RECEIVER-点击红包弹出的界面
     * LUCKEY_MONEY_DETAIL-红包领取后的详情界面
     */
    private String LAUCHER = "com.tencent.mm.ui.LauncherUI";
    private String LUCKEY_MONEY_DETAIL = "com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI";
    private String LUCKEY_MONEY_RECEIVER = "com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyNotHookReceiveUI";

    private static final String TAG = "RedPacketService";

    //聊天界面“微信红包” TextView ID
    private String VIEW_ID_WXHB = "com.tencent.mm:id/aum";
    //聊天界面"已领取" TextView ID
    private String VIEW_ID_RECIEVED = "com.tencent.mm:id/aul";
    //打开红包界面“开” Button ID
    private String VIEW_ID_OPEN = "com.tencent.mm:id/dan";
    //得到的红包金额
    private String VIEW_ID_MONEY_AMOUNT = "com.tencent.mm:id/d62";
    //会话列表界面“微信红包” TextView ID
    private String VIEW_ID_CHET_LIST_WXHB = "com.tencent.mm:id/bal";
    //点击红包打开的界面 红包内容描述 TextView ID
    private String VIEW_ID_DESCRIPTION = "com.tencent.mm:id/dam";


    /**
     * 获取PowerManager.WakeLock对象
     */
    private PowerManager.WakeLock wakeLock;

    /**
     * KeyguardManager.KeyguardLock对象
     */
    private KeyguardManager.KeyguardLock keyguardLock;

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        if ((null == event.getPackageName())||(null == event.getClassName())){
            return;
        }
        String pkgName = event.getPackageName().toString();
        //如果不是微信
        if(!"com.tencent.mm".equals(pkgName)){
            return;
        }

        int eventType = event.getEventType();
        String className = event.getClassName().toString();
        Log.i(TAG, "onAccessibilityEvent eventType=" + eventType + " className=" + className);

        AccessibilityNodeInfo rootNode = getRootInActiveWindow();

        switch (eventType) {
            //通知栏来信息,判断是否含有微信红包字样,是的话跳转
            case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
                List<CharSequence> texts = event.getText();
                for (CharSequence text : texts) {
                    String content = text.toString();
                    Log.i(TAG, "TYPE_NOTIFICATION_STATE_CHANGED content=" + content);
                    if (!TextUtils.isEmpty(content)) {
                        //判断是否含有[微信红包]字样
                        if (content.contains("[微信红包]")) {
                            if (!isScreenOn()) {
                                wakeUpScreen();
                            }
                            //如果有则打开微信红包页面
                            openWeChatPage(event);
                        }
                    }
                }
                break;

            //窗口内容变化监听
            case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:

                //进入开红包界面前会有一个loading界面,之后开界面才刷新出来
                findNodeInfosByViewId(rootNode,VIEW_ID_OPEN);

                //会话界面来了个红包,只有内容的刷新
                findNodeInfosByViewId(rootNode,VIEW_ID_WXHB);

                //会话列表来了个红包,只有文字内容的刷新
                findNodeInfosByViewId(rootNode,VIEW_ID_CHET_LIST_WXHB);

                findNodeInfosByViewId(rootNode,VIEW_ID_DESCRIPTION);

                break;

            //界面跳转的监听
            case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:

                //判断是否是红包领取后的详情界面
                if (LUCKEY_MONEY_DETAIL.equals(className)) {
                    //获取到的红包金额
                    //findNodeInfosByViewId(rootNode,VIEW_ID_MONEY_AMOUNT);
                    performBackClick();
                //点微信红包后 开的那个界面
                } else if (LUCKEY_MONEY_RECEIVER.equals(className)){
                    //判断是否是显示‘开’的那个红包界面
                    int findResult = findNodeInfosByViewId(rootNode,VIEW_ID_OPEN);
                    Log.i(TAG, "findNodeInfosByViewId findResult=" + findResult);
                    //在开的界面但却没有找到开按钮,红包被别人抢光了
                    if (0 == findResult){
                        findNodeInfosByViewId(rootNode,VIEW_ID_DESCRIPTION);
                    }
                } else {
                    //微信聊天界面找微信红包
                    findNodeInfosByViewId(rootNode,VIEW_ID_WXHB);

                    //会话列表微信红包
                    findNodeInfosByViewId(rootNode,VIEW_ID_CHET_LIST_WXHB);
                }
                break;
        }
    }

    /**
     * 模拟返回操作
     */
    public void performBackClick() {
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.i(TAG, "performBackClick");
        performGlobalAction(GLOBAL_ACTION_BACK);
    }

    private int findNodeInfosByViewId(AccessibilityNodeInfo rootNode, String viewID) {
        if (null == rootNode){
            return -1;
        }

        List<AccessibilityNodeInfo> nodeInfoList = rootNode.findAccessibilityNodeInfosByViewId(viewID);
        for (int i = nodeInfoList.size()-1; i>=0; i--) {
            AccessibilityNodeInfo nodeInfo = nodeInfoList.get(i);
            CharSequence className = nodeInfo.getClassName();
            CharSequence text = nodeInfo.getText();
            CharSequence contentDes = nodeInfo.getContentDescription();
            AccessibilityNodeInfo parent = nodeInfo.getParent();
            Log.i(TAG, "findNodeInfosByViewId viewID=" + viewID + " className=" + className + " text=" + text + " contentDes=" + contentDes);

            //开界面
            if(VIEW_ID_OPEN.equals(viewID)){
                nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                return 1;
            //微信红包字样
            } else if(VIEW_ID_WXHB.equals(viewID)){
                List<AccessibilityNodeInfo> recieved = null;
                if (null != parent){
                    recieved = parent.getParent().findAccessibilityNodeInfosByViewId(VIEW_ID_RECIEVED);
                }
                //是否已经领过了
                if ((recieved != null) && recieved.size() > 0) {
                    Log.i(TAG, "findNodeInfosByViewId 这个已经领过了, continue");
                    continue;
                }
                Log.i(TAG, "VIEW_ID_WXHB 您有新的红包");
                //while循环,遍历"领取红包"的各个父布局,直至找到可点击的为止
                while (parent != null) {
                    if (parent.isClickable()) {
                        //模拟点击
                        parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                        return 2;
                    }
                    parent = parent.getParent();
                }
            //红包金额
//            } else if (VIEW_ID_MONEY_AMOUNT.equals(viewID)){
//                return true;
            } else if (VIEW_ID_CHET_LIST_WXHB.equals(viewID)){
                if (text.toString().contains("[微信红包]")){
                    //while循环,遍历"领取红包"的各个父布局,直至找到可点击的为止
                    Log.i(TAG, "VIEW_ID_CHET_LIST_WXHB 您有新的红包");
                    while (parent != null) {
                        if (parent.isClickable()) {
                            //模拟点击
                            parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                            return 3;
                        }
                        parent = parent.getParent();
                    }
                }
            } else if (VIEW_ID_DESCRIPTION.equals(viewID)){
                if (text.toString().contains("该红包已被领取") || text.toString().contains("红包派完了")){
                    performBackClick();
                }
                return 4;
            }
        }
        return  0;
    }

    /**
     * 开启红包所在的聊天页面
     */
    private void openWeChatPage(AccessibilityEvent event) {
        if (event.getParcelableData() != null && event.getParcelableData() instanceof Notification) {
            Notification notification = (Notification) event.getParcelableData();
            //打开对应的聊天界面
            PendingIntent pendingIntent = notification.contentIntent;
            Log.i(TAG, "openWeChatPage");
            try {
                pendingIntent.send();
            } catch (PendingIntent.CanceledException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 服务连接
     */
    @Override
    protected void onServiceConnected() {
        Toast.makeText(this, "抢红包服务开启", Toast.LENGTH_SHORT).show();
        super.onServiceConnected();
    }

    /**
     * 必须重写的方法:系统要中断此service返回的响应时会调用。在整个生命周期会被调用多次。
     */
    @Override
    public void onInterrupt() {
        Toast.makeText(this, "我快挂了啊---", Toast.LENGTH_SHORT).show();
    }

    /**
     * 服务断开
     */
    @Override
    public boolean onUnbind(Intent intent) {
        Toast.makeText(this, "抢红包服务关闭", Toast.LENGTH_SHORT).show();
        return super.onUnbind(intent);
    }

    /**
     * 返回桌面
     */
    private void back2Home() {
        Intent home = new Intent(Intent.ACTION_MAIN);
        home.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        home.addCategory(Intent.CATEGORY_HOME);
        startActivity(home);
    }

    /** 是否为锁屏或黑屏状态*/
    public boolean isLockScreen() {
        KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);

        return km.inKeyguardRestrictedInputMode() || !isScreenOn();
    }
    /**
     * 判断是否处于亮屏状态
     *
     * @return true-亮屏,false-暗屏
     */
    public boolean isScreenOn() {
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
            return pm.isInteractive();
        } else {
            return pm.isScreenOn();
        }
    }

    /**
     * 解锁屏幕
     */
    private void wakeUpScreen() {
        //先将锁释放
        release();
        //获取电源管理器对象
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        //后面的参数|表示同时传入两个值,最后的是调试用的Tag
        wakeLock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.FULL_WAKE_LOCK, "bright");
        //点亮屏幕
        wakeLock.acquire();

        //得到键盘锁管理器
        KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
        keyguardLock = km.newKeyguardLock("unlock");
        //解锁
        keyguardLock.disableKeyguard();
        Log.i(TAG, "wakeUpScreen wakeLock=" + wakeLock + " keyguardLock=" + keyguardLock);
    }

    /**
     * 释放keyguardLock和wakeLock
     */
    public void release() {
        if (keyguardLock != null) {
            keyguardLock.reenableKeyguard();
            keyguardLock = null;
        }
        if (wakeLock != null) {
            wakeLock.release();
            wakeLock = null;
        }
    }

}

redpacket_service_config.xml RedPacketService配置文件

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagDefault|flagRetrieveInteractiveWindows|flagIncludeNotImportantViews"
    android:canRetrieveWindowContent="true"
    android:description="@string/desc"
    android:notificationTimeout="100"
/>

AndroidManifest.xml 增加服务声明及权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.snatch">
    <!--解锁权限-->
    <uses-permission android:name="android.permission.DISABLE_KEYGUARD"></uses-permission>
    <!--亮屏权限-->
    <uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>

    <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
        <activity
                android:name=".MainActivity"
                android:label="@string/app_name"
                android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <!--抢红包服务-->
        <service
                android:name=".RedPacketService"
                android:enabled="true"
                android:exported="true"
                android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
            <intent-filter>
                <action android:name="android.accessibilityservice.AccessibilityService" />
            </intent-filter>
            <meta-data
                    android:name="android.accessibilityservice"
                    android:resource="@xml/redpacket_service_config"></meta-data>
        </service>
    </application>

</manifest>

Android微信抢红包服务源码

你可能感兴趣的:(Android微信抢红包服务源码)