Accessibility:无障碍,又称辅助性功能.

AccessibilityService:无障碍服务,继承于 Serveice. 它可以监听操作、检索窗口内容、启用触摸浏览等

一、Android中的 Accessibility

在原生android设备中 Settings 应用程序菜单中有一项 Accessibility(无障碍). 该项菜单下有项 TalkBack功能:它能读取屏幕上的内容,对于盲人和视力低弱人士而言,这项功能非常实用. 还有不知道大家是否会注意,使用三方app store批量自动安装app时,此时Accessibility中会出现 "xx自动安装"功能. 那么这些功能是怎实现的呢?是如何实现的呢?—— AccessibilityService

二、UiAutomator2.0 与 AccessibilityService

  在《UiAutomator2.0 - 控件实现点击操作原理》中已经分析了UiAutomator自动测试点击操作的具体实现过程,最终的操作是由 UiAutomation 这个类实现的.从这个类注释可以看出:可以将UiAutomation看作特殊AccessibilityService 类型,它不为服务生命周期提供挂钩,并且公开了对UI测试自动化有用的其他API.也就是说UiAutomator2.0是通过 AccessibilityService来实现的.

三、验证与 AccessibilityService的关联

a.为了验证上面的猜想是否正确,在Android studio中新建app工程->建一个服务类MyAccessibility继承 AccessibilityService

package com.zzw.barrierfree;

import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent; public class MyAccessibility extends AccessibilityService {
private static final String TAG = MyAccessibility.class.getSimpleName(); // 初始化服务操作
@Override
protected void onServiceConnected() {
Log.d(TAG, "onServiceConnected: ------- config accessibility ");
AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo();
// 响应某个应用的事件,包名为应用的包名。设置为null等同于所有包名
accessibilityServiceInfo.packageNames = new String[]{ "com.android.settings"};
// 响应时间的类型,事件分很多种:单击、长按、滑动。 这里设置为所有事件
accessibilityServiceInfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
// 设置回馈给用户的方式,语音播出还是振动
accessibilityServiceInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN;
// 响应时间的设置
accessibilityServiceInfo.notificationTimeout = 1000;
setServiceInfo(accessibilityServiceInfo);
} // 响应AccessibilityEvent的事件
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
int eventTypeId = event.getEventType();
String eventText = "";
Log.d(TAG, "onAccessibilityEvent: ----------------Start--------------");
switch (eventTypeId) {
case AccessibilityEvent.TYPE_VIEW_CLICKED:
eventText = "TYPE_VIEW_CLICKED";
break;
case AccessibilityEvent.TYPE_VIEW_FOCUSED:
eventText = "TYPE_VIEW_FOCUSED";
break;
case AccessibilityEvent.TYPE_VIEW_LONG_CLICKED:
eventText = "TYPE_VIEW_LONG_CLICKED";
break;
case AccessibilityEvent.TYPE_VIEW_SELECTED:
eventText = "TYPE_VIEW_SELECTED";
break;
case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:
eventText = "TYPE_VIEW_TEXT_CHANGED";
break;
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
eventText = "TYPE_WINDOW_STATE_CHANGED";
break;
case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
eventText = "TYPE_NOTIFICATION_STATE_CHANGED";
break;
case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END:
eventText = "TYPE_TOUCH_EXPLORATION_GESTURE_END";
break;
case AccessibilityEvent.TYPE_ANNOUNCEMENT:
eventText = "TYPE_ANNOUNCEMENT";
break;
case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START:
eventText = "TYPE_TOUCH_EXPLORATION_GESTURE_START";
break;
case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER:
eventText = "TYPE_VIEW_HOVER_ENTER";
break;
case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT:
eventText = "TYPE_VIEW_HOVER_EXIT";
break;
case AccessibilityEvent.TYPE_VIEW_SCROLLED:
eventText = "TYPE_VIEW_SCROLLED";
break;
case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED:
eventText = "TYPE_VIEW_TEXT_SELECTION_CHANGED";
break;
case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
eventText = "TYPE_WINDOW_CONTENT_CHANGED";
break;
}
eventText = eventText + ":" + eventTypeId;
Log.e(TAG, "onAccessibilityEvent:"+ eventText);
Log.d(TAG, "onAccessibilityEvent: -------------------End----------------");
} // 打断获取事件的过程
@Override
public void onInterrupt() { }
}

b.在AndroidManifest.xml中配置服务

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.zzw.barrierfree"> <application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/AppTheme.NoActionBar">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <!--服务配置-->
<service
android:name=".MyAccessibility"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
</service>
</application>
</manifest>

c.运行该app,此时在设置->无障碍中会出现配置的服务, 但是该服务处于关闭状态



d.手动开启该服务,打开android studio中的logcat. 操作(点击/滑动等)设置应用程序,会出现相应的响应事件.以下是命令开启方式:

adb shell settings put secure enabled_accessibility_services com.zzw.barrierfree/com.zzw.barrierfree.MyAccessibility

adb shell settings put secure accessibility_enabled 1



e.结合上篇的点击时监听的相应事件,与log中打印的事件是一致的. 那就说明:点击/滑动等操作是通过 AccessibilityService 监听对应的视图或窗口状态来判断操作是否成功执行.

