Android辅助功能

Android辅助功能:保留第四版正文机制,以所有者—状态—结果合同、事件轨迹和章专属故障完成可重放验收。

学习目标

  • 能沿“Android辅助功能”的用户事件解释Android组件、状态所有者、线程与销毁边界。
  • 能围绕“让 App 能被视障用户使用——contentDescription、焦点顺序、TalkBack 测试和可访问性最佳实践。”改出一个可运行结果,并用前后状态而非组件数量验收。
  • 能在旋转、进程重建、拒权、离线或无效输入中选择适用反例,定位首个状态分叉。
  • 能用双视口、大字体、焦点顺序、状态语义和对比度截图独立重放结论,并标明第四版机制与现代targetSdk政策的边界。

你的 App 可能有一批"看不见"的用户

全球数亿人有视力障碍,他们通过 使用手机——手指滑动屏幕,TalkBack 朗读手指碰到的元素。如果你的 App 不给 ImageView 加 contentDescription,TalkBack 用户听到的就是"未加标签的按钮"——他们完全不知道这按钮是干什么的。

无障碍(Accessibility)不是可选的"附加功能"——它是让产品能被所有人使用的基础要求。

TalkBack 看到的不是你界面上的像素,而是一棵无障碍语义树:每个可聚焦控件是一个节点,TalkBack 朗读它的 contentDescription 或文本,并按从上到下、从左到右的顺序遍历焦点。下图把同一个界面和它对应的语义树并排放在一起,看清"用户看到的"和"TalkBack 听到的"差在哪。

无障碍语义树:界面控件 → TalkBack 朗读什么、按什么顺序读每个可聚焦控件 = 一个语义节点;TalkBack 从上到下、从左到右遍历焦点,触摸探索 + 双击激活界面(用户看到的)无障碍语义树(TalkBack 听到的)焦点遍历◉ 拍照ImageButton1朗读:拍照clickable=true → 双击激活犯罪现场照片TextView2朗读:犯罪现场照片clickable=false → 仅朗读▬▬▬▬▬ImageView(装饰分割图)⊘ 跳过(不进焦点遍历)importantForAccessibility="no"2024-03-12 已处理列表项(可点击)3朗读:2024 年 3 月 12 日,已处理,按钮clickable=true → 双击激活记住四条:① ImageButton / ImageView 不设 contentDescription,TalkBack 只会读「未加标签的按钮」② 纯装饰图设 importantForAccessibility="no" 被跳过 ③ 焦点从上到下、从左到右遍历④ 用户用手指划过屏幕触摸探索(朗读当前控件),再双击激活它
TalkBack 看到的不是像素,而是这棵 无障碍语义树 :每个可聚焦控件是一个节点,朗读它的 contentDescription 或文本,并按从上到下、从左到右 遍历焦点 。图标类控件不设 contentDescription 就会被读成「未加标签的按钮」;纯装饰图设 importantForAccessibility="no" 让阅读器跳过。用户靠触摸探索朗读、双击激活。

基本无障碍属性

contentDescription

<!-- ❌ 差:TalkBack 读不了 -->
 
<!-- ✅ 好:TalkBack 会读"发送消息" -->

纯装饰性图片(比如背景花纹)设 android:contentDescription="@null" —— TalkBack 会跳过它。

焦点顺序

默认情况下,TalkBack 按布局文件顺序从左到右、从上到下朗读。如果布局跟视觉顺序不一致,用 nextFocusForward 等属性调整:

 

测试无障碍

Android Studio 内置 Accessibility Scanner——一键扫描当前页面,自动检测缺失的 contentDescription、对比度不足、触摸区域太小等问题。开启 TalkBack(设置→无障碍→TalkBack),实际操作一遍 App,感受视障用户的体验。

分步1 / 5

① 开启 TalkBack

进入"设置 → 无障碍 → TalkBack",打开开关。听到语音反馈即表示激活成功。注意:TalkBack 的手势逻辑与常规操作不同——单指滑动切换焦点,双击触发点击。

容易踩的坑

小结

  • contentDescription 是 TalkBack 用户"看到"你界面的唯一窗口——写有意义的描述
  • 装饰性图片设 @null 避免干扰;按钮/图标必须有描述
  • 焦点顺序确保朗读顺序符合用户预期
  • Accessibility Scanner 自动检测常见无障碍问题
  • 无障碍设计惠及所有人——高对比度字幕所有人看得更清,大触摸区域所有人点得更准

练习

问题 1:“第18章 Accessibility”覆盖哪些正式节点和项目主线?

问题 2:怎样建立本页最小可执行实验?

问题 3:为什么只在正常点击路径运行不能证明完成?

问题 4:怎样设计能推翻当前实现的反例?

问题 5:从第4版语境迁移到现代目标SDK时如何控制变量?

问题 6:本页达到独立交接标准需要什么?

名词解释

本章出现的专业名词,用大白话再讲一遍。

TalkBack

Android 内置的屏幕阅读器。视障用户通过触摸和滑动手势导航界面,TalkBack 朗读手指触碰到的元素内容。

Accessibility Scanner

Google 提供的无障碍扫描工具。分析当前界面,自动检测缺失的 contentDescription、对比度问题、触摸区域过小等无障碍缺陷。

“Android辅助功能”不使用未获授权的纸书正文;InformIT出版信息授权电子版完整目录只用于确认第四版32章、269个正式目录节点和时代语境,第四版官方勘误用于识别工具链变更。下列中文解释、图示、交互、代码与练习均为独立教学重写,平台行为再以Android Developers的一手文档复核。

为什么“Android辅助功能”必须回到可观察状态

“Android辅助功能”的学习结果不是记住类名,而是能预测“让 App 能被视障用户使用——contentDescription、焦点顺序、TalkBack 测试和可访问性最佳实践。”在一次输入、一次重建和一次失败中的不同状态,并指出哪条Android合同产生差异。

第四版机制逐项深读

18. Accessibility

在“Android辅助功能”中,“18. Accessibility”的通过条件是可比较体验,不是扫描器零告警;动态错误、超时与音频反馈仍需人工验证。

TalkBack

在“Android辅助功能”中,分析“TalkBack”按TalkBack线性焦点顺序走完整任务,检查自定义控件是否暴露可执行action与状态变化。

Making Non-Text Elements Readable by TalkBack

在“Android辅助功能”中,分析“Making Non-Text Elements Readable by TalkBack”按TalkBack线性焦点顺序走完整任务,检查自定义控件是否暴露可执行action与状态变化。

Creating a Comparable Experience

在“Android辅助功能”中,“Creating a Comparable Experience”要求可访问性树表达与视觉界面等价的名称、角色、状态和操作;contentDescription不能重复可见文本或描述装饰。

For the More Curious: Using Accessibility Scanner

在“Android辅助功能”中,“For the More Curious: Using Accessibility Scanner”的通过条件是可比较体验,不是扫描器零告警;动态错误、超时与音频反馈仍需人工验证。

Challenge: Improving the List

在“Android辅助功能”中,“Challenge: Improving the List”用于推翻“让 App 能被视障用户使用——contentDescription、焦点顺序、TalkBack 测试和可访问性最佳实践。”的顺利路径:先写预期,再引入一个边界输入、重建或平台差异,并用状态、日志与用户结果解释首个分叉。

Challenge: Providing Enough Context for Data Entry

在“Android辅助功能”中,“Challenge: Providing Enough Context for Data Entry”用于推翻“让 App 能被视障用户使用——contentDescription、焦点顺序、TalkBack 测试和可访问性最佳实践。”的顺利路径:先写预期,再引入一个边界输入、重建或平台差异,并用状态、日志与用户结果解释首个分叉。

Challenge: Announcing Events

在“Android辅助功能”中,验证“Challenge: Announcing Events”在大字体、触摸探索和无视觉条件下完成同一任务,并记录首个焦点陷阱或缺失播报。

“Android辅助功能”验收回顾

“Android辅助功能”只有在双视口、大字体、焦点顺序、状态语义和对比度截图能够从相同基线再次得到相同断言时才通过;第四版机制与现代平台政策分别记录,不用新API名称掩盖旧行为。

← 上一页:应用本地化 · 下一页:数据绑定与MVVM →

章专属可重放状态实验

先预测“启用 TalkBack,遍历列表、编辑字段并触发状态变化”发生后,View 语义树、AccessibilityService 与应用状态应怎样改变content description、role、state、action 和 announcement;再操作三个实验。第四版示例与当前 Android 政策分别记录,实验不把新 API 名称倒填为原书内容。

实验一:所有者—状态—结果合同

选择任一正式目录节点和正常/边界场景,检查它是否真的进入本章状态合同。目录标题只有同时出现在解释、可视状态和交付证据中才算覆盖。

Owner · state · observable result

Android辅助功能:状态合同

让 TalkBack 用户以线性焦点、语义标签和可执行 action 完成同一任务

验证场景

第四版正式目录节点

accessibility · 正常任务

18. Accessibility固定 SDK、设备配置和初始状态,触发“启用 TalkBack,遍历列表、编辑字段并触发状态变化”

状态所有者View 语义树、AccessibilityService 与应用状态
受控状态content description、role、state、action 和 announcement
触发事件启用 TalkBack,遍历列表、编辑字段并触发状态变化

冻结入口:18. Accessibility

记录View 语义树、AccessibilityService 与应用状态的初始content description、role、state、action 和 announcement

观察:无障碍节点树、焦点顺序、操作录制、Scanner 与任务断言中的“18. Accessibility”轨迹

预期:由View 语义树、AccessibilityService 与应用状态提交content description、role、state、action 和 announcement,并持续满足“非视觉用户获得与视觉用户等价的任务结果和变化反馈”

实验二:事件与生命周期轨迹

沿五次转换逐步执行“启用 TalkBack,遍历列表、编辑字段并触发状态变化”。每一步只允许View 语义树、AccessibilityService 与应用状态按职责提交状态,并持续核对“非视觉用户获得与视觉用户等价的任务结果和变化反馈”。

Deterministic event replay

Android辅助功能:事件轨迹

选择一次状态转换1 / 5

不变量:非视觉用户获得与视觉用户等价的任务结果和变化反馈

交付证据:无障碍节点树、焦点顺序、操作录制、Scanner 与任务断言

实验三:章专属反例与同输入恢复

注入“自定义图片按钮没有名称,TalkBack 只读出“未标记的按钮””,保存第一个偏离点;撤销后以完全相同的 SDK、设备状态和用户事件重放。只有无障碍节点树、焦点顺序、操作录制、Scanner 与任务断言一起恢复才算修复。

Fault · cancel · restore

Android辅助功能:反例与恢复

故障:自定义图片按钮没有名称,TalkBack 只读出“未标记的按钮”

1. 冻结输入一致

第 1 次使用相同 SDK、设备配置、初始状态与用户事件

2. 注入边界一致

保持正常输入不变,仅注入“自定义图片按钮没有名称,TalkBack 只读出“未标记的按钮””

3. 检查所有者一致

非视觉用户获得与视觉用户等价的任务结果和变化反馈

4. 核对结果一致

无障碍节点树、焦点顺序、操作录制、Scanner 与任务断言

讨论

评论区加载中…