妙用AccessibilityService黑科技实现微信自动加好友拉人进群聊

| TYPE_TOUCH_EXPLORATION_GESTURE_START | 触摸浏览事件开始 |
| TYPE_TOUCH_EXPLORATION_GESTURE_END | 触摸浏览事件完成 |
| TYPE_WINDOW_CONTENT_CHANGED | 窗口的内容发生变化,或子树根布局发生变化 |
| TYPE_VIEW_SCROLLED | View滚动 |
| TYPE_VIEW_TEXT_SELECTION_CHANGED | Edittext文字选中发生改变事件 |
| TYPE_ANNOUNCEMENT | 应用产生一个通知事件 |
| TYPE_VIEW_ACCESSIBILITY_FOCUSED | 获得无障碍焦点事件 |
| TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED | 无障碍焦点事件清除 |
| TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY | 在给定的移动粒度下遍历视图文本的事件 |
| TYPE_GESTURE_DETECTION_START | 开始手势监测 |
| TYPE_GESTURE_DETECTION_END | 结束手势监测 |
| TYPE_TOUCH_INTERACTION_START | 触摸屏幕事件开始 |
| TYPE_TOUCH_INTERACTION_END | 触摸屏幕事件结束 |
| TYPE_WINDOWS_CHANGED | 屏幕上的窗口变化事件,需要API 21+ |
| TYPE_VIEW_CONTEXT_CLICKED | View中的上下文点击事件 |
| TYPE_ASSIST_READING_CONTEXT | 辅助用户读取当前屏幕事件 |

好吧,上面的表其实并没什么大用,我还是习惯直接把event.toString()给打印出来, 然后自行去判断~

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如图就可以拿到event类型,以及产生对应事件的类名,核心是这两个, 除此之外还有Text和ContentDescription等。

比如我那个监听Notification跳转到添加好友页的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这里就是对事件类型做了下判断,然后获取contentIntent,跳转而已。 简单点讲就是:

你在这个方法里,去判断一波事件类型和className, 然后再获取控件,做一些点击,滚动,填充文本等。


2.服务的配置

自定义完这个服务要想让他启用你还得执行下面的操作:

Step 1:在res文件夹下创建xml文件夹,新建一个配置的xml文件(名字自己定)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

<?xml version="1.0" encoding="utf-8"?>

属性简介如下

  • accessibilityEventTypes:设置监听的事件种类,用|隔开,监听所有可以用typeAllMask;
  • accessibilityFeedbackType:服务提供的反馈类型,feedbackGeneric通用反馈;
  • accessibilityFlags:辅助功能附加的标志,flagDefault默认的配置
  • canRetrieveWindowContent:辅助功能服务是否能够取回活动窗口内容的属性
  • notificationTimeout:响应时间
  • packageNames:监听的应用包名,不填,默认监听所有应用的事件
  • settingsActivity:允许用户修改辅助功能的activity类名

Step 2:接着AndroidManifest.xml文件中对该Service进行配置

先是添加一个权限:

android:permission=“android.permission.BIND_ACCESSIBILITY_SERVICE”

接着是Service的配置:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这里是你那个配置文件xml文件的文件名,其他照抄。

Step 3:安装到手机后,需要在手机设置的无障碍处开启服务

一般在设置的辅助功能处能找到:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果Logcat那里能看到打印的LOG,说明服务正常运行,接下来要找控件节点


3.找控件

这里可以用到神器UI Automator来查看布局层次,打开Android Studio, Ctrl + alt + A,输入 monitor

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

依次点击:选中设备 -> Dump View Hierarchy for UI Automator

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

稍等一会,右侧就会出现当前页面的布局层次图,如图随手选中一个邀请的节点:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

右侧可以拿到对应的信息,一般比较常用的是这几个,有一点要注意!!! resource-id不一定是唯一的

获得控件基本都会通过下述这个方法:

getRootInActiveWindow( ):获取当前整个活动窗口的根节点 返回的是一个**AccessibilityNodeInfo**类,代表View的状态信息, 提供了下述几个非常实用的方法:

  • getParent:获取父节点。
  • getChild:获取子节点。
  • performAction:在节点上执行一个动作。
  • findAccessibilityNodeInfosByText:通过字符串查找节点元素。
  • findAccessibilityNodeInfosByViewId:通过视图id查找节点元素。

后面的这两个方法会返回一个AccessibilityNodeInfo列表,一般操作是 遍历,然后筛选特定节点,比如我程序里的,获得底部Tab节点为"通讯录", 然后点击,跳转后遍历,筛选"群聊"的节点,点击。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

另外,UI Automator有时并不可靠(实时问题),我建议写多一个遍历节点 的方法,可以更清楚里面的控件情况:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

拿到控件,接着就到触发事件了。


4.触发事件

通过调用**performAction**()传入一个时间类型即可触发相应时间,比如点击,长按等 事件就多了,自己点开AccessibilityNodeInfo类查看吧,这里介绍下最常用的几个事件:

