Android微信抢红包插件原理和实现 适配微信6.6.1版本

一、前言

年关将至,小伙伴们又聊起了春节长假的旅行安排和各自家乡的年味习俗,不一而足。其中在各个微信群聊中抢红包也是为大家所津津乐道的。有时,可能因为手动去抢红包速度慢了,产生分分钟与一个亿差肩而过的遗憾。而这个时候,有小伙伴建议可以写一个微信自动抢红包的插件,这引起了我的兴趣,也就有了今天这篇文章。

依稀记得,微信红包插件在几年前就有了。本人曾经在CSDN上看到四哥写的微信红包插件的文章介绍,大致了解其中的原理。实际上就是通过AccessibilityService来监听出现新的红包后页面内容的变化和模拟点击,实现拆开红包。

二、原理解析

关于AccessibilityService

官网是这样介绍的

Accessibility services should only be used to assist users with disabilities in using Android devices and apps. They run in the backgro und and receive callbacks by the system when AccessibilityEvents are fired. Such events denote some state transition in the user interface, for example, the focus has changed, a button has been clicked, etc.

上面大概的意思就是AccessibilityService是一个辅助服务,可用来帮助残障人士使用Android设备,对页面的内容变化做出相应的处理等。

AccessibilityService的内容描述

官网上对于AccessibilityService的内容介绍和API描述

AccessibilityService的示例代码

官网上关于AccessibilityService的示例代码

三、开发思路

  • 通过注册AccessibilityService来监听通知栏和页面内容变化事件
  • 通过系统提供的findAccessibilityNodeInfosByTextfindAccessibilityNodeInfosByViewId来获取页面具体的控件对象
  • 通过performAction(AccessibilityNodeInfo.ACTION_CLICK)方法来模拟点击事件

注意:

微信默认当有新的消息(包括红包)如果不在对应的聊天页面,那么新的消息将通过通知栏弹出,所以当我们在微信的消息列表页面或者对应的聊天页面时 可以直接通过当前页面内容的变化来判断是否出现新的红包或者改红包是否已经领取过;

新版微信红包页面无法直接通过findAccessibilityNodeInfosByText来获取拆开红包的按钮,所以我们可以通过遍历页面内容的节点树来获取“拆”这个控件(具体请参考代码实现),模拟触发点击事件,来领取红包;

关于手机锁屏问题,当触发微信红包消息事件时,我们可以通过添加解开屏幕来跳转;部分机型和添加密码的手机可以通过发送提醒声来告知用户出现新的红包啦!!!

四、逻辑实现

集成AccessibilityService类

1、 新建一个继承自AccessibilityService的类,然后在AndroidManifest文件中进行注册,如下:

        <service
            android:name="com.mm.plugin.LMPAccessibilityService"android:enabled="true"android:exported="true"android:label="@string/service_name"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/plugin_service_config"/></service>

注意,在AndroidManifest文件声明配置文件是在4.0以后的写法,之前的SDK需要直接在代码中配置。

还需要声明一个权限:

android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"

2、 添加该服务的配置文件,位于res/xml文件夹下:

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

android:accessibilityEventTypes=”typeNotificationStateChanged|typeWindowStateChanged|typeWindowContentChanged|typeWindowsChanged”

服务接收的响应事件类型;

android:accessibilityFeedbackType=”feedbackGeneric”

响应的反馈方式;

android:description=”@string/accessibility_description”

在手机设置中开启服务的描述内容;

android:notificationTimeout=”100”

响应时间;

android:packageNames=”com.tencent.mm”

服务接收指定的应用时间,这里我们默认只接收微信

