QQ/微信自动抢红包软件

版权声明:本文为博主原创文章,未经博主允许不得转载。转载请注明出处。 https://blog.csdn.net/qq_36882793/article/details/85050976

以下:内容参考自乱七八糟哪都有的地方。 内容仅用于自我记录学习使用。该程序在QQ方面存在bug,不建议使用。关于辅助类的基础使用这里不再叙述。可以参考https://www.cnblogs.com/popfisher/p/7455754.html该内容

主要是通过AccessibilityService,即辅助Service实现的。可以通过AccessibilityService实现监控屏幕内容变化,模拟用户操作等功能。

下面是对AccessibilityService中常用的方法的介绍
disableSelf():禁用当前服务,也就是在服务可以通过该方法停止运行

findFoucs(int falg):查找拥有特定焦点类型的控件

getRootInActiveWindow():如果配置能够获取窗口内容,则会返回当前活动窗口的根结点

getSeviceInfo():获取当前服务的配置信息

onAccessibilityEvent(AccessibilityEvent event):有关AccessibilityEvent事件的回调函数,系统通过sendAccessibiliyEvent()不断的发送AccessibilityEvent到此处

performGlobalAction(int action):执行全局操作,比如返回,回到主页,打开最近等操作

setServiceInfo(AccessibilityServiceInfo info):设置当前服务的配置信息

getSystemService(String name):获取系统服务

onKeyEvent(KeyEvent event):如果允许服务监听按键操作,该方法是按键事件的回调,需要注意,这个过程发生了系统处理按键事件之前

onServiceConnected():系统成功绑定该服务时被触发,也就是当你在设置中开启相应的服务,系统成功的绑定了该服务时会触发,通常我们可以在这里做一些初始化操作

onInterrupt():服务中断时的回调

BaseAccessibilityService
基类Service,主要供QQ和微信Service继承使用。提供了一些基本方法。

package com.example.qxb_810.qianghongbaodemo.service;

import android.accessibilityservice.AccessibilityService;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Build;
import android.os.PowerManager;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.Button;
import com.example.qxb_810.qianghongbaodemo.common.EventTypes;

import com.example.qxb_810.qianghongbaodemo.listener.ScreenListener;

import java.util.List;

import static android.content.ContentValues.TAG;

/**
 * @Data :  2018/12/13
 * @Des : 辅助Service基类
 */
