【安卓学习之微信抢红包】 微信抢红包 3 - 辅助服务(AccessibilityService)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ljb568838953/article/details/82383330

█ 【安卓学习之微信抢红包】 微信抢红包 3 - 辅助服务(AccessibilityService)

█ 相关文章:

 ● 【安卓学习之微信抢红包】 微信抢红包 1 - 知识点归纳
 ● 【安卓学习之微信抢红包】 微信抢红包 2 - 通知服务(NotificationListenerService)
 ● 【安卓学习之微信抢红包】 微信抢红包 3 - 辅助服务(AccessibilityService)
 ● 【安卓学习之微信抢红包】 微信抢红包 4 - APP自动更新(补充)
 ● 【安卓学习之微信抢红包】 微信抢红包 5 - 工具Android Monitor

█ 读前说明:

 ● 本文通过学习别人写demo,学习相关知识,如果涉及侵权请告知
 ● 本文只简单罗列相关的代码实现过程
 ● 涉及到的逻辑以及说明也只是简单介绍,主要当做笔记,了解过程而已

█ AccessibilityService:

 ● 作用:可以监听事件(如页面切换,页面滚动,监听通知等),并获取当前界面的AccessibilityNodeInfo节点。
 ● 条件:开启APP的【辅助服务/无障碍服务】
 ● 使用:
 - 在【AndroidManifest.xml】声明此服务类
 - 新建一个继承AccessibilityService的服务类

█ 辅助服务界面的跳转:

 ● 打开【辅助服务】(即【无障碍服务】)的设置
 - 找到[无障碍],然后开启[微信抢红包服务]即可

Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivity(intent);

 ● 【无障碍服务】界面中有该选项,需要在【AndroidManifest.xml】文件中绑定对应的服务
- 微信抢红包服务-android.permission.BIND_ACCESSIBILITY_SERVICE

<service
    android:name="service.QiangHongBaoService"
    android:enabled="true"
    android:exported="true"
    android:label="微信抢红包服务"
    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/qianghongbao_packet_service" />
</service>

这里写图片描述
 
这里写图片描述

这里写图片描述

 ● 总结:
  AndroidManifest.xml中声明此服务类, 并必须声明 BIND_ ACCESSIBILITY _SERVICE 许可和意图过滤器android. accessibilityservice .AccessibilityService,还有我们在系统设置中通知使用权列表中看到的label标签【微信抢红包服务】
 

█ 辅助服务代码的实现:

// 抢红包外挂服务
public class QiangHongBaoService extends AccessibilityService {

    @Override
    public void onCreate() {
        super.onCreate();
        //初始化辅助插件工作
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //发送广播,已经断开辅助服务
    }
    // 中断AccessibilityService返给的响应时会调用
    @Override
    public void onInterrupt() {
        //中断抢红包服务
    }
    // 系统会成功连接上服务时调用
    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
        //发送广播,已连接抢红包服务
    }
    // 可以接收系统发送来的经过过滤(在配置工作时设置)的AccessibilityEvent
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        //窗口变化事件
        //获取当前界面通知中应用的包名,也就是微信红包的通知
        String pkn = String.valueOf(event.getPackageName());
        //判断包名是否相同
        if(pkn.equals("com.tencent.mm")) {
            //获取用户界面中发生事件的类型
            final int eventType = event.getEventType();
            //通知栏事件
            if (eventType == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {
                //获取微信包中的数据
                Parcelable data = event.getParcelableData();
                //判断数据是否为空
                if (data == null || !(data instanceof Notification)) {
                    return;
                }
                //获取微信红包通知中的文字信息
                List<CharSequence> texts = event.getText();
                //如果信息不为空
                if (!texts.isEmpty()) {
                    String text = String.valueOf(texts.get(0));
                    //设置通知事件
                    if (ticker.contains("[微信红包]")) { //红包消息
                        openHongBaoNotification(nf); //打开红包通知
                    }
                }
            }// 当Window发生变化时发送此事件
            else if (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
                openHongBao(event);     //打开红包方法
            }
        }
    }
    // 接收通知栏事件,该方法可以直接在【通知服务】中调用
    public static void notificationEvent(String ticker, Notification nf) {
        if (ticker.contains("[微信红包]")) { //红包消息
            openHongBaoNotification(nf);     //打开红包通知
        }
    }
}

█ 拆红包的实现:

 ● 【通知服务】接收到消息,调用notificationEvent(String ticker, Notification nf)
 ● 手机不锁屏状态,将微信的通知栏消息打开