3、在LMPAccessibilityService类中部分逻辑实现

 @Overridepublic void onAccessibilityEvent(AccessibilityEvent event) {//接收事件,如触发了通知栏变化、界面变化等  }@Overrideprotected boolean onKeyEvent(KeyEvent event) {//接收按键事件return super.onKeyEvent(event);}@Overridepublic void onInterrupt() {//服务中断,如授权关闭或者将服务杀死}@Overrideprotected void onServiceConnected() {super.onServiceConnected();//连接服务后,一般是在授权成功后会接收到}

4、关于界面内容变化和抢红包核心业务逻辑

在辅助服务中AccessibilityEvent事件中的处理:

        //通知栏事件if (eventType == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {Parcelable data = event.getParcelableData();if (data == null || !(data instanceof Notification)) {return;}if (LMPAccessibilityService.isNotificationServiceRunning() && getConfig().isEnableNotificationService()) { //开启快速模式,不处理return;}List<CharSequence> texts = event.getText();if (!texts.isEmpty()) {String text = String.valueOf(texts.get(0));notificationEvent(text, (Notification) data);}} else if (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {// 这里同一个应用内 如果页面内容没有变化的话是没有执行的Log.e(TAG, "TYPE_WINDOW_STATE_CHANGED");onWindowStateChanged(event);} else if (eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {// 这里只要页面内容变化 就会执行 例如不同应用之间的跳转Log.e(TAG, "TYPE_WINDOW_CONTENT_CHANGED");if (mCurrentWindow != WINDOW_LAUNCHER) { //不在聊天界面或聊天列表,不处理return;}handleChatListHongBao();}

在通知栏中过滤微信红包消息:

    /*** 通知栏事件*/private void notificationEvent(String ticker, Notification nf) {String text = ticker;int index = text.indexOf(":");if (index != -1) {text = text.substring(index + 1);}text = text.trim();if (text.contains(HONGBAO_TEXT_KEY)) { //红包消息handleNewHongBaoNotification(nf);}}

对通知栏和页面变化的逻辑处理:

private void onWindowStateChanged(AccessibilityEvent event) {Log.d(TAG, event.getClassName() + "");if (wxHongbaoPageName.equals(event.getClassName())) {mCurrentWindow = WINDOW_LUCKYMONEY_RECEIVEUI;//点中了红包,下一步就是去拆红包openHongbao();} else if (wxHongbaoDetailsPageName.equals(event.getClassName())) {mCurrentWindow = WINDOW_LUCKYMONEY_DETAIL;if (curHongbaoNotificationList.size() == 0) {// 设置当前是否需要领取红包状态为否 后续重新接收新的领取红包事件isReceivingHongbao = false;//拆完红包后看详细的纪录界面 在这里可以返回到当前的上一个页面if (getConfig().getWechatAfterGetHongBaoEvent() == Config.WX_AFTER_GET_GOHOME) {//返回主界面,以便收到下一次的红包通知AccessibilityHelper.performHome(getService());} else {// 返回到上个页面AccessibilityHelper.performBack(getService());}} else {for (int i = 0; i < curHongbaoNotificationList.size(); i++) {openHongbaoPage4Notification(curHongbaoNotificationList.get(i));}}} else if (wxChatPageName.equals(event.getClassName())) {mCurrentWindow = WINDOW_LAUNCHER;//在聊天界面,去点中红包handleChatListHongBao();} else {mCurrentWindow = WINDOW_OTHER;}}

上文提到的,新版微信已经不支持通过获取文本内容来定位到拆开按钮,所以我们直接通过遍历节点树来获取具体的控件模拟点击”开“按钮:

     /*** 点击聊天里的红包后,显示的界面*/@TargetApi(Build.VERSION_CODES.JELLY_BEAN)private void openHongbao() {AccessibilityNodeInfo nodeInfo = getService().getRootInActiveWindow();if (nodeInfo == null) {Log.w(TAG, "rootWindow为空");return;}AccessibilityNodeInfo targetNode = null;int event = getConfig().getWechatAfterOpenHongBaoEvent();int wechatVersion = getWechatVersion();if (event == Config.WX_AFTER_OPEN_HONGBAO) { //拆红包// 通过遍历当前页面的节点树,获取到红包页面的“开”按钮if (wechatVersion == wx523VersionCode || wechatVersion == wx661VersionCode) {targetNode = AccessibilityHelper.findNodeInfosByClassName(nodeInfo, BUTTON_CLASS_NAME);} else {Log.d(TAG, "抱歉,暂时不支持该微信版本!");Toast.makeText(getContext(), "抱歉,暂时不支持该微信版本!", Toast.LENGTH_SHORT).show();}} else if (event == Config.WX_AFTER_OPEN_NONE) {return;}if (targetNode != null) {final AccessibilityNodeInfo n = targetNode;long sDelayTime = getConfig().getWechatOpenDelayTime();if (sDelayTime != 0) {getHandler().postDelayed(new Runnable() {@Overridepublic void run() {// 模拟拆开红包AccessibilityHelper.performClick(n);}}, sDelayTime);} else {// 模拟拆开红包AccessibilityHelper.performClick(n);}}}

至此,我们就完成了微信抢红包插件开发实现,以上代码适配了微信6.5.23和6.6.1版本。
另外我们还可以添加延时抢红包功能来防止封号和过滤群聊等功能~~。
亲测在小米、vivo等机型上可以完美运行,实现自动抢红包功能。

最后附上相关截图:

关于控件ID的获取,我们可以借助Android的DDMS工具里的Dump View Hierarchy For UI Automator 去分析微信UI结构。

这个ID就是我们上文提到的findAccessibilityNodeInfosByViewId方法中的参数。

最终效果:

这里因为测试用的微信号没有实名认证,所以打开红包后默认会进入微信的实名认证页面~~~

源码地址:
https://github.com/chenzhi-ls/WeChatLuckyMoneyPlugin


五、延展总结

关于AccessibilityService这个类,我们来可以用来实现比如免root自动安装、虚拟按键操作等。

最后声明:本项目中用到的内容仅用作学习研究使用,对技术的可行性做相关探索,如果利用本文案例或者技术进行其他非法操作,带来的一切法律责任与本人无关!!!

Android微信抢红包插件原理和实现 适配微信6.6.1版本相关推荐

  1. android黑科技系列——微信抢红包插件原理解析和开发实现

    一.前言 自从几年前微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导 ...

  2. 偶然一次机会对xposed插件学习记录(微信自动抢红包原理研究,适配微信8.0)

    为什么称这次机会纯属偶然? 微信的一次大版本更新,朋友圈狂刷表情包新增动画特效的情况下,本着学习年轻人的喜好,融入年轻人生活圈的宗旨(其实我也才刚毕业),我也将微信更新到8.0,在我体验微信8.0带来 ...

  3. Android 微信抢红包插件

    转载开源工程:https://github.com/geeeeeeeeek/WeChatLuckyMoney 这个Android插件可以帮助你在微信群聊抢红包时战无不胜.当检测到红包时,插件会自动点击 ...

  4. Android微信抢红包插件源码解析

    这个Android插件可以帮助你在微信群聊抢红包时战无不胜.当检测到红包时,插件会自动点击屏幕,人工点击的速度无法比拟. 你正在查看的是dev分支,这个分支包含大量实验性的修改,不再更新.如果你希望有 ...

  5. android群聊红包原理,Android之微信抢红包实现原理分析

    微信抢红包主要用到AccessibilityService,该服务需要用户手动到辅助功能里面授权,下面直接粘贴源码,先看Activity,主要是跳转到辅助功能界面,让用户开启辅助功能的服务: publ ...

  6. js微信抢红包脚本代码_javascript实现仿微信抢红包

    仿微信抢红包 javascript实现仿微信抢红包 红包个数:个

  7. Android 辅助功能(无障碍)自定义开发类似微信抢红包插件

    背景: 通常在无人值守的Android智能设备或不能触摸交互的设备中,当系统运行异常时, 系统有可能会弹出应用程序无响应(ANR)对话框,提示是否终止当前进程或等待,或应用程序异常退出时系统偶尔也会有 ...

  8. 微信抢红包插件 android 8.0,重磅!微信8.0专属红包全量上线!

    "本文由我原创,来源 

  9. python微信抢红包代码_用Python实现微信自动化抢红包,再也不用担心抢不到红包了...

    1. 概述 刚刚收到了两个消息,一个好消息,一个坏消息. 先说好消息,好消息就是微信群里有人要发红包,开心~ 不过转念一想,前几次的红包一个都没抢到,这次???不由自主的叹了一口气 ... 过了一会, ...

最新文章

  1. ExecutorService 的理解与使用
  2. python把光标定义到指定的位置并删除之前的字符_python 批量修改预定字符串并将修改后的字符串插入文件指定位置...
  3. 必应词典UWP版-开发小结
  4. jmeter 线程组与参数_jmeter接口测试基础篇之初步认识及参数化请求
  5. 深度学习与神经网络关系(BP网络【浅层】与深层网络)
  6. 让自己的user能够看到S4 product master这个tile
  7. Golang系列:打印命令行参数
  8. Java基础学习总结(122)——Java八种基本数据类型的包装类及其装箱拆箱详解
  9. 官宣!DolphinScheduler 毕业成为 Apache 软件基金会顶级项目
  10. java返回语句_Java中return的语句
  11. linux tar命令 打包压缩
  12. 如何获得Windows聚焦壁纸
  13. python + selenium清除Chrome缓存
  14. mysql 查询视图_MySQL查看视图
  15. 解决魅族手机不输出Log日志 或者输出部分日志问题
  16. Ozone Block Chunk文件的layout方式
  17. 0083-Zipkin耗时分析
  18. 最全数据结构的基本概念
  19. MySQL获取指定日期为所在月份的第几周
  20. (附源码)APP垃圾自动分类管理系统 毕业设计160846

热门文章

  1. PMP备考指南之第三章:项目经理的角色
  2. Linux网络:物理层 | 数据通信 | 基带频带 | 信源编码 | 射频 | 调制
  3. 如何搭建一个自己的网站-域名篇(上)
  4. 饥荒云服务器t键,饥荒T键使用说明 | 手游网游页游攻略大全
  5. 用 Python 中的蒙特卡洛模拟预测股票收益
  6. Python 根据弧度和半径求弧长
  7. VISA招商银行全币种国际芯片卡
  8. spiral grid
  9. 项目总结:HR员工系统
  10. 通过添加HOST解决emby/jellyfin/TMM刮不动的问题。