@TargetApi(Build.VERSION_CODES.N)
public class BaseAccessibilityService extends AccessibilityService {
    //锁屏、解锁相关
    protected KeyguardManager.KeyguardLock mKeyguardLock;
    //唤醒屏幕相关
    protected PowerManager.WakeLock mWakeLock = null;
    protected String mEnvelopeKey = "";
    protected AccessibilityNodeInfo mRootNodeInfo;
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        mRootNodeInfo = event.getSource();
        if (mRootNodeInfo == null) return;
        // 判断事件类型
        switch (event.getEventType()) {
            // 如果状态栏改变
            case EventTypes.TYPE_NOTIFICATION_STATE_CHANGED:
                progressStatusBar(event, mEnvelopeKey);
                break;
            case EventTypes.TYPE_WINDOW_STATE_CHANGED:
            case EventTypes.TYPE_WINDOW_CONTENT_CHANGED:   //  window窗口内容或者状态改变的时候
                Log.e(TAG, "事件类型  " + (event.getEventType() == 32 ? "TYPE_WINDOW_STATE_CHANGED" : "TYPE_WINDOW_CONTENT_CHANGED"));
                // 处理其他聊天窗口的红包信息
                progressOtherChat(event);
                //  处理当前页面红包信息
                progressCurrChat(event);
                break;
        }
    }

    /**
     *  处理状态栏消息
     * @param event
     * @param envelopeKey 关键字
     */
    protected void progressStatusBar(AccessibilityEvent event, String envelopeKey) {
        List<CharSequence> text = event.getText();
        if (text != null && !text.isEmpty()) {
            text.stream().filter(t -> t.toString().contains(envelopeKey))
                    .forEach(t -> {
                        // 到达这一步说明存在红包,则跳转进去
                        if (event.getParcelableData() != null && event.getParcelableData() instanceof Notification) {
                            try {
                                Notification notification = (Notification) event.getParcelableData();
                                PendingIntent intent = notification.contentIntent;
                                // 这里需要处理一下解锁操作
                                //要跳转之前,先进行解锁屏幕,然后再跳转,有可能你现在屏幕是锁屏状态,先进行解锁,然后打开页面,有密码的可能就不行了
                                wakeUpAndUnlock(getApplicationContext());
                                intent.send();
                            } catch (PendingIntent.CanceledException e) {
                                e.printStackTrace();
                            }
                        }

                    });
        }
    }

    /**
     * 处理其他聊天页消息
     *
     * @param event
     */
    protected void progressOtherChat(AccessibilityEvent event) {

    }

    /**
     * 处理当前聊天页消息
     *
     * @param event
     */
    protected void progressCurrChat(AccessibilityEvent event) {

    }

    /**
     * 唤醒屏幕并解锁权限
     */
    @SuppressLint("Wakelock")
    @SuppressWarnings("deprecation")
    protected void wakeUpAndUnlock(Context context) {
        // 点亮屏幕
        mWakeLock.acquire();
        // 释放
        mWakeLock.release();
        // 解锁
        mKeyguardLock.disableKeyguard();
    }

    /**
     * 模拟返回操作
     */
    protected void performBackClick() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        performGlobalAction(GLOBAL_ACTION_BACK);
    }

    /**
     * 模拟返回操作
     */
    protected void performBackClick(int time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        performGlobalAction(GLOBAL_ACTION_BACK);
    }

    /**
     * 模拟下滑操作
     */
    public void performScrollBackward() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        performGlobalAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
    }

    /**
     * 模拟上滑操作
     */
    public void performScrollForward() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        performGlobalAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
    }


    /**
     * 查找对应ID
     *
     * @param id
     * @return
     */
    protected AccessibilityNodeInfo findViewByID(String id) {
        AccessibilityNodeInfo accessibilityNodeInfo = getRootInActiveWindow();
        if (accessibilityNodeInfo == null) {
            return null;
        }
        List<AccessibilityNodeInfo> nodeInfoList = accessibilityNodeInfo.findAccessibilityNodeInfosByViewId(id);
        if (nodeInfoList != null && !nodeInfoList.isEmpty()) {
            for (AccessibilityNodeInfo nodeInfo : nodeInfoList) {
                if (nodeInfo != null) {
                    return nodeInfo;
                }
            }
        }
        return null;
    }

    /**
     * 模拟发送信息
     *
     * @param key
     * @param time
     */
    protected void replyMessage(String key, int time) {
        //延迟
        if (time > 0) {
            try {
                Thread.sleep(time);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //获取QQ聊天页面输入框
        AccessibilityNodeInfo chat_edit = findViewByID(EventTypes.QQ_CHAT_MESSAGE_INPUT);
        if (chat_edit != null) {
            //把口令粘贴到输入框中
            pastaText(chat_edit, getApplicationContext(), key);
            //获取QQ聊天页面发送消息按钮
            AccessibilityNodeInfo sendMessage = findViewByID(EventTypes.QQ_CHAT_MESSAGE_SEND);
            //然后就按下发送按钮
            if (sendMessage != null && Button.class.getName().equals(sendMessage.getClassName())) {
                performViewClick(sendMessage);
            }
        }

    }

    /**
     * 粘贴口令到输入框
     *
     * @param nodeInfo
     * @param context
     * @param key
     */
    protected void pastaText(AccessibilityNodeInfo nodeInfo, Context context, String key) {
        //android>21 = 5.0时可以用ACTION_SET_TEXT
        //android>18 3.0.1可以通过复制的手段,先确定焦点,再粘贴ACTION_PASTE
        //使用剪切板
        ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
        //获取焦点
        nodeInfo.performAction(AccessibilityNodeInfo.ACTION_FOCUS);
        //需要替换的key
        clipboard.setPrimaryClip(ClipData.newPlainText("text", key));
        //粘贴进入内容
        nodeInfo.performAction(AccessibilityNodeInfo.ACTION_PASTE);
    }

    /**
     * 模拟点击事件
     *
     * @param nodeInfo nodeInfo
     */
    protected void performViewClick(AccessibilityNodeInfo nodeInfo) {
        if (nodeInfo == null) {
            return;
        }
        while (nodeInfo != null) {
            if (nodeInfo.isClickable()) {
                nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                break;
            }
            nodeInfo = nodeInfo.getParent();
        }
    }

    @Override
    public void onInterrupt() {
        interrupt();
    }

    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
        serviceConnected();
        // 获取电源管理器对象
        PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
        // 获取PowerManager.WakeLock对象,后面的参数|表示同时传入两个值,最后的是调试用的Tag
        mWakeLock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright");
        KeyguardManager km = (KeyguardManager) getApplicationContext().getSystemService(Context.KEYGUARD_SERVICE);
        mKeyguardLock = km.newKeyguardLock("unLock");

        //初始化屏幕的监听
        ScreenListener screenListener = new ScreenListener(getApplicationContext());
        screenListener.begin(new ScreenListener.ScreenStateListener() {
            @Override
            public void onScreenOn() {
                Log.e("ScreenListener", "屏幕打开了");
            }

            @Override
            public void onScreenOff() {
                //在屏幕关闭的时候,进行锁屏,不执行的话,锁屏就失效了,因为要实现锁屏状态下也可以进行抢红包。
                Log.e("ScreenListener", "屏幕关闭了");
                if (mKeyguardLock != null) {
                    mKeyguardLock.disableKeyguard();
                    mKeyguardLock.reenableKeyguard();
                }
            }

            @Override
            public void onUserPresent() {
                Log.e("ScreenListener", "解锁了");
            }
        });
    }

    /**
     *  断开时操作
     */
    protected void interrupt() {
    }

    /**
     *  连接时操作
     */
    protected void serviceConnected() {
    }
}