//点击
performAction(AccessibilityNodeInfo.ACTION_CLICK);

//长按
performAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);

//滚动
performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); //向下滚一下
performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); //向上滚一下

//填充EditText(API版本需要>18可用方法1,API>21两种方法都可以使用)

//方法1:
ClipboardManager clipboard = (ClipboardManager)this.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText(“text”, “填充内容”);
clipboard.setPrimaryClip(clip);
//获得焦点
info.performAction(AccessibilityNodeInfo.ACTION_FOCUS);
粘贴进入内容
info.performAction(AccessibilityNodeInfo.ACTION_PASTE);

//方法2:
Bundle arguments = new Bundle();
arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, “填充内容”);
info.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);

除了控件触发事件外,AccessibilityService提供了一个**performGlobalAction(),用于执行 一些通用的事件**:

GLOBAL_ACTION_BACK 点击返回按钮
GLOBAL_ACTION_HOME 点击home
GLOBAL_ACTION_NOTIFICATIONS 打开通知
GLOBAL_ACTION_RECENTS 打开最近应用
GLOBAL_ACTION_QUICK_SETTINGS 打开快速设置
GLOBAL_ACTION_POWER_DIALOG 打开长按电源键的弹框

另外在实际开发中,直接调用这些全局方法又是并没有生效, 我在调GLOBAL_ACTION_BACK的时候就发现有时不会回退, 个人的解决方案是使用**handler.postDelay()**延时执行:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

除了这样玩以外,我还利用时间差,串行去执行几个任务,比如:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上面的步骤是:

进入群聊聊天信息页后,列表滚动两次,接着依次:

  • 1.延时1s后,找到添加成员按钮并点击;
  • 2.延时2.3s后,把名字填充到EditText里
  • 3.延时3s后,点击确定按钮

就不用过于依赖onAccessibilityEvent方法,除了用handler.postDelay外, 还可以用Thread.sleep(休眠时长),用到的点大概就这么多,其余的自行探究吧。


小结

本节讲解一波如何通过AccessibilityService来实现自动加好友以及拉人进群, 之前是打算用xposed来写的,后面发现没我想像中简单,而且很多用安卓机的都 不会搞机(基),root也不会,后来还是选择了AccessibilityService,简单易用, 当然后面还是会研究一波xposed实现的,敬请期待~ 对了,还有,之前那个网页端的机器人被封原因估计是信息秒回,如果有还用 itchat那个做机器人的,建议回复的时间可以稍微延长些;

关于AccessibilityService更多内容可见


附:关键代码(都可以在:github.com/coder-pig/W… 找到): 代码有Bug的话正常,后续会优化下逻辑,感觉写得有点杂~

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

package com.coderpig.wechathelper;

import android.accessibilityservice.AccessibilityService;
import android.app.Notification;
import android.app.PendingIntent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;

import java.util.List;

/**

  • 描述:微信监控服务类
  • @author CoderPig on 2018/04/04 13:46.
    */

public class HelperService extends AccessibilityService {

private static final String TAG = “HelperService”;
private Handler handler = new Handler();
private String userName = “123”;

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
int eventType = event.getEventType();
CharSequence classNameChr = event.getClassName();
String className = classNameChr.toString();
Log.d(TAG, event.toString());
switch (eventType) {
case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
if (event.getParcelableData() != null && event.getParcelableData() instanceof Notification) {
Notification notification = (Notification) event.getParcelableData();
String content = notification.tickerText.toString();
if (content.contains(“请求添加你为朋友”)) {
PendingIntent pendingIntent = notification.contentIntent;
try {
pendingIntent.send();
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
}
}
break;
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
switch (className) {
case “com.tencent.mm.plugin.subapp.ui.friend.FMessageConversationUI”:
addFriend();
break;
case “com.tencent.mm.plugin.profile.ui.SayHiWithSnsPermissionUI”:
verifyFriend();
break;
case “com.tencent.mm.plugin.profile.ui.ContactInfoUI”:
performBackClick();
break;
case “com.tencent.mm.ui.LauncherUI”:
if (!userName.equals(“123”)) {
openGroup();
}
break;
case “com.tencent.mm.ui.contact.ChatroomContactUI”:
if (!userName.equals(“123”)) {
inviteGroup();
}
break;
case “com.tencent.mm.ui.chatting.ChattingUI”:
if (!userName.equals(“123”)) {
openGroupSetting();
}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

写在最后

今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。

最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

【算法合集】

【延伸Android必备知识点】

里以图片的形式给大家展示一部分。

还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

[外链图片转存中…(img-Gx0rfnQE-1711862082600)]

【算法合集】

[外链图片转存中…(img-5cxM9qLq-1711862082601)]

【延伸Android必备知识点】

[外链图片转存中…(img-htXlf3lK-1711862082601)]

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值