核心类: AccessibiliiiiiiiityService

简单的说,AccessibilityService 为了方便残障人士实现操作,可以监控app的运行,在界面上实现一些自动操作.

而 AccessibilityService 的原理简单的来说就是: 安卓中 View 组件会主动发出各种状态改变的广播,Service收到后可以判断状态也可以获取发出广播的组件的view和view的子组件.

而实现一个 AccessibilityerService 需要三步

在xml文件中进行配置

在 AndroidManifest 文件中进行配置

实现AccessibilityService,监控app界面中的操作.

配置 xml 文件

在 res -> xml -> 路径下新建一个 autoservice_config 文件

android:accessibilityEventTypes="typeNotificationStateChanged|typeWindowStateChanged|typeWindowContentChanged"

android:accessibilityFeedbackType="feedbackGeneric"

android:accessibilityFlags=""

android:canRetrieveWindowContent="true"

android:description="@string/app_name"

android:notificationTimeout="100">

这个配置文件中有两个选项比较重要:

android:accessibilityEventTypes="typeNotificationStateChanged|typeWindowStateChanged|typeWindowContentChanged"

eventTypes 这个选项决定了你写的Service能收到什么类型的事件。

android:canRetrieveWindowContent 这个选项决定了能否通过 service提供的方法获取到app中的view.

在AndroidManifest文件中配置 AccessibilityService

android:name=".service.MyAutoService"

android:enabled="true"

android:label="@string/app_label"

android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"

android:process="@string/isolated_process">

android:name="android.accessibilityservice"

android:resource="@xml/autoservice_config" />

接着在manifest中配置 AccessibilityService,这里按配置规则来就可以了.

实现自己的自定义 AccessibilityService

接着就是最重要的部分,我们要根据要监控的app实现自己的自定义AccessibilityService , 要做的并不复杂,实现要清楚几个概念

AccessibilityNodeInfo

界面中所有的view元素都会作为这么一个类出现.

AccessibilityEvent

Event事件,当app进出前后台或者有点击滑动等事件的时候,都会发出这么一个event

onAccessibilityEvent()

接收 event的回调方法,我们就在这个回调中实现自己的逻辑.

@Override

public void onAccessibilityEvent(AccessibilityEvent event) {

String packageName = event.getPackageName().toString();

if (PACKAGE_NAME_TANTAN.equals(packageName)) {

Log.d(TAG, event.getPackageName().toString() + event.getEventType());

switch (event.getEventType()) {

case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:

AccessibilityNodeInfo mNodeInfo = getRootInActiveWindow();

Rect rect = new Rect();

mNodeInfo.getBoundsInScreen(rect);

boolean isPerformed = mNodeInfo.performAction(GESTURE_SWIPE_RIGHT);

accessibilityNodeInfo = mNodeInfo;

traversalNodeInfo(mNodeInfo);

performLoveButtonClick(mLoveButton);

// performSwipeRight(mNodeInfo);

Log.d(TAG, "child counts is :" + mNodeInfo.getChildCount() + "\nrect is :" + rect.toString() + "\n performed is :" + isPerformed);

break;

}

}

}