QQAccessibilityService — QQ还有bug未解决,会重复点击以拆开红包并且不停。尝试用几种方式解决,最后因无法标识红包是否已拆开,所以目前仍未解决这个问题,所以建议不要使用。
另外,该程序不会点击“你已领取XXXX的红包/口令红包”提示之前的红包,虽然没什么卵用。

package com.example.qxb_810.qianghongbaodemo.service;

import android.annotation.TargetApi;
import android.graphics.Rect;
import android.os.Build;
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.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.stream.Collectors;


/**
 * @Data :  2018/12/12
 * @Des : QQ服务类基类
 */
@TargetApi(Build.VERSION_CODES.N)
public class QQAccessibilityService extends BaseAccessibilityService {
    private static final String TAG = QQAccessibilityService.class.getSimpleName();

    private static final int MAX_CACHE_TOLERANCE = 100;     // 缓存最大的红包数量
    private static final String ENVELOPE_NORMAL_KEY = "点击查看详情";   // 普通红包
    private static final String ENVELOPE_PASSWORD_KEY = "口令红包";  // 口令红包
    private static final String ENVELOPE_OPENED = "你领取了";  // 领取过后的红包
    private Queue<String> mNodeIdQueue = new LinkedList<>();      // 存储已经领取的红包的id
    private int mOpenedCount;   // 已领取数量
    protected boolean isBackStatus = false; // 是否是返回触发状态
    private int mMaxTop = 0;

    @Override
    public void onCreate() {
        super.onCreate();
        mEnvelopeKey = "[QQ红包]";
    }

    /**
     * 处理QQ当前窗口的红包信息
     *
     * @param event
     */
    @Override
    protected void progressCurrChat(AccessibilityEvent event) {
        AccessibilityNodeInfo rootInActiveWindow = getRootInActiveWindow();
        if (rootInActiveWindow == null) return;
        // 返回状态不更新视图
        if (isBackStatus) {
            Log.e(TAG, "isBackStatus 状态 false");
            isBackStatus = false;
            return;
        }
        // 已领取的红包集
        mMaxTop = 0;
        List<AccessibilityNodeInfo> accessibilityNodeInfoList = rootInActiveWindow.findAccessibilityNodeInfosByText(ENVELOPE_OPENED);
        accessibilityNodeInfoList.stream().filter(e -> e.getText() != null && (e.getText().toString().endsWith("的红包。") || e.getText().toString().endsWith("的口令红包。")))
                .forEach(e -> {
                    Rect screenRect = new Rect();
                    e.getBoundsInScreen(screenRect);
                    mMaxTop = screenRect.top > mMaxTop ? screenRect.top : mMaxTop;
                });
        List<AccessibilityNodeInfo> envelopeTextList = findNodeInfosByTexts(rootInActiveWindow, new String[]{ENVELOPE_NORMAL_KEY, ENVELOPE_PASSWORD_KEY});
        envelopeTextList.stream().forEach(t -> {
            // 如果是口令红包
            if (t.getText() != null && t.getText().toString().contains(ENVELOPE_PASSWORD_KEY)) {
                progressPassword(t);
            } else {
                progressNormal(t);
            }
        });
    }

