为了提供更好的信息无障碍体验,继钉钉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也在后续的迭代中将无障碍支持常态化,不断优化无障碍体验,带给视障用户更易用,更好用的上手体验,让钉钉帮助到越来越多的人... ...
后记
无障碍优化是需要坚持做的事情,希望大家一起努力,帮助视障群体通过互联网更好的融入社会。如果你有更好的无障碍优化方案,欢迎在留言区一起交流讨论。
原文发布时间为:2018-01-31
本文作者:朴文