博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
微信自动抢红包android实现
阅读量:6983 次
发布时间:2019-06-27

本文共 6812 字,大约阅读时间需要 22 分钟。

 

AccessibilityService-微信自动抢红包

在领导发红包的时候,看到有些同事在1s、2s抢到红包,为什么他们能够这么快?一定是“开挂”的想法立马浮现出来。

做一个程序猿,为什么不自己写一个呢?

借助Android的辅助功能的AccessibilityService服务就能够做到。

 

  1.  检测当前界面是否有红包(未拆开的红包)
  2. 让手机自动点击发现的红包(未拆开的红包)
  3. 检测拆红包弹出窗口上那个“开”的按钮,并让手机自动点击
  4. 进入红包详情界面,检测到返回按钮,自动点击返回到聊天界面,继续抢红包
一、创建Android Project后,先来编辑AccessibilityService的配置accessible_service_config.xml
  1.  
    <?xml version="1.0" encoding="utf-8"?>
  2.  
    <accessibility-service
  3.  
    xmlns:android="http://schemas.android.com/apk/res/android"
  4.  
    android:description="@string/app_name"
  5.  
    android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged"
  6.  
    android:accessibilityFeedbackType="feedbackGeneric"
  7.  
    android:accessibilityFlags="flagDefault"
  8.  
    android:canRetrieveWindowContent="true"
  9.  
    android:notificationTimeout="10"
  10.  
    android:packageNames="com.tencent.mm"
  11.  
    />
android:accessibilityEventTypes 辅助服务关注的事件类型
当前配置:typeWindowStateChanged|typeWindowContentChanged(对应等下需要使用到的事件)
android:accessibilityFeedbackType 事件的反馈给用户的方式
当前配置:feedbackGeneric(通用)
android:accessibilityFlags 辅助服务额外的flag信息
当前配置:flagDefault(默认)
android:canRetrieveWindowContent 是否可以获取窗口内容
当前配置:true
android:notificationTimeout 两个同样类型的辅助事件发给辅助服务的最小时间间隔
当前配置:10
android:packageNames 辅助服务监听的应用包名,可监听多个应用包名,使用逗号隔开。
当前配置:com.tencent.mm(监听微信发出的事件)
二、在AndroidManifest.xml中注册AccessibilityService服务
  1.  
    <service
  2.  
    android:name=".LooterService"
  3.  
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
  4.  
    <intent-filter>
  5.  
    <action android:name="android.accessibilityservice.AccessibilityService" />
  6.  
    </intent-filter>
  7.  
    <meta-data
  8.  
    android:name="android.accessibilityservice"
  9.  
    android:resource="@xml/accessible_service_config" />
  10.  
    </service>
  1. AccessibilityService需要权限android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
  2. 添加intent-filter下的action android:name="android.accessibilityservice.AccessibilityService"