    /**
     * 根据Text查找文本内容
     *
     * @param text
     */
    private List<AccessibilityNodeInfo> findNodeInfosByTexts(AccessibilityNodeInfo rootInActiveWindow, String[] text) {
        List<AccessibilityNodeInfo> envelopeTextList = new ArrayList<>();
        Arrays.stream(text).forEach(t -> {
            List<AccessibilityNodeInfo> accessibilityNodeInfosByText = rootInActiveWindow.findAccessibilityNodeInfosByText(t);
            envelopeTextList.addAll(accessibilityNodeInfosByText.stream().filter(tt -> {
                Rect rect = new Rect();
                tt.getBoundsInScreen(rect);
                return rect.top > mMaxTop;
            }).collect(Collectors.toList()));
        });
        // 根据屏幕坐标排序
//        Collections.sort(envelopeTextList, (o1, o2) -> {
//            Rect o1ScreenRect = new Rect();
//            o1.getBoundsInScreen(o1ScreenRect);
//            Rect o2ScreenRect = new Rect();
//            o2.getBoundsInScreen(o2ScreenRect);
//            return o1ScreenRect.top - o2ScreenRect.top;
//        });

        return envelopeTextList;
    }

    /**
     * 处理普通红包
     */
    private void progressNormal(AccessibilityNodeInfo normaNodeInfo) {
        performViewClick(normaNodeInfo);
        performBackClick(1000);
        isBackStatus = true;
        Log.e(TAG, "progressNormal 状态 true");
    }


    /**
     * 处理口令红包
     */
    private void progressPassword(AccessibilityNodeInfo passwordNodeInfo) {
        AccessibilityNodeInfo parent = passwordNodeInfo.getParent();
        if (parent != null) {
            CharSequence contentDescription = parent.getContentDescription();
            if (!TextUtils.isEmpty(contentDescription)) {
                // 获取口令
                String key = contentDescription.toString();
                if (key.contains(",") && key.contains("口令:")) {
                    key = key.substring(key.indexOf("口令:") + 3, key.lastIndexOf(","));
                    // 填写口令并发送
                    replyMessage(key, 0);
                    performBackClick(1000);
                    isBackStatus = true;
                    Log.e(TAG, "progressPassword 状态 true");
                }
            }
        }
    }

    /**
     * 处理其他聊天窗口的红包信息
     */
    @Override
    protected void progressOtherChat(AccessibilityEvent event) {
        AccessibilityNodeInfo source = event.getSource();
        if (source != null) {
            //根据event的source里的text,来判断这个消息是否包含[QQ红包]的字眼,有的话就跳转过去
            CharSequence text = source.getText();
            if (!TextUtils.isEmpty(text) && text.toString().contains(mEnvelopeKey)) {
                performViewClick(source);
            }
        }
    }

