为了提供更好的信息无障碍体验, 继钉钉 iOS 完成无障碍支持后, 钉钉 Android 于 2017 年 6 月中旬启动无障碍改造工作经过与合作方深圳市信息无障碍研究会两个多月的共同努力, 不断沟通, 测试, 改进, 目前钉钉 Android 无障碍支持已经达到了较好的可用性
下面我们一起来回顾钉钉 Android 无障碍支持的项目过程
无障碍支持简介
视觉存在障碍的用户无法真切的看到手机设备的屏幕内容, 因此需借助读屏软件, 主要依赖听觉完成交互目前 Android 设备多采用 Talkback 作为无障碍辅助服务
Talkback 是 Android 系统内置的无障碍服务, 经过多个版本更新, 目前有较好的体验效果它主要通过语音震动和其他的语音反馈让盲人用户知道目前屏幕上是什么正在触摸什么能够做什么
Talkback 开启后基本的操作方式:
1. 滚动: 双指滑动
2. 点击: 选中 view 后在屏幕任意位置双击
3: 长按: 选中 view 后, 双击后按住
4. 左滑右滑: 前一项下一项
下面以已进行无障碍优化的钉钉为例, 描述下无障碍支持要做的事情, 清楚目的地才能够知道怎么做以下为部分聊天场景
为能够观察到朗读内容, 上面示例打开了 Talkback 中开发者设置的显示语音输出选项
我们要做的就是让 View 获得焦点后, 让读屏软件读出最恰当的描述, 让盲人用户清楚目前在什么位置, 能够做什么
无障碍事件分发
我们从源码层次分析无障碍事件分发流程, 帮助理解 Android 无障碍框架工作原理, 以更好的进行无障碍支持:
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
在 View.java 中, 我们可以看到很多类似上面 sendAccessibilityEvent 的方法调用这里就是我们查看无障碍事件分发的起点
最终调用继承 AccessibilityService 的读屏辅助 APP 的 onAccessibilityEvent(AccessibilityEvent event) 方法, 完成无障碍提示 Talkback 便是此类 App, 其 onAccessibilityEvent 内对 event 进行内容解析并朗读等音频反馈当然我们也可以继承 AccessibilityService 开发自己的无障碍辅助 APP
上图从方法调用顺序展示无障碍事件分发流程
无障碍工作清单
1. contentDescription 标记用户界面元素, 最简单也是最有效的
这是无障碍支持中最简单的工作, 也是最主要的工作, 依赖其就能够完成 90% 的无障碍支持工作
TalkBack 以 View 组件的四个属性作为读屏内容: contentDescription 组件类型 (图片按钮等), 状态 (例如 checkBox 的选中状态), 后三者由 Android 框架自动支持, contentDescription 属性不会显示在屏幕上, 当用户导航到这些控件时, 描述文本将会被读出对于 ImageView,ImageButton,CheckBox,contentDescription 是必须要添加的属性 TextView,Button 等含有 text 属性的元素, 可选择不添加, Android 框架将以其 text 属性作为读屏内容 contentDescription 需保证简洁明确, 切忌冗长, 较长的描述文本将影响盲人用户的操作效率
2. 启动焦点导航, 启动视图焦点和控制焦点顺序
盲人用户无法准确辩知当前界面可操作元素位置, 相对与触摸操作, 他们更多通过左右滑动获取可操作元素焦点因此无障碍中的另外一个主要工作是控制元素焦点
当用户界面元素的 android:focusable 属性设置为 true 时, 允许用户使用定向控制聚焦元素并与之交互 Android 框架提供的用户界面控件默认可聚焦, 同时 Android 也提供了 API 让开发者决定用户界面控件是否可聚焦与请求给控件赋予焦点无障碍支持中需保证每个操作做元素均是可聚焦的, 同时对无障碍用户存在干扰的元素应设置为不可获取焦点
焦点顺序是以一种在某一特定方向上寻找相邻元素的算法为基础的在某些情况下, 默认的算法可能不匹配开发者定义的顺序, 或可能对于用户不符合逻辑在这些情况下, 可以在布局文件中使用 android:nextFocusxxx 属性明确地覆盖焦点顺序
3. 自定义视图
当 Android 框架提供的无障碍事件无法满足我们的需求时, 例如, 拖动一个进度条, 我们希望把当前进度反馈给盲人用户, 此时便需要自定义视图通过上面对无障碍事件的分发过程的源码分析, 也可大致清楚自定义视图在无障碍支持时可以做的几个事情此处不再深入展开, 感兴趣的读者看参阅以下文档的自定义视图章节
http://www.siaa.org.cn/androidguideline.pdf
sendAccessibilityEvent() // 适当时机发送无障碍事件
onInitializeAccessibilityEvent() // 初始化无障碍事件
dispatchPopulateAccessibilityEvent()// 对无障碍事件重写
onInitializeAccessibilityNodeInfo() // 该方法填充 AccessibilityNodeInfo 对象, 无障碍服务该对象获得更多的上下文, 为用户提供合适的反馈
4. 自定义无障碍服务
Android 提供了标准的无障碍服务, 包括 Talkback, 开发人员也可以创建和发布自己的无障碍服务我们甚至可以利用无障碍服务代表用户操作, 完成诸多黑科技功能我们以 google 提供的 sample demo 为例
1) 无障碍服务声明, 像其他 Service 服务一样, 需要在 AndroidManifest.xml 中声明该服务
2) 无障碍服务参数配置, 可以采用代码动态设置, 同时 android4.0 后可采用 < meta-data > 标签完成
accessibilityEventTypes // 指定监
听的时间类型, 例如点击, 窗口变化等
packageNames // 指定该无障碍
服务可以处理的应用包名, 多个应用可用,
分隔
canRetrieveWindowContent // 是否可以
获取到窗口内容
3) 无障碍服务方法, 自定义无障碍服务需要继承自 AccessibilityService, 并重写该类 onAccessibilityEvent, onInterrupt 等方法通过 AccessibilityEvent 可获得 View 上下文等信息, 甚至可代表用户操作 抢红包插件等多是基于无障碍服务
4) 对获取到的 AccessibilityEvent 做音频或者震动反馈, 提供无障碍服务
5. 测试
无障碍优化非一蹴而就的事情, 特别是对如钉钉此类功能较多的应用, 会有遗漏以及处理不当的地方, 同时需防止增加 contentDescription 属性时引进的 NPE 异常因此无障碍优化过程中, 测试与回归是必须的环节, 也可以借助 Espresso 或 Robolectric 实现自动化测试测试方法与测试内容参照:
https://developer.android.com/training/accessibility/testing.html
另外, 我们也可以联系专业的无障碍团队, 帮助验收测试, 钉钉无障碍优化过程中, 深圳无障碍信息研究会给予了巨大的帮助和支持, 非常感谢
PS: 如果你希望了解盲人工程师的工作, 可阅读这篇历史文章:
对着黑屏, 背代码编程, 他的终极目标是让自己失业
特殊情况和注意事项
条件允许的情况下, 使用 Android 内置的界面控件, 这些控件默认提供了无障碍支持钉钉存在部分以 ImageView 代替 CheckBox 的使用方式, 该方式在 UI 上无区别, 但是在无障碍交互方式下, 盲人将无法正确获知当前 View 的操作方式和选中状态不应直接采用 ImageView 完成 CheckBox 的功能
EditView, 因该使用 hint 代替 contentDescription 文本框为空时, hint 能提示盲人用户输入什么内容, 当文本框非空时, talkback 将会读出当前输入文本的内容, 而非 hint 如设置了 contentDescription, 将会失去此体验
小控件组, 如果控件比推荐的触摸尺寸小, 可以考虑使用 ViewGroup 将这些控件组合起来, 并使用 android:contentDescription 为该组合提供内容描述以增大可点击区域, 减少无效焦点
有功能改变的控件, 如果用户在正常使用应用的过程中, 应用中的按钮或其他控件的功能会发生改变 (例如, 一个按钮从播放变为暂停), 需对按钮的 android:contentDescription 做出相应改变
相关联控件, 提供独立功能的一组控件, 例如日期选择器 (DatePicker), 当用户与相关联控件中的个别控件交互的时候, 提供有效的音频反馈
补充无障碍音频反馈, 例如, 开发者想要把应用程序执行的操作告知用户, 如书籍自动翻页功能, 需使用 announceForAccessibility(CharSequence) 方法让无障碍服务为用户读出该信息
无障碍中 contentDescription 属性是最简单而有效的, 务须保证简介准确
在创建布局前, 复查和遵守设计指南中提供的无障碍方案 https://material.io/guidelines/usability/accessibility.html#accessibility-principles
钉钉 Android 无障碍进展
为提供更好的信息无障碍体验, 让视障用户能够尽可能的像正常用户一样使用钉钉, 继钉钉 iOS 完成无障碍支持, 钉钉 Android 于 2017 年 6 月中旬启动无障碍改造工作经过与合作方深圳市信息无障碍研究会两个多月的共同努力, 不断沟通, 测试, 改进, 目前钉钉 Android 无障碍支持已经达到了较好的可用性目前浙江盲人学校等组织已在使用我们也建立了无障碍绿色通道, 以第一时间收到用户反馈的无障碍问题, 并及时作出处理
在移动互联网时代, 我们已经很难想象离开网络该如何生活, 对于视障者来说, 无障碍化程序能够帮助他们打开一个全新的世界钉钉正在推进国际化, 无障碍支持将帮助更多的国内外视障用户, 让钉钉国际化版本呈现出更高的质量
钉钉将持续推进无障碍工作, 目前 PC 端的无障碍改造已在开发中, 钉钉 Android 与钉钉 iOS 也在后续的迭代中将无障碍支持常态化, 不断优化无障碍体验, 带给视障用户更易用, 更好用的上手体验, 让钉钉帮助到越来越多的人... ...
后记
无障碍优化是需要坚持做的事情, 希望大家一起努力, 帮助视障群体通过互联网更好的融入社会如果你有更好的无障碍优化方案, 欢迎在留言区一起交流讨论
来源: https://yq.aliyun.com/articles/417019