三、创建继承AccessibilityService的服务类LooterService(检测的id基于微信6.6.1版本)
在accessible_service_config.xml配置了android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged",所以这里监听
窗口界面的内容是否改变当发生变化时(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED),就有进入到下面的if中:
//如果当前的事件类型是窗口内容出现了变化,那么判断是否有红包视图出现    if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED){        List
hongbaoList = mRootNodeInfo.findAccessibilityNodeInfosByText("微信红包"); List
weikaiList = mRootNodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/aeb"); Log.e("looter","发现红包检测数量 : " + hongbaoList.size()); for (int i = 0; i < weikaiList.size(); i++) { if (weikaiList.get(i).getText().equals("领取红包")){ AccessibilityNodeInfo curNodeInfo = weikaiList.get(i); curNodeInfo.getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK); } } }
通过findAccessibilityNodeInfosByText("微信红包")获取红包数量list;
通过findAccessibilityNodeInfosByViewId("com.tencent.mm:id/aeb"),根据特定id获取到红包item节点list。(下面再说下怎么获取到对应微信版本的id)
在for循环里,通过条件 if (weikaiList.get(i).getText().equals("领取红包"))匹配未拆开的红包item节点,
getParent()拿到父节点,父节点.performAction(AccessibilityNodeInfo.ACTION_CLICK)进行模拟点击。
模拟点击后,弹出红包窗口,这时候监听到窗口的状态发生变化(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED)进入下面的if中:
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED){    List
clickedWindowList = mRootNodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/c2i"); if (clickedWindowList.size() > 0){ AccessibilityNodeInfo curNodeInfo1 = clickedWindowList.get(0); curNodeInfo1.performAction(AccessibilityNodeInfo.ACTION_CLICK); }}
通过findAccessibilityNodeInfosByViewId("com.tencent.mm:id/c2i"),根据特定id获取到“開”控件的节点list。
这里就不用去getParent()拿父节点了,直接进行模拟点击,把红包拆开。
进入到红包详情界面,窗口状态发生变化,上下的if中的代码都会执行到,由于红包详情界面没有com.tencent.mm:id/c2i这个id,所以没有进行模拟点击(拆红包)。
检测到com.tencent.mm:id/ho这个的item节点,模拟点击,返回到聊天界面,继续检测是否未拆开的红包。
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED){    List
backlist = mRootNodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/ho"); if (backlist.size() > 0){ AccessibilityNodeInfo curNodeInfo1 = backlist.get(0); curNodeInfo1.performAction(AccessibilityNodeInfo.ACTION_CLICK); }}
再说下怎么获取到对应微信版本的控件id
使用Android Studio内部的工具Android Device Monitor
点击Dump View Hierarchy for UI Automator这个按钮
这个dump界面截图上点击领取红包,在右侧resource-id一栏中出现这个控件的id。
后续的控件id,依样画葫芦就能获取到对应控件id。
在最后贴一下LooterService这个类的完整代码:
public class LooterService extends AccessibilityService {    //该对象代表了整个窗口视图的快照    private AccessibilityNodeInfo mRootNodeInfo = null;    @Override    public void onAccessibilityEvent(AccessibilityEvent event) {        mRootNodeInfo = event.getSource();        if (mRootNodeInfo == null){            return;        }        //如果当前的事件类型是窗口内容出现了变化,那么判断是否有红包视图出现        try {            if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED){                List
hongbaoList = mRootNodeInfo.findAccessibilityNodeInfosByText("微信红包"); List
weikaiList = mRootNodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/aeb"); Log.e("looter","发现红包检测数量 : " + hongbaoList.size()); for (int i = 0; i < weikaiList.size(); i++) { Log.e("looter"," --- weikaiList.get(i).getText() --- " + weikaiList.get(i).getText() ); if (weikaiList.get(i).getText().equals("领取红包")){ AccessibilityNodeInfo curNodeInfo = weikaiList.get(i); curNodeInfo.getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK); } } } if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED){ List
clickedWindowList = mRootNodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/c2i"); if (clickedWindowList.size() > 0){ AccessibilityNodeInfo curNodeInfo1 = clickedWindowList.get(0); curNodeInfo1.performAction(AccessibilityNodeInfo.ACTION_CLICK); } } if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED){ List
backlist = mRootNodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/ho"); if (backlist.size() > 0){ AccessibilityNodeInfo curNodeInfo1 = backlist.get(0); curNodeInfo1.performAction(AccessibilityNodeInfo.ACTION_CLICK); } } } catch (Exception e1) { e1.printStackTrace(); } } @Override public void onInterrupt() { }}
这是这个项目的导出apk包,之前上传的资源。下载分数感觉高,后面重新上传了一个,被拒了。
http://download.csdn.net/download/u014506842/10194630
你可能感兴趣的文章
go1
查看>>
使用 Palette 让你的 UI 色彩与内容更贴合
查看>>
关于ASP.NET"未能映射路径"问题
查看>>
详谈如何定制自己的博客园皮肤
查看>>
iBATIS配置文件的特殊使用方法
查看>>
Python正则表达式指南
查看>>
T-SQL 根据年月日创建DateTime
查看>>
【CSS进阶】CSS 颜色体系详解
查看>>
论:CMMI项目策划方法(PP)
查看>>
高可用高性能分布式文件系统FastDFS实践Java程序
查看>>
【Coursera课程笔记】Web智能和大数据Week3_MapReduce
查看>>
从头写个http client(java)
查看>>
Windows Phone笔记索引(总)
查看>>
1分钟破解3dState '学习版'得一些版权信息。
查看>>
我和linux
查看>>
动态调用webservice
查看>>
Java刷题知识点之方法覆盖(方法重写)和方法重载的区别
查看>>
爆牙齿的世界杯日记(小组首轮)
查看>>
ITTC数据挖掘平台介绍(四) 框架改进和新功能
查看>>
JDK5.0新特性系列---11.4线程 Condition
查看>>