    @Override
    protected void interrupt() {
        Toast.makeText(this, "QQ抢红包服务已关闭", Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void serviceConnected() {
        Toast.makeText(this, "QQ抢红包服务已开启", Toast.LENGTH_SHORT).show();
    }

}

WXAccessibilityService 辅助Service — 与QQ流程相似, 比QQ多一个点击开的环节。

package com.example.qxb_810.qianghongbaodemo.service;

import android.annotation.TargetApi;
import android.os.Build;
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;

/**

 * @Data :  2018/12/12
 * @Des :   QQ服务服务Service
 */
@TargetApi(Build.VERSION_CODES.N)
public class WXAccessibilityService extends BaseAccessibilityService {
    private static final String TAG = WXAccessibilityService.class.getSimpleName();
    private static final String ENVELOPE_STATUS_KEY = "[微信红包]";   // 状态栏提示红包
    private static final String ENVELOPE_NORMAL_KEY = "领取红包";   // 未领取标志

    @Override
    public void onCreate() {
        super.onCreate();
        mEnvelopeKey = "[微信红包]";
    }

    /**
     * 处理其他聊天窗口的红包信息
     */
    @Override
    protected void progressOtherChat(AccessibilityEvent event) {
        AccessibilityNodeInfo source = event.getSource();
        if (source != null) {
            //根据event的source里的text,来判断这个消息是否包含[QQ红包]的字眼,有的话就跳转过去
            CharSequence text = source.getText();
            if (!TextUtils.isEmpty(text) && text.toString().contains(ENVELOPE_STATUS_KEY)) {
                performViewClick(source);
            }
        }
    }

    /**
     * 处理普通红包
     *
     * @param normalList
     */
    private void progressNormal(List<AccessibilityNodeInfo> normalList) {
        if (normalList != null && !normalList.isEmpty()) {
            // 过滤点击
            normalList.stream().forEach(t -> {
                performViewClick(t);
                Log.e(TAG, "红包控件的类名是 : " + t.getClassName().toString());
            });
        }
    }

    /**
     * 处理QQ当前窗口的红包信息
     *
     * @param event
     */
    @Override
    protected void progressCurrChat(AccessibilityEvent event) {
        AccessibilityNodeInfo rootInActiveWindow = getRootInActiveWindow();
        if (rootInActiveWindow == null) return;
        // 找到含有关键文本的控件
        List<AccessibilityNodeInfo> envelopeNormalTextList = rootInActiveWindow.findAccessibilityNodeInfosByText(ENVELOPE_NORMAL_KEY);      // 处理普通红包
        progressNormal(envelopeNormalTextList);
        progressDialog();
    }


    /**
     * 处理红包弹窗后的红包领取
     */
    private void progressDialog() {
        AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
        if (nodeInfo == null) {
            return;
        }
        List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText("恭喜");
        for (int i = list.size() - 1; i >= 0; i--) {
            AccessibilityNodeInfo parent = list.get(i).getParent();
            for (int j = 0; j < parent.getChildCount(); j++) {
                AccessibilityNodeInfo child = parent.getChild(j);
                if (child != null && child.isClickable()) {
                    child.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    performBackClick(1200);
                    break;
                }
            }
        }
    }
    @Override
    protected void interrupt(){
        Toast.makeText(this, "微信抢红包服务已关闭", Toast.LENGTH_SHORT).show();
    }
    @Override
    protected void serviceConnected() {
        Toast.makeText(this, "微信抢红包服务已开启", Toast.LENGTH_SHORT).show();
    }
}

接下来在res目录下建立xml文件夹并创建一下两个xml,用于配置两个Service。

envelope_service_config_qq.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- 关键是android:accessibilityEventTypes="typeAllMask", typeAllMask代表监听所有的事件,这边不写的话,AccessibilityService就接收不到 -->
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagRequestFilterKeyEvents"
    android:canRetrieveWindowContent="true"
    android:canRequestFilterKeyEvents="true"
    android:description="@string/app_name"
    android:notificationTimeout="100"
    android:packageNames="com.tencent.mobileqq" />

envelope_service_config_wx.xml

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeWindowContentChanged|typeNotificationStateChanged|typeWindowStateChanged"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagRequestFilterKeyEvents"
    android:canRetrieveWindowContent="true"
    android:canRequestFilterKeyEvents="true"
    android:description="@string/app_name"
    android:notificationTimeout="100"
    android:packageNames="com.tencent.mm" />

ScreenListener — 屏幕状态监听

package com.example.qxb_810.qianghongbaodemo.listener;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.PowerManager;

public class ScreenListener {

    private Context mContext;
    private ScreenBroadcastReceiver mScreenReceiver;
    private ScreenStateListener mScreenStateListener;

    public ScreenListener(Context context) {
        mContext = context;
        mScreenReceiver = new ScreenBroadcastReceiver();
    }

    /**
     * screen状态广播接收者
     */
    private class ScreenBroadcastReceiver extends BroadcastReceiver {
        private String action = null;

        @Override
        public void onReceive(Context context, Intent intent) {
            action = intent.getAction();
            if (Intent.ACTION_SCREEN_ON.equals(action)) { // 开屏
                mScreenStateListener.onScreenOn();
            } else if (Intent.ACTION_SCREEN_OFF.equals(action)) { // 锁屏
                mScreenStateListener.onScreenOff();
            } else if (Intent.ACTION_USER_PRESENT.equals(action)) { // 解锁
                mScreenStateListener.onUserPresent();
            }
        }
    }
    /**
     * 开始监听screen状态
     *
     * @param listener
     */
    public void begin(ScreenStateListener listener) {
        mScreenStateListener = listener;
        registerListener();
        getScreenState();
    }

    /**
     * 获取screen状态
     */
    private void getScreenState() {
        PowerManager manager = (PowerManager) mContext
                .getSystemService(Context.POWER_SERVICE);
        if (manager.isScreenOn()) {
            if (mScreenStateListener != null) {
                mScreenStateListener.onScreenOn();
            }
        } else {
            if (mScreenStateListener != null) {
                mScreenStateListener.onScreenOff();
            }
        }
    }

    /**
     * 停止screen状态监听
     */
    public void unregisterListener() {
        mContext.unregisterReceiver(mScreenReceiver);
    }

    /**
     * 启动screen状态广播接收器
     */
    private void registerListener() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        filter.addAction(Intent.ACTION_USER_PRESENT);
        mContext.registerReceiver(mScreenReceiver, filter);
    }

    public interface ScreenStateListener {// 返回给调用者屏幕状态信息
        public void onScreenOn();

        public void onScreenOff();

        public void onUserPresent();
    }
}


EventTypes — 一些状态辨识或者类型

package com.example.qxb_810.qianghongbaodemo.common;

public final class EventTypes {
    //所有事件
    public static final int TYPE_ALLMASK = -1;
    //通知栏
    public static final int TYPE_NOTIFICATION_STATE_CHANGED = 64;
    //点击事件
    public static final int TYPE_VIEW_CLICKED = 1;
    //控件获取焦点
    public static final int TYPE_VIEW_FOCUSED = 8;
    //长按事件
    public static final int TYPE_VIEW_LONG_CLICKED = 2;
    //页面变动
    public static final int TYPE_VIEW_SCROLLED = 4096;
    //控件选中
    public static final int TYPE_VIEW_SELECTED = 4;
    //输入框文本改变
    public static final int TYPE_VIEW_TEXT_CHANGED = 16;
    //输入框文本selection改变
    public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192;
    //窗口内容改变
    public static final int TYPE_WINDOW_CONTENT_CHANGED = 2048;
    //窗口状态改变
    public static final int TYPE_WINDOW_STATE_CHANGED = 32;