private void openHongBaoNotification(Notification notification) {
    PendingIntent pendingIntent = notification.contentIntent;
    boolean lock = NotificationUtil.isLockScreen(getContext());
    //是否为锁屏或黑屏状态
    if (!lock) {
        pendingIntent.send();// 会启动包装的Intent(如启动service,activity)
    }
}

 ● 触发QiangHongBaoService 中的onAccessibilityEvent(AccessibilityEvent event)→openHongBao(event)打开红包

private void openHongBao(AccessibilityEvent event) {
    if ("com.tencent.mm.plugin.luckymoney.ui.En_fba4b94f".equals(event.getClassName())) {
        handleLuckyMoneyReceive(); //点中了红包,下一步就是去拆红包
    } else if ("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI".equals(event.getClassName())) {
        //关闭拆完红包对话框,防止无法进入微信
        service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
        //拆完红包后返回主界面,以便收到下一次的红包通知
        service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME);
    } else if ("com.tencent.mm.ui.LauncherUI".equals(event.getClassName())) {
        handleChatListHongBao();//在聊天界面,去领取红包
    }
}

 ● 点击聊天里的红包后,显示的界面

private void handleLuckyMoneyReceive() {
    //获取当前窗口的信息
    AccessibilityNodeInfo nodeInfo = getService().getRootInActiveWindow();
    AccessibilityNodeInfo targetNode = null;
    //获取微信打开红包后的事件
    int wechatVersion = getWechatVersion(); //获取微信版本
       if (wechatVersion < 700) {   //当前微信版本小于7.0,使用文字匹配
        targetNode = nodeInfo.findAccessibilityNodeInfosByText("拆红包").get(0);
    } else {//设置拆红包按钮id
        String buttonId = "com.tencent.mm:id/b43";
        if (wechatVersion == 700) {
            buttonId = "com.tencent.mm:id/b2c";
        }
        if (buttonId != null) {//通过id查找界面信息与按钮信息
            targetNode = nodeInfo.findAccessibilityNodeInfosByViewId(buttonId).get(0);
        }
        if (targetNode == null) { //通过组件查找
            for (int i = 0; i < nodeInfo.getChildCount(); i++) {
                AccessibilityNodeInfo node = nodeInfo.getChild(i);
                if("android.widget.Button".equals(node.getClassName())) {
                     targetNode = node;
                     break;
                }
            }
        }
    }
    //如果拆红包对话框存在 就单击拆开红包
    if (targetNode != null) {
        if(targetNode.isClickable()) {
            targetNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
        } else {
            performClick(targetNode.getParent());
        }
    }
}

 ● 触发QiangHongBaoService 中的onAccessibilityEvent(AccessibilityEvent event)→openHongBao(event)打开红包→关闭拆完红包对话框,防止无法进入微信

 

█ 相关资料:

 ● 1.2015-10-04 Android中微信抢红包插件原理解析和开发实现 - 尼古拉斯_赵四 - CSDN博客
  那么辅助功能就是干这些事,他的功能其实就是可以概括两句话:第一、寻找到我们想要的View节点;第二、然后模拟点击,实现特定功能。
  我们知道Android中的View体系是一个树形结构,那么每一个View就是一个节点。所以我们可以查找到指定的节点,那么我们该如何查找到我们想要的节点呢?这里我们先看一下辅助功能(AccessibilityService)的用法
 ● 2.2016-02-14 Android辅助功能AccessibilityService与抢红包辅助
  抢红包的原理都差不多,一般是用Android的辅助功能(AccessibilityService类)先监听通知栏事件或窗口变化事件来查找红包关键字然后去模拟点击或打开红包。锁屏黑屏状态自动解锁亮屏,在聊天界面收到红包不会自动打开,因为通知栏没有消息提示从而监听不了,此时只需手动点一下即可。
 ● 3.2016-10-24 (AccessibilityService) Android 辅助功能笔记 - 芥末末的沫 - 简书
 - TYPE_NOTIFICATION_STATE_CHANGED,基本窗口view的变化都可以使用这个type来监听
  represents the event of change in the content of a window. This change can be adding/removing view, changing a view size, etc.
 - TYPE_WINDOW_STATE_CHANGED,打开popupwindow,菜单,对话框时候会触发
  Represents the event of opening a Pop,Menu,Dialog etc.
 - TYPE_WINDOW_CONTENT_CHANGED,更加精确的代表了基于当前event.source中的子view的内容变化
  Represents the event of changing the content of a window and more specifically the sub-tree rooted at the event’s source.
 - TYPE_WINDOWS_CHANGED,窗口的变化
  Represents the event change in the windows shown on the screen.
 ● 4.2017-04-17【总结】Android辅助功能(一)-AccessibilityEvent的分发 | 变猴旅程 | 从人变猴的历程

转载请注明出处:

https://blog.csdn.net/ljb568838953/article/details/82383330

猜你喜欢

转载自blog.csdn.net/ljb568838953/article/details/82383330