前言

  之前看到了微信抢红包的插件,觉得这个功能实在强大了,这和之前我想实现的模拟点击事件基本相似,可以完美的触发一个view的点击事件,当然静默安装的原理也和抢红包的原理是一样的。

  小米有开源小米的抢红包的demo,之后有童鞋在此之上增加了自己的逻辑,使其完善。现在为了学习,我也加入抢红包的demo大军哈哈,主要在于学习。

原理

  原理主要是通过辅助功能AccessibilityService来完成的,AccessibilityService是Google用来帮助肢体不便的人所开发的一个功能,能够触发相应的用户事件比如点击,滑动等等。

  抢红包的功能也是基于此能力之上,去进行模拟点击事件。当然,AccessibilityService的功能需要得到用户的许可,通过它的功能的介绍,已经可以知道它的强大,其实这个的能力和root相当,甚至更强,毕竟可以模拟一切的用户事件。

  所以,在实现的方法前,需要了解
  1. 如何获取特定能够点击的view的节点
  2. 触发点击事件,进行判断

逻辑

需要注意:保持屏幕常亮,需要把每个群的消息免打扰取消,主要为了能够接收到通知Notification,在一开始请回到Home

  1. 接收到Notification之后,存入List中作为待处理红包.

  2. 逐个处理List中的PendingIntent,开启微信的聊天界面,获取可以点击的红包列表,逐个点击。

  3. 进入红包处理,两种情况,
    一、进入接收红包的界面,获取抢红包的按钮,触发点击。进入红包detail界面,结束。
    二、已经抢过,进入红包detail界面,或者被抢完了,停留在receive界面,结束,回到主界面。

  4. 回到步骤1

工程源码

  1. 首先新建一个PluginService继承AccessibilityService,然后再Manifest.xml中进行注册:
<service
            android:name=".PluginService"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/accessible_service_config" /></service>

  其中的android:resource=…的是对于Service的参数配置,文件的位置在于res下的xml文件下,名字定为accessible_service_config.xml
各个参数的定义:

  android:accessibilityEventTypes:允许接收的事件,这里定义为notification变化事件,窗口切换变化事件,窗口内容变化事件。

  android:accessibilityFeedbackType:设置返回给用户的形式

  android:packageNames:指定响应某个指定应用的事件。需要知道某个应用的包名的时候可以通过DDMS中的hierarchy view进行查看。

  android:notificationTimeout:设置响应的时间

<accessibility-service
    xmlns:android="http://schemas.android.com/apk/res/android"android:description="@string/app_name"android:accessibilityEventTypes="typeNotificationStateChanged|typeWindowContentChanged|typeWindowStateChanged"android:accessibilityFeedbackType="feedbackAllMask"android:packageNames="com.tencent.mm"android:notificationTimeout="0"android:accessibilityFlags=""android:canRetrieveWindowContent="true"/>