    //QQ的应用包名
    public static final String QQ_PACKAGE_NAME = "com.tencent.mobileqq";
    //QQ聊天页面
    public static final String QQ_IM_CHAT_ACTIVITY = "com.tencent.mobileqq.activity.SplashActivity";
    //点击拆开
    public static final String QQ_CLICK_TAKE_APART = "恭喜发财";

    //口令红包
    public static final String QQ_CLICK_PASSWORD_DIALOG = "口令红包";

    //聊天页面,输入框ID
    public static final String QQ_CHAT_MESSAGE_INPUT = "com.tencent.mobileqq:id/input";

    //聊天页面,发送按钮
    public static final String QQ_CHAT_MESSAGE_SEND = "com.tencent.mobileqq:id/fun_btn";

}

MainActivity.java

package com.example.qxb_810.qianghongbaodemo;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        requestPermissions();
        //打开系统设置中辅助功能
        Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);
        startActivity(intent);
        Toast.makeText(MainActivity.this, "找到微信/QQ自动抢红包服务,开启即可", Toast.LENGTH_LONG).show();
    }

    /**
     * 动态申请权限  ----  API23后需要动态申请权限
     */
    private void requestPermissions() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            // 读写存储权限 和联网权限
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WAKE_LOCK}, 1);
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.BIND_ACCESSIBILITY_SERVICE}, 1);
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 1);
        }
    }
}

清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.qxb_810.qianghongbaodemo">
    
    <application
        android:allowBackup="true"
        android:icon="@mipmap/app_icon"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/app_icon"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:enabled="true"
            android:exported="true"
            android:label="QQ自动抢红包服务"
            android:name=".service.QQAccessibilityService"
            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/envelope_service_config_qq"/>
        </service>
        <service
            android:enabled="true"
            android:exported="true"
            android:label="WX自动抢红包服务"
            android:name=".service.WXAccessibilityService"
            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/envelope_service_config_wx"/>
        </service>
    </application>
    <uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
</manifest>

猜你喜欢

转载自blog.csdn.net/qq_36882793/article/details/85050976