private void performLoveButtonClick(final AccessibilityNodeInfo mLoveButton) {

new Thread(new Runnable() {

@Override

public void run() {

while (true) {

try {

boolean isClicked = mLoveButton.performAction(AccessibilityNodeInfo.ACTION_CLICK);

Log.d(TAG, "love Button is clicked = " + isClicked);

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}).start();

}

private void traversalNodeInfo(AccessibilityNodeInfo mNodeInfo) {

int mChildCount = mNodeInfo.getChildCount();

Log.d(TAG, "class name:" + mNodeInfo.getClassName().toString() + " child count is :" + mChildCount + "\n");

mLoveButton = mNodeInfo;

if (mChildCount > 0) {

for (int i = 0; i < mChildCount; i++) {

traversalNodeInfo(mNodeInfo.getChild(i));

}

}

}

思路很简单:在 onAccessibilityEvent() 方法中收到 event后,判断事件类型,如果要监控的app出现在前台(接收到TYPE_WINDOW_STATE_CHANGED事件),此时遍历所有view找到探探软件中的喜欢按钮,然后模拟点击事件就OK了。

如何找到指定的view呢?

微信图片_20170604132450.png

之前的话,可以通过 android自带的 uiautomatorviewer 这个工具来获取到界面上的控件的id,然后通过 findAccessibilityNodeInfosByViewId() 这个方法来获取到制定的view,但是现在的很多app已经把id隐藏掉了,所以这个方法行不通了.

现在除了遍历所有的view也没有更好的解决办法了.

好在探探里的这个喜欢按钮在view树的最后一个节点,我们只要前序遍历这棵view树,保留最后一个view就能获取的这个button。

private void traversalNodeInfo(AccessibilityNodeInfo mNodeInfo) {

int mChildCount = mNodeInfo.getChildCount();

Log.d(TAG, "class name:" + mNodeInfo.getClassName().toString() + " child count is :" + mChildCount + "\n");

mLoveButton = mNodeInfo;

if (mChildCount > 0) {

for (int i = 0; i < mChildCount; i++) {

traversalNodeInfo(mNodeInfo.getChild(i));

}

}

}

boolean isClicked = mLoveButton.performAction(AccessibilityNodeInfo.ACTION_CLICK);

最后一步开启一个工作线程,定时点击button就ok了.

需要注意的问题

所有的自动操作都需要app保持在与用户交互的状态下才能进行,目前没有找到在后台也能让监控服务正常运行的方法.

探探自动右滑_利用AccessibilityService实现探探自动右划相关推荐

  1. python图片自动校正流量_利用python西电流量自动查询脚本

    ##code # -*- coding: utf-8 -*- #!/usr/bin/python ''' name: get_pay_info function: 自动获取流量信息 lib: requ ...

  2. 探探自动右滑_探探自动右滑:Python学习日志番外01

    给很多人种草了Python 像博主是直接用在工作中做ASO分析.自动化打包 但大多数朋友都说不知道用在什么地方 学会了爬虫也不知道干嘛? 博主想了许久 秉承"Python自有黄金屋,Pyth ...

  3. python修改桌面壁纸_利用Python对windows桌面自动更换壁纸

    根据时间星期几判断用哪张壁纸 # !/usr/bin/env python3 # -*- coding:utf-8 -*- import requests # import pywintypes im ...

  4. linux自动键入密码_通过键入条件进行Excel自动筛选

    linux自动键入密码 Someone emailed me for help with an Excel AutoFilter last week. He wanted to type the cr ...

  5. hibernate mysql 自动建表_配置hibernate根据实体类自动建表功能

    Hibernate支持自动建表,在开发阶段很方便,可以保证hbm与数据库表结构的自动同步. 如何使用呢?很简单,只要在hibernate.cfg.xml里加上如下代码 Xml代码update upda ...

  6. 怎么取消苹果手机自动续费_知乎会员怎样取消自动续费

    已开通连续订阅,需要从第三方支付账户( 或系统 )中关闭自动续费功能.否则自动续费仍有效,会持续扣费.
 关闭路径如下: 1.收到 [App store & Apple] 扣费账单的用户 (使 ...

  7. mysql 备份 没有自动删除文件_删掉spfile在没有自动备份控制文件下从以前的rman备份中恢复数据库...

    1.首先要有一个包含spfile备份的rman备份: run { allocate channel c1 device type disk; allocate channel c2 device ty ...

  8. 怎么取消苹果订阅自动续费_首开79,到期自动续费扣178元! 如何取消爱奇艺自动续费?...

    很多朋友通过了爱奇艺新用户99元一年的活动开通了爱奇艺黄金会员,目前爱奇艺官网在大力推广自动续费服务,自动续费首次开通比较优惠,但是到期后下次扣分价格就不怎么划算了,比如新用户首次开通最低79元一年( ...

  9. vscode python 自动补全_利用CodeBERT,这个VS Code扩展可以自动生成Python文档字符串...

    机器之心报道 编辑:魔王 该扩展利用可处理编程语言和自然语言的预训练模型 CodeBERT,实现快速生成 Python 文档字符串的功能. Visual Studio Code(简称 VS Code) ...

最新文章

  1. asp.net mvc 页面传值的方法总结
  2. 具有IOctl的简单字符驱动
  3. AI算法连载19:统计之最大熵算法
  4. 大屏数据可视化综合设计
  5. [NOIP2011] 计算系数(二项式定理)
  6. CTU 2019 Open Contest G.Beer Mugs
  7. 新手入门makefile教程
  8. Trump International Hotel Washington, D.C.宣布跻身猫途鹰“旅行者之选”美国获奖酒店四强之列
  9. 顺序表实验——顺序表的基本操作
  10. WPS Office JS宏实现文件和数据的上传及下载
  11. 将图片转换为Base64编码字符串、解析Base64编码字符串后生成图片
  12. autoit3转换php,autoit入门基础教程——字符串与变量转换.pdf
  13. 用字符数组输出平行四边形
  14. Soft Cosine Measure
  15. int(m)什么意思
  16. 计算机专业毕业论文格式,2016年计算机专业毕业论文内容及格式要求
  17. android 播放 优酷视频
  18. org.hibernate.QueryException: Unmatched braces for alias path 解决方案
  19. 华为机试真题 C 实现【非严格递增连续数字序列】【2022 Q4新题】
  20. Java: Tomcat到底是干嘛的?

热门文章

  1. mysql二进制日志开启方法_mysql中如何开启binlog?开启二进制日志文件?binary log?
  2. 渐进式Web应用程序居然是Web开发的未来
  3. kindeditor java上传_富文本编辑器kindeditor上传图片的配置方法
  4. spring boot 学习之五(日志配置)
  5. 当浙江“十万企业上云“遇见中国软件生态大会
  6. javascript数据结构与算法 --- 高级排序算法
  7. 文件中有一组整数,要求排序后输出到另一个文件中
  8. jfinal后台获取权限树,以供前台展示
  9. 指数体系与因素分析:概念、作用与种类
  10. You don't have permission to access / on this server提示 求解决办法~