Android-Accessibility-Api

Github >

更新:Android-Accessibility-Api (2.0)

安卓无障碍服务Api, 为了简化无障碍服务使用,并使用 Kotlin 以提供简洁的Api。

文章目录

  • Android-Accessibility-Api
      • **[更新:Android-Accessibility-Api (2.0)](https://blog.csdn.net/qq_37299249/article/details/122968555)**
    • 基础导航
    • 视图检索
      • 提取文字
      • 视图搜索
    • 视图节点(ViewNode)
    • 全局手势
      • 示例
      • Api文档
    • 使用
      • 引入 Android-Accessibility-Api
      • 创建你的服务
        • 基础服务
        • 手势服务
      • 额外配置
      • 合并服务

基础导航

查看代码

//无障碍服务声明 未开启会跳转设置页面提示开启服务,并抛出异常 终止执行
requireBaseAccessibility()
toast("下拉通知栏..")
delay(1000)
toast("快捷设置..")
//操作之间需要适当延时等待
delay(1000)
//下拉通知栏快捷设置
quickSettings()
delay(1000)
//返回操作
back()
delay(500)
//返回操作
back()
delay(1000)
//电源菜单
powerDialog()
delay(500)
back()
delay(1000)
//进入最近任务页面
recents()
delay(1000)
back()
delay(1000)
//Home 按键 / 返回桌面
home()
delay(100)

更多操作:

方法 说明
lockScreen() 锁屏,需要Android P
screenShot() 触发系统截屏,需要Android P
splitScreen() 触发系统分屏,需要Android P

视图检索

提取文字

requireBaseAccessibility()
//使用 ScreenTextFinder() 来搜索屏幕上的文字
val ts = ScreenTextFinder().find().joinToString("\n\n")withContext(Dispatchers.Main) {AlertDialog.Builder(act).apply {setTitle("提取文字:")setMessage(ts)show()}
}

视图搜索

  1. 提供一个基础类 ViewFinder, 并封装一个 ViewFinderWithMultiCondition 来指定搜索条件,实现快速搜索

ViewFinder 主要方法:

方法 说明
findFirst(includeInvisible: Boolean = false): ViewNode? 立即搜索,返回满足条件的第一个结果
includeInvisible: 是否包含不可见元素
findAll(includeInvisible: Boolean = false): Array<ViewNode> 立即搜索,返回满足条件的所有结果
waitFor(waitMillis: Long = 30000): ViewNode? 等待搜索,在指定时间内循环搜索(视图更新),超时返回null
require(waitMillis: Long = WAIT_MILLIS): ViewNode 等待超时抛出异常

示例1: 等待 Chrome 打开 > 展开菜单

//等待无障碍开启 默认时间30s,超时将抛出异常
waitBaseAccessibility()
toast("start chrome after 1s")
delay(1000)
//打开Chrome
val targetApp = "com.android.chrome"
act.startActivity(act.packageManager.getLaunchIntentForPackage(targetApp))
//等待页面
if (waitForApp(targetApp, 5000).also {toast("wait " + if (it) "success" else "failed")}
) {//id 搜索,点击打开菜单withId("menu_button").tryClick()
}

示例2: 文本操作

查看代码

requireBaseAccessibility()
//editor() 指定编辑框
editor().require().apply { // this is ViewNoderepeat(5) {//追加文本appendText(".x")delay(500)}delay(1000)//清空文本text = ""delay(1000)//设置文本text = "123456"delay(1000)//选择文本setSelection(0, 5)delay(1000)//清除选择clearSelection()//失去焦点clearFocus()
}
  1. 提供自定义搜索条件 CustomViewFinder

搜索所有可点击的视图:

requireBaseAccessibility()
//自定义条件搜索
val s = findAllWith { it: AccessibilityNodeInfo -> it.isClickable
}.joinToString("\n\n")withContext(Dispatchers.Main) {AlertDialog.Builder(act).apply {setTitle("可点击节点:")setMessage(s)show()}
}

视图节点(ViewNode)

根据视图搜索得到 ViewNode,可进行的操作详见接口:ViewOperation.kt

全局手势

全局手势可以点击/长按任意坐标,执行路径手势。

示例

查看代码

class DrawableAction : Action {override val name: Stringget() = "手势画图 - Rect - Circle - Oval"@RequiresApi(Build.VERSION_CODES.N)override suspend fun run(act: Activity) {requireBaseAccessibility()requireGestureAccessibility()act.startActivity(Intent(act, DrawableActivity::class.java))toast("1s后开始绘制,请不要触摸屏幕")delay(1000)//设置相对屏幕 非必须setScreenSize(500, 500)//指定点转路径手势gesture(2000L, arrayOf(100 t 100,100 t 200,200 t 200,200 t 100,100 t 100))delay(800)//点击clear按钮withText("clear").tryClick()//使用PathdrawCircle()delay(800)withText("clear").tryClick()drawOval()}@RequiresApi(Build.VERSION_CODES.N)fun drawCircle() {val p = Path().apply {//此处路径坐标为绝对坐标addOval(RectF(500f, 500f, 800f, 800f), Path.Direction.CW)}gesture(2000L, p) {toast("打断")}}//AdapterRectF 会根据设置的相对屏幕大小换算@RequiresApi(Build.VERSION_CODES.N)fun drawOval() {val p = Path().apply {//使用AdapterRectF 会根据设置的相对屏幕尺寸将坐标转换addOval(AdapterRectF(200f, 200f, 300f, 300f), Path.Direction.CW)}gesture(2000L, p)}infix fun <A, B> A.t(that: B): Pair<A, B> = Pair(this, that)
}

Api文档

手势Api全部需要Android N+

展开查看

方法 说明
fun setScreenSize(width: Int, height: Int) 设置屏幕相对坐标
fun gesture(
duration: Long,
points: Array<Pair<Int, Int>>,
onCancel: Function0? = null
): Boolean
根据点坐标生成路径 执行手势
fun gesture(
duration: Long,
path: Path,
onCancel: Function0? = null
): Boolean
根据Path执行手势
fun gestureAsync(
duration: Long,
points: Array<Pair<Int, Int>>
)
异步执行手势
fun gestures(
duration: Long,
ppss: Array<Array<Pair<Int, Int>>>,
onCancel: Function0? = null
): Boolean
多路径手势
fun longClick(x: Int, y: Int) 长按; x,y 相对坐标
fun swipe(x1: Int, y1: Int, x2: Int, y2: Int, dur: Int) 两点间滑动
fun scrollUp(): Boolean 向上滑动
fun scrollDown(): Boolean 向下滑动

使用

由于部分系统版本启动支持手势的无障碍服务会造成系统卡顿(掉帧),所以本库分为两个服务来设计。

引入 Android-Accessibility-Api

  1. Add it in your root build.gradle at the end of repositories:
allprojects {repositories {...maven { url 'https://jitpack.io' }}
}
  1. Add the dependency
dependencies {implementation 'com.gitee.Vove:Android-Accessibility-Api:Tag'
}

the TAG is

创建你的服务

基础服务

用来支持 布局检索,视图操作

  1. 定义你的 BaseAccessibilityService

展开查看 BaseAccessibilityService

class BaseAccessibilityService : AccessibilityApi() {//启用 页面更新 回调override val enableListenAppScope: Boolean = trueoverride fun onCreate() {//must setbaseService = thissuper.onCreate()}override fun onDestroy() {//must setbaseService = nullsuper.onDestroy()}//页面更新回调override fun onPageUpdate(currentScope: AppScope) {Log.d("TAG", "onPageUpdate: $currentScope")}
}
  1. 服务注册
<serviceandroid:name=".service.BaseAccessibilityService"android:description="@string/base_ser_desc"android:label="BaseService Demo"android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"><intent-filter><action android:name="android.accessibilityservice.AccessibilityService" /></intent-filter><meta-dataandroid:name="android.accessibilityservice"android:resource="@xml/base_accessibility_config" />
</service>
  1. base_accessibility_config.xml

点击展开 res/xml/base_accessibility_config.xml

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"android:accessibilityEventTypes="typeWindowStateChanged"android:accessibilityFeedbackType="feedbackAllMask"android:accessibilityFlags="flagIncludeNotImportantViews|flagReportViewIds|flagRetrieveInteractiveWindows|flagRequestEnhancedWebAccessibility"android:canRetrieveWindowContent="true"android:description="@string/base_ser_desc"android:notificationTimeout="10"android:canRequestEnhancedWebAccessibility="true"android:settingsActivity=".MainActivity"android:summary="基础导航/视图检索操作"/>
<!--    android:canRequestFilterKeyEvents="true"-->
<!--flagRequestFilterKeyEvents-->

手势服务

用于执行手势,Android N+可用

  1. 定义 GestureAccessibilityService

展开查看 GestureAccessibilityService

class GestureAccessibilityService : AccessibilityService() {override fun onCreate() {super.onCreate()//must callAccessibilityApi.gestureService = this}override fun onDestroy() {super.onDestroy()//must callAccessibilityApi.gestureService = null}override fun onInterrupt() {}override fun onAccessibilityEvent(event: AccessibilityEvent?) {}
}
  1. 服务注册
<serviceandroid:name=".service.GestureAccessibilityService"android:description="@string/ges_ser_desc"android:label="Gesture Service Demo"android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"><intent-filter><action android:name="android.accessibilityservice.AccessibilityService" /></intent-filter><meta-dataandroid:name="android.accessibilityservice"android:resource="@xml/gesture_accessibility_config" />
</service>
  1. gesture_accessibility_config.xml

点击展开 res/xml/gesture_accessibility_config.xml

和基础服务配置区别仅为 android:canPerformGestures="true"

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"android:accessibilityEventTypes=""android:accessibilityFeedbackType=""android:accessibilityFlags=""android:canPerformGestures="true"android:canRetrieveWindowContent="false"android:description="@string/ges_ser_desc"android:notificationTimeout="10"android:packageNames=""android:settingsActivity=".MainActivity"android:summary="执行手势" />

额外配置

在 Application 中初始化:

指定 BASE_SERVICE_CLSGESTURE_SERVICE_CLS

override fun onCreate() {super.onCreate()AccessibilityApi.apply {BASE_SERVICE_CLS = BaseAccessibilityService::class.javaGESTURE_SERVICE_CLS = GestureAccessibilityService::class.java}
}

合并服务

如果你想使用一个服务来完成,可使用如下配置

  1. 创建服务
class MyAccessibilityService : AccessibilityApi() {//启用 页面更新 回调override val enableListenAppScope: Boolean = trueoverride fun onCreate() {//同时设置baseService = thisAccessibilityApi.gestureService = thissuper.onCreate()}override fun onDestroy() {//同时设置baseService = nullAccessibilityApi.gestureService = nullsuper.onDestroy()}//页面更新回调override fun onPageUpdate(currentScope: AppScope) {Log.d("TAG", "onPageUpdate: $currentScope")}
}
  1. 清单注册
<serviceandroid:name=".service.MyAccessibilityService"android:description="@string/ser_desc"android:label="Service Demo"android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"><intent-filter><action android:name="android.accessibilityservice.AccessibilityService" /></intent-filter><meta-dataandroid:name="android.accessibilityservice"android:resource="@xml/accessibility_config" />
</service>
  1. res/xml/accessibility_config.xml

点击展开 accessibility_config.xml

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"android:accessibilityEventTypes="typeWindowStateChanged"android:accessibilityFeedbackType="feedbackAllMask"android:accessibilityFlags="flagIncludeNotImportantViews|flagReportViewIds|flagRetrieveInteractiveWindows|flagRequestEnhancedWebAccessibility"android:canRetrieveWindowContent="true"android:description="@string/base_ser_desc"android:notificationTimeout="10"android:canPerformGestures="true"android:canRequestEnhancedWebAccessibility="true"android:settingsActivity=".MainActivity"android:summary="基础导航/视图检索操作"/>
<!--    android:canRequestFilterKeyEvents="true"-->
<!--flagRequestFilterKeyEvents-->
  1. Application 初始化配置
AccessibilityApi.apply {BASE_SERVICE_CLS = MyAccessibilityService::class.javaGESTURE_SERVICE_CLS = MyAccessibilityService::class.java
}

更多 Api 可在下列文件查看

  • view_finder_api.kt
  • gesture_api.kt
  • nav_api.kt
  • nav_api.kt
  • ViewNode

安卓无障碍API封装库: Android-Accessibility-Api相关推荐

  1. 张鸿洋 视频 android,PageStateManager 在张鸿洋的 LoadingAndRetryManager 的基础上改写,优化 api,封装 @codeKK Android开源站...

    页面状态管理 在张鸿洋的LoadingAndRetryManager的基础上改写,修正一些 bug,优化 api,并提供使用时封装的例子 特性 api 超级简单 可以在 xml 中使用 Statefu ...

  2. android7 api中文版pdf,android 7 api 中文

    android是比较常用的手机系统,很多品牌的手机都是安卓系统的,对于开发者来说相对于ios系统更好进行扩展.这里小编带来了android 7 api中文文档,介绍了一些基本语法.接口知识,对于开发者 ...

  3. android英文文献翻译,安卓 英文 外文 文献翻译 android api级别.doc

    安卓 英文 外文 文献翻译 android api级别.doc Android API Levels As you develop your application on Android, it s ...

  4. 谷歌Android无障碍套件,安卓无障碍套件下载-Android无障碍套件最新版下载v8.2.0.324286243_游戏369...

    安卓无障碍套件(Android Accessibility Suite)是一款包含一系列无障碍应用的app,用户仅通过开关即可控制安卓设备,朗读屏幕上的内容,使用这个大型屏幕菜单来锁定手机.控制音量和 ...

  5. Android Location API跟踪您当前的位置

    Android Location API can be used to track your mobile current location and show in the app. In this ...

  6. 使用Android Accessibility实现免Root自动批量安装功能

    对于国内Android设备,应用的自动批量安装/更新一直是一个痛点,在之前,第三方应用商店通常要求设备Root,然后调用系统的PackageManagerService命令行来实现后台安装.最近,豌豆 ...

  7. Android Accessibility自动安装app

    对于国内Android设备,应用的自动批量安装/更新一直是一个痛点,在之前,第三方应用商店通常要求设备Root,然后调用系统的PackageManagerService命令行来实现后台安装.最近,豌豆 ...

  8. 【Android 内存优化】Android 原生 API 图片压缩原理 ( Bitmap_compress 方法解析 | Skia 二维图形库 | libjpeg 函数库 | libpng 函数库 )

    文章目录 一. 图片质量压缩方法 二. Skia 二维图形库 三. libjpeg.libpng 函数库引入 在博客 [Android 内存优化]图片文件压缩 ( Android 原生 API 提供的 ...

  9. 渣男手册,安卓恋爱话术库API

    渣男手册,安卓恋爱话术库API  Lan   2020-04-17 14:56   228 人阅读  0 条评论 import requestswhile (True):i = input(" ...

最新文章

  1. 移动Web开发图片自适应两种常见情况解决方案
  2. 给嵌入式工程师的一封信
  3. (经典)Hibernate多对一关系映射(四)
  4. jQuery选中该复选框来实现/全部取消/未选定/获得的选定值
  5. 架构之路之spring+springmvc+maven+mongodb的搭建(转载:http://blog.csdn.net/tomcat_2014/article/details/55100130)
  6. 来几个FUNNY PICS,让大家笑一笑!
  7. 计算机网络上机作业,204计算机网络上机大作业.docx
  8. php 计算数组的差值,数组计算差值及项的小计,该如何处理
  9. 未能加载文件或程序集 Newtonsoft.Json, Version=4.5.0.0 的报错,解决方法
  10. Centos7 Kubernetes(K8s) k8s 开发 单服务器部署 rocketmq
  11. 【心电信号】基于matlab GUI心电信号数字滤波处理【含Matlab源码 484期】
  12. IE兼容性问题web.config设置
  13. 联想服务器如何u盘安装系统教程,联想lenovo u盘安装Windows 7系统操作步骤详解
  14. pandas最快入门(一)-读取与数据结构
  15. 【纯干货】Vue仿蘑菇街商城项目(vue+koa+mongodb)X
  16. 无线宽带有哪些适用场景?
  17. 在线互动课堂Web版初体验(视频连麦互动)
  18. Day537538539540541.scrapy爬虫框架 -python
  19. 禁止macOS 在Safari下载的ZIP文件自动解压
  20. JS中Array方法中常用方法一:Array.isArray():

热门文章

  1. eMMC Mandatory Boot和Alternative Boot
  2. java毕业设计体育城场地预定系统前台源码+lw文档+mybatis+系统+mysql数据库+调试
  3. oracle mysql查询速度慢_oracle 根据时间范围查询缓慢问题排查解决
  4. 12306系统架构,凭什么支撑每天如洪水般的各种抢票插件?
  5. 贡献三个可以查找免费代理服务器的网址
  6. 小学计算机课教师教学笔记,小学信息技术教学随笔
  7. 开篇-HOG提取训练检测+样本制作
  8. 计算机对测绘领域的应用,GPS技术在测绘工程领域中的应用
  9. 怎么设置ie10默认浏览模式为兼容模式
  10. 顺丰“牵手”唯品会,电商物流大战事的小缩影