UiAutomator2.0 - 与AccessibilityService的关联的更多相关文章

  1. UiAutomator2.0 - Toast信息的验证

    目录 问题:在做UI自动化测试时,偶尔会碰到 Toast 这种提示信息(如图),通过Uiautomatorviewer 无法获该类控件的信息.所以无法验证,该条case不能实现.然后就没然后了... ...

  2. Uiautomator1.0与Uiautomator2.0测试项目搭建与运行原理

    Uiautomator是Android原生测试框架,可以用于白盒接口测试也可以用于UI自动化测试,Uiautomator分1.0版本与2.0版本,它们都是基于UiAutomation的测试框架,都是通 ...

  3. UiAutomator2.0升级填坑记

    UiAutomator2.0升级填坑记 SkySeraph May. 28th 2017 Email:skyseraph00@163.com 更多精彩请直接访问SkySeraph个人站点:www.sk ...

  4. UiAutomator2.0 - 控件实现点击操作原理

    目录 一.UiObject 二.UiObject2 穿梭各大技术博客网站,每天都能看到一些的新的技术.突然感觉UiAutomator 2.0相对于现在来说已经是个很久远的东西了ε=(´ο`*))).写 ...

  5. UiAutomator1.0 与 UiAutomator2.0

      在使用2.0之前,对android自动化框架也做过一些了解<Android 自动化测试框架>.使用UiAutomator2.0也有一段时间,这里将1.0与2.0进行一个对比总结. Ui ...

  6. 初探UiAutomator2.0中使用Xpath定位元素

    J 今天的主题是讲一下在使用过程中遇到的一个问题,如何在UiAutomator2.0中使用Xpath定位元素? 背景 现在的app在打包成apk的时候都是有加固处理的,各种混淆加固,所以已经破坏了或扰 ...

  7. uiautomator2.0框架

    1.   Uiautomator1.0 Uiautomator2.0 date 2012 2015 super class UiAutomatorTestCase InstrumentationTes ...

  8. uiautomator2.0的配置的两种方法

    方法一(使用在线下载的方式导入依赖): 1.首先创建项目工程,创建的项目的android_api版本要与测试的android_api版本一致(24就是24 ,不能26或者17去兼容) 2.然后就是将本 ...

  9. hive1.1.0建立外部表关联HDFS文件

    0. 说明 已经安装好Hadoop和hive环境,hive把元数据存储在mysql数据库.这里仅讨论外部表和HDFS的关联,并且删掉外部表之后,对HDFS上的文件没有影响. 1. 在HDFS创建分区, ...

随机推荐

  1. es6中常用方法

    查询数组中是否包含了某个元素keyword arr.includes(keyword)

  2. WIN10解决:失败 – 检测到病毒文件下载失败问题

    欢迎访问我的个人博客四个空格,本文永久链接移至:WIN10解决:失败 – 检测到病毒文件下载失败问题 这个是Windows防火墙的原因,直接按WINDOWS键,输入windows,窗口搜索:Windo ...

  3. PHP——??空合并运算符和?:三元运算符

    前言 在上一篇随笔,用三元运算符简单写的一个东西,引发了对他的兴趣,所以打算研究下. PHP7的新特性: https://php.net/manual/zh/migration70.new-featu ...

  4. [ZJOI2019]线段树(线段树)

    看到这题,首先想到将求和转期望,即每次操作进行概率为1/2,求节点打标记概率. 首先对于每次区间修改操作,对节点进行分类: 1.这个点和其父亲都和修改区间无交,这种情况可以无视. 2.这个点和修改区间 ...

  5. 第四十五篇--将文件写入SD卡

    RAM: 运行内存 ROM: 外部存储,手机内部存储 SD卡:外部存储,SD卡存储. 在存储文件时千万不要忘记向清单文件中添加相应权限,并且android6.0以后还要添加运行时权限 还有一个权限有所 ...

  6. java动态代理源码解析

    众所周知,java动态代理同反射原理一直是许多框架的底层实现,之前一直没有时间来分析动态代理的底层源码,现结合源码分析一下动态代理的底层实现 类和接口 java动态代理的主要类和接口有:java.la ...

  7. 20165232 week1 kali安装

    20165232 Week1 kali安装 一.安装虚拟机 首先到kali官网下载64bit版本的kali(3.5G),这里我是从同学盘上拷过来的. 下载VMWARE 进入官网,找到如下图示 点击进行 ...

  8. quartz基本介绍和使用

    一.什么是quartz,有什么用. Quartz是一个完全由java编写的开源作业调度框架,由OpenSymphony组织开源出来.所谓作业调度其实就是按照程序的设定,某一时刻或者时间间隔去执行某个代 ...

  9. kafka 日常使用和数据副本模型的理解

    kafka 日常使用和数据副本模型的理解 在使用Kafka过程中,有时经常需要查看一些消费者的情况.Kafka健康状况.临时查看.同步一些数据,又由于Kafka只是用来做流式存储,又没有像Mysql或 ...

  10. 通过<meta>标签指定IE的文档模式实现CSS3兼容

    今天发现之前做好的一个页面在IE中打开显示的效果不正常,本地和服务器上显示的是两种不同的样式. 经过确认文档内容和CSS都是一样的. 通过IE F12(开发人员工具)发现不正常的样式 浏览器文档模式自 ...