2.在PluginService中进行逻辑的处理
在onAccessibilityEvent中进行事件的监听,监听包括三种类型的,一种是通知栏的变化,一种是窗口内容的变化,一种是窗口切换的变化。

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {int eventType = event.getEventType();switch (eventType) {// 监听通知栏消息case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:handlerNotification(event);break;// 监听窗口变化消息case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:handlerWindowStateChange(event);break;// 监听窗口内容的动态变化case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:handlerWindowContentChange(event);break;default:break;}
}

3.我们回到了主界面,有群发了红包,那么进入notification变化的事件中去,在其中判断是否是含有红包的消息,如果是的话则模拟打开notification,这里多做了一个步奏就是将多个notification存储到一个list里面,进行足一的打开。

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public void handlerNotification(AccessibilityEvent event) {if (event == null) return;List<CharSequence> contents = event.getText();if (contents != null && !contents.isEmpty()) {for (CharSequence content : contents) {String text = content.toString();if (!text.contains("[微信红包]")) continue;if (event.getParcelableData() != null &&event.getParcelableData() instanceof Notification) {Notification notification = (Notification) event.getParcelableData();PendingIntent pendingIntent = notification.contentIntent;Log.e("pendingintent", pendingIntent.getCreatorPackage().toString());if (pendingIntent.getCreatorPackage().toString().equals("com.tencent.mm")) {if ((curStatus != Status.ON_CHAT_ROOM || curStatus != Status.ON_LUCKY_MONEY_RECEIVED) &&untreatedLuckyMoneyList.size() == 0) {openNotification(pendingIntent);} else {untreatedLuckyMoneyList.add(0, pendingIntent);}}}}}
}/*** 开启Notification中所指向的微信聊天页面** @param pendingIntent*/
public void openNotification(PendingIntent pendingIntent) {if (pendingIntent == null) return;// 模拟点击了notificationtry {pendingIntent.send();curStatus = Status.ON_CHAT_ROOM;} catch (PendingIntent.CanceledException e) {e.printStackTrace();}
}

4.一下方法通过判定窗口变化的具体的类来判定进入了哪一个界面。从而进行对应的操作。
  a 进入了聊天界面,则进行领取红包的字样遍历,同时进行模拟点击开启。
  b 进入领取红包界面,则遍历得到拆红包字样的节点,同时模拟点击
  c 进入红包详情界面,则模拟返回键退出。

要知道具体的类是什么的时候,可以通过测试输出消息,通过event.getClassName().toString()的输出查看具体的类名。

public void handlerWindowStateChange(AccessibilityEvent event) {if (event == null || event.getSource() == null) return;String className = event.getClassName().toString();// 微信主界面 com.tencent.mm.ui.LauncherUIif (className.equals("com.tencent.mm.ui.LauncherUI")) {curStatus = Status.ON_CHAT_ROOM;if (canOpenNode == null) {canOpenNode = event.getSource().findAccessibilityNodeInfosByText("领取红包");trashOpenNode = new ArrayList<AccessibilityNodeInfo>();}openLuckyMoney();// 红包接收界面 com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI} else if (className.equals("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI")) {curStatus = Status.ON_LUCKY_MONEY_RECEIVED;unpackLuckyMoney(event.getSource());// 红包的detail界面 com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI} else if (className.equals("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI")) {curStatus = Status.ON_LUCKY_MONEY_DETAIL;back();}}

5.进入到微信的聊天界面,这时候会触发窗口变化消息,这时候通过view找到具有领取红包字样的节点,如果有,则进行模拟点击,如果没有回到主界面。这里其中一个步奏也是将多个具有领取红包的节点存储到list中,等待开启。

/*** 在聊天界面中打开红包*/
public void openLuckyMoney() {if (canOpenNode != null && canOpenNode.size() == 0) {backToHome();disposeLuckyMoneyList();canOpenNode = null;trashOpenNode = null;}if (canOpenNode == null) {backToHome();return;}AccessibilityNodeInfo node = canOpenNode.remove(0);trashOpenNode.add(node);if (node.getParent() != null && node.getParent().isClickable()) {node.getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK);}}

6.假如进入到了红包领取界面,则需要先判断是否被领取完了,或者是过期了,如果都不是,则找到拆红包字样的节点进行模拟点击

public void unpackLuckyMoney(AccessibilityNodeInfo nodeInfo) {if (nodeInfo == null) {back();return;}// 打开红包,如果红包已被抢完,遍历节点, 如果匹配“红包详情”、“手慢了”和“过期”,则返回// 继续打开其他红包List<AccessibilityNodeInfo> packedLists = new ArrayList<>();packedLists.addAll(nodeInfo.findAccessibilityNodeInfosByText("红包详情"));packedLists.addAll(nodeInfo.findAccessibilityNodeInfosByText("手慢了"));packedLists.addAll(nodeInfo.findAccessibilityNodeInfosByText("过期"));if (!packedLists.isEmpty()) {back();return;}List<AccessibilityNodeInfo> unPackedLists = nodeInfo.findAccessibilityNodeInfosByText("拆红包");if (unPackedLists.isEmpty()) {back();} else {AccessibilityNodeInfo node = unPackedLists.get(0);node.performAction(AccessibilityNodeInfo.ACTION_CLICK);}}

7.当进入到了红包详情页面时候,则进行返回,返回到聊天界面之后,会继续进行红包列表进行拆红包,知道拆完了所有的红包之后,就会退回到主界面,然后继续拆开notification list中的消息,如果没有消息,则等待。

改进

通过遍历节点去找到能点击的事件是比较浪费效率的,其实通过DDMS中的hierarchy view可以看到每个控件的ID,通过ID可以直接获取该控件,然后模拟点击,就不用进行遍历了。

项目源码,github网址

参考文档网址
参考工程

android微信的抢红包插件相关推荐

  1. Android 微信自动抢红包(源码以及apk下载可以参考末文)

    微信自动抢红包 一.调试环境搭建: 二.具体代码实现可以参考:https://github.com/xiaxiaxa/RedWechat (近期整理并且debug的一个基础版本) 一.调试环境搭建: ...

  2. 微信同步助手android,微信同步助手插件(自媒体分发)

    微信同步助手插件能够快速在各大平台同步推送微信公众号文章,适用于新媒体运营用户,支持多种平台同步推送,包括今日头条.WordPress.知乎.简书等,一键即可同步推送文章,大大减少了复制粘贴排版带来的 ...

  3. android qq红包,Android实现QQ抢红包插件

    又想到快要过年了,到时候还不知道群里要发好多红包,所以我将之前在网上宕的一份微信抢红包的代码修改了一下,实现了QQ抢红包!可以支持抢QQ拼手气红包,普通红包,口令红包,现在再也不怕20年单身手速的人跟 ...

  4. 安卓微信自动抢红包插件实现和优化

     又是兴趣系列 网上有很多自动强红包的例子和代码,笔者也是做了一些优化. 先说说自己的两个个优势 1.可以在聊天界面自动强不依赖于通知栏推送 2.可以在屏幕熄灭的时候的时候点亮屏幕自动抢(目前只测 ...

  5. 安卓微信自动抢红包插件 实现 和优化

    转载请注明作者AndroidMSky和链接http://blog.csdn.net/AndroidMsky/article/details/53490459 又是兴趣系列 网上有很多自动强红包的例子和 ...

  6. c语言写抢QQ红包软件,Android实现QQ抢红包插件

    又想起快要过年了qq协议代挂抢红包脚本,到时候还不知道群里要发很多红包,所以我将之前在网上宕的一份陌陌抢红包的代码更改了一下,实现了QQ抢红包!可以支持抢QQ拼手气红包,普通红包,口令红包,现在再也不 ...

  7. android qq自动发红包,Android实现QQ抢红包插件

    又想到快要过年了,到时候还不知道群里要发好多红包,所以我将之前在网上宕的一份微信抢红包的代码修改了一下,实现了qq抢红包!可以支持抢qq拼手气红包,普通红包,口令红包,现在再也不怕20年单身手速的人跟 ...

  8. android 微信 去广告插件,Android"挂逼"修练之行--微信小程序逆向辅助插件工具开发详解 ......

    一.前言 之前一篇文章已经详细介绍了 微信小程序包的格式 ,在之前文章中也了解到小程序包存放在沙盒目录,但是微信为了让小程序包安全就对文件名做了一个处理,导致我们很难找到对应的小程序对应的包文件,所以 ...

  9. android 微信 去广告插件,Xposed去除微信朋友圈广告

    一.背景:最近发现微信朋友圈的广告有点多,有时前十条就出现2条广告,还是针对性投放的,于是想着怎么去除广告. 本次研究用的是微信谷歌商店版,版本名是7.0.0,版本号是1363,云盘地址,反编译工具是 ...

最新文章

  1. 【NIO】阻塞与非阻塞
  2. Android 2.0中电话本contact的读写操作(增删改查一)
  3. guestbook.php注入,TinyGuestBook 'sign.php'多个SQL注入漏洞
  4. 多媒体制作技术心得体会_多媒体课件制作学习心得体会
  5. rman实验——测试备份压缩
  6. 为docker设置国内镜像【转】
  7. 【NLP】Transformer大家庭简介!
  8. java 反射 Constructor、Method、Field 基本用法
  9. [转]JavaScript优化方案
  10. fmc是fpga直接引出来的吗_家长速看!你还在用“不要和陌生人说话”糊弄孩子的安全教育吗?...
  11. 为什么机器人企业的算法工程师需要ROS开发经验
  12. python处理表格数据教程_python利用Excel读取和存储测试数据完成接口自动化教程...
  13. 边做边学:《 Inter Planetary File System》简介
  14. hadoop远程调试
  15. 如何写好一篇SCI论文
  16. Spark独到见解--Action算子总结
  17. [c++期末刷题]将 1 元钱换成 1 分、2 分、5 分的硬币
  18. 微信小程序整合Vant Weapp 步骤
  19. vue路由跳转总是跳转到首页,路由匹配不上
  20. JSD-2204-Session-Token-JWT-Day12

热门文章

  1. ESP32(MicroPython) 串口控制多路pmw输出
  2. 信息化孤岛探讨及解决思路(一)
  3. 荐书 | 当我们在谈论死亡时,应该说些什么?
  4. 自定义ImageView系列 - 区域截图(下)
  5. ipad iphone开发_如何阻止iPhone或iPad自动连接到Wi-Fi网络
  6. 自定义收缩TextView
  7. HTMLhead/head中标签的含义
  8. Win7听歌时声音忽大忽小
  9. Android实现Excel表格样式
  10. Zoomlt屏幕画图工具