记AccessibilityService使用(转)
转自 :http://www.jianshu.com/p/ba298b8d5a6e
一、AccessibilityService的使用
首先先写一个类去继承AccessibilityService
public class MyAccessibilityService extends AccessibilityService {
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
//主要操作都在这里
}
@Override
public void onInterrupt() { }
...
}
接下来在res/xml文件夹下新建一个xml文件(不要问我xml文件夹哪来的(:зゝ∠)),叫做aaa.xml(名字随意拉~~)。
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged|typeNotificationStateChanged"
android:accessibilityFeedbackType="feedbackAllMask"
android:accessibilityFlags="flagDefault"
android:canRetrieveWindowContent="true"
android:description="@string/intro"
android:notificationTimeout="10"
android:packageNames="com.tencent.mm"/>
接下来解释下各个属性:
- description: 就是给你的这个辅助功能做个简短说明。
- packageNames: 这个servie希望接收到的事件的包名,如果要接收多个,可以在几个包名之间用 , 隔开。
- accessibilityEventTypes :这个就是设置了它能监视的动作,比如状态栏来消息拉,界面发生变化拉等等,可以监视一个或多个(由分隔'|')动作,它有typeViewTextChanged,typeNotificationStateChanged,typeWindowContentChanged,typeAllMask等等,其他的类型可以参考这里。
- accessibilityFeedbackType :提供反馈类型,语音震动等等。也是可以设置必一个或多个(由分隔'|')值,可以设置feedbackSpoken、feedbackAllMask等。
- notificationTimeout:两个相同类型的可访问性事件之间的最小周期。就是监视到一个动作和监视到下一个动作的时间间隔。
- canRetrieveWindowContent:是否要能够检索活动窗口的内容,此设置不能在运行时改变。
- settingsActivity:允许用户修改设置该服务的组件名称。
aaa.xml文件写好以后,就开始配置AndroidManifest.xml文件了
<service
android:name=".MyAccessibilityService"
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/aaa"/>
</service>
记住一定还要加上权限
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />
好了,现在所有的东西都以及准备好了,运行程序,就可以在手机的设置-辅助功能里面找到自己的功能了。
二、抢红包功能
首先先了解下这个servie响应的事件类型,TYPE_NOTIFICATION_STATE_CHANGED是通知栏事件,TYPE_WINDOW_STATE_CHANGED是窗口状态改变,TYPE_WINDOW_CONTENT_CHANGED是窗口内容改变,这3个就是本次最主要的事件类型,通过AccessibilityEvent可以获得这个事件类型,我们需要做判断即可。
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
int eventType = event.getEventType();
switch (eventType) {
case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
//TODO处理通知栏来的事件类型
break;
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
//TODO
case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
//TODO窗口出现变化的时候处理
break;
}
}
接下来先处理通知栏
从上图可以看到它的event type以及本次抢红包的关键字“[微信红包]”,所以在处理通知栏事件的时候先判断该消息的text是否有关键字,如果有,则打开微信界面。
private void getNotificationInfo(AccessibilityEvent event) {
Parcelable parcelable = event.getParcelableData();
if (parcelable instanceof Notification) {
Notification notification = (Notification) parcelable;
try {
notification.contentIntent.send();
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
}
}
打开界面也就意味这窗口发生改变了,所以onAccessibilityEvent又接收到新的事件了。接下来就要在另外两个事件里面做找红包和开红包的操作了。
从上面两个图片可以知道,点击抢红包和点击开的时候它们的event type都是TYPE_WINDOW_STATE_CHANGED,并且在重点关注一下它们的class,所以可以在TYPE_WINDOW_STATE_CHANGED里面做获取event.getClassName();然后再根据这个class判断到底是做抢红包呢还是开红包呢。
case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
rootNodeInfo = getRootInActiveWindow();//相当于获得了这个界面,可以在这上面找控件啊什么的
if (rootNodeInfo == null) return;
if (className.equals(com.tencent.mm.ui.LauncherUI)) {
getLuckyMoney();//找红包,找到红包就打开
} else if (className.equals(com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI)) {
openLuckyMoney();//开红包
backLuckyMoney(eventType);//红包详情,红包抢光了,红包超时了做一个取消的动作
} else if (className.equals(com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI)) {
backLuckyMoney(eventType);
}
break;
找红包就是在rootNodeInfo里面findAccessibilityNodeInfosByText("领取红包"),如果有,则返回这个红包的AccessibilityNodeInfo。对于图片里面的textview:领取红包,为了反正在聊天界面不停的找到这个开过的红包,然后打开红包,关闭,打开,关闭的死循环,在找红包这边需要加一个判断,如果这个红包已经开过一次了,在窗口没有变化的时候将不点击红包。判断的条件就是图片中的textview:时间和imageview:XXX头像。
public boolean judgeNode(AccessibilityNodeInfo node) {
try {
if (node == null) return false;
AccessibilityNodeInfo node1 = node.getParent().getParent();
int count = node1.getChildCount();
result.setLength(0);
for (int i = 0; i < count; i++) {
AccessibilityNodeInfo node2 = node1.getChild(i);
if ("android.widget.ImageView".equals(node2.getClassName())) {
CharSequence contentDescription = node2.getContentDescription();
if (contentDescription != null)
result.append(contentDescription.toString());
}
if ("android.widget.TextView".equals(node2.getClassName())) {
CharSequence thisNodeText = node2.getText();
if (thisNodeText != null) result.append(thisNodeText.toString());
}
}
if (result.equals(info)) return false;
info = hongbaoInfo;
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
红包找到了别忘了在判断结束后加上node.performAction(AccessibilityNodeInfo.ACTION_CLICK)来打开抢红包界面。下面就是开红包了,需要找到红包界面中中间的那个“开”字,有两种办法获得这个字,第一种是递归寻找界面上面的button,它是该界面的唯一button,第二种就是直接使用这个button的resource-id,不过据说这个id腾X会经常改动它,不怕麻烦可以选择哦。
找到之后别忘了点击这个node哦node.performAction(AccessibilityNodeInfo.ACTION_CLICK)。
在打开红包后进入红包详情,这时候要退出这个界面回到聊天界面,还有就是红包被抢光了,也需要回到聊天界面,这时候分别判断rootNodeInfo.findAccessibilityNodeInfosByText(text),如果找到,则为true,做performGlobalAction(GLOBAL_ACTION_BACK);就可以了。
具体的操作全部记录完毕了,目前的代码还有些碧油鸡,还需要改改,先这样吧。
参考资料:
记AccessibilityService使用(转)的更多相关文章
- 红包外挂史及AccessibilityService分析与防御
最近在做一个有趣的外挂的小玩意,前提我们要了解一个重要的类AccessibilityService 转载请注明出处:https://lizhaoxuan.github.io 前言 提起Accessib ...
- Spark踩坑记——Spark Streaming+Kafka
[TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...
- Spark踩坑记——数据库(Hbase+Mysql)
[TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...
- 这些年一直记不住的 Java I/O
参考资料 该文中的内容来源于 Oracle 的官方文档.Oracle 在 Java 方面的文档是非常完善的.对 Java 8 感兴趣的朋友,可以从这个总入口 Java SE 8 Documentati ...
- 千回百折:百度Java研发offer斩获记和经验分享
起因 面试过程 等待offer的过程中悟道 Java面试常考知识点个人总结 过程 百度——作为国内互联网的巨头之一,最近的一些风波对其褒贬不一,但是类似事件不是第一次发生,也绝对不是最后一次,对于真的 ...
- 记一次nginx部署yii2项目时502 bad gateway错误的排查
周六闲来无事,就试着安装和部署下yii2,安装过程没什么问题,但部署到nginx上时遇到了502 bad gatewary问题,折腾了半天才搞定.这个问题是我以前在部署yii2时没有遇到过的,因此记在 ...
- 原生JS实战:写了个一边玩游戏,一边记JS的API的游戏
本文是苏福的原创文章,转载请注明出处:苏福CNblog:http://www.cnblogs.com/susufufu/p/5878913.html 本程序[一边玩游戏,一边记JS的API]是本人的个 ...
- ArcGIS中的标注和注记
在ArcMap中可以使用标注和注记来识别要素,选择标注或注记取决于你需要如何控制文本显示以及在ArcMap中如何存储文本. 1.标注只是临时显示相关数据或字段 2.标注用于长时间保存数据以及显示方式. ...
- 记处理线上记录垃圾日志 The view 'Error' or its master was not found
最近监控线上日志,网站是ASP.NET MVC 开发的,发现不少错误日志都记录同样的内容: The view 'Error' or its master was not found or no vie ...
随机推荐
- 采用个hook技术对writefile函数进行拦截(2)
http://www.cnblogs.com/zhxfl/archive/2011/11/03/2233846.html 这个是笔者之前写过的WriteFile HOOK代码 必须补充对这几个函数的H ...
- Android Studio工程Gradle编译报错
一.环境的搭建: 首先搭建好AndroidStudio环境.我使用的是Ubuntu 12.04系统(由于此机器还要运行其他程序,为避免兼容性问题,暂未更新到最新,而继续沿用此稳定版),java和jdk ...
- 转:ubuntu下安装ssh服务
本文内容来自 http://www.cnblogs.com/chen1987lei/archive/2010/12/02/1894768.html ========================= ...
- 利用vs自带工具分析程序性能
测试程序写好后可以通过VS2010分析菜单里选择启用性能向导 选择CPU采样后就选择需要分析的项目 测试项目选择完成后就可以运行分析,结束分析后VS2010会提供个详细报告文档 从分析结果来看GetC ...
- SSIS 导入多个Excel 数据
http://blog.csdn.net/jinjazz/article/details/2710169 http://blog.csdn.net/jinjazz/article/details/27 ...
- Summit Online Judge
题意: 询问将取值在 $[L,R]$ 的若干个整数相加,可以得到 $[x,y]$ 区间内多少个数字. 解法: 只需要考虑求 $[L,R]$ 的数字能凑出 $[1,n]$ 的多少个数字,即可得出答案. ...
- ElasticSearch入门及核心概念介绍
Elasticsearch研究有一段时间了,现特将Elasticsearch相关核心知识和原理以初学者的角度记录下来,如有不当,烦请指正! 0. 带着问题上路——ES是如何产生的? (1)思考:大 ...
- Java常见设计模式学习(非原创)
文章大纲 一.策略模式二.观察者模式三.工厂模式四.单例模式五.其他模式六.设计模式总结七.参考文章 一.策略模式 现在假设我们有个"鸭子项目",首先我们用OOP(面向对象)的 ...
- CF1175E Minimal Segment Cover 题解
题意:给出\(n\)个形如\([l,r]\)的线段.\(m\)次询问,每次询问区间\([x,y]\),问至少选出几条线段,使得区间\([x,y]\)的任何一个部位都被至少一条线段覆盖. 首先有一个显然 ...
- mysql8必知必会7 连接 内连接 外连接 交叉连接
/* 2 需求:建立产品和分类表 1.查询每种分类的产品数量,没有产品的分类也要统计.(cname,quantity) 2.根据分类名称查询分类中的所有产品 */ -- --------------- ...