TalkBack — 谷歌为 Android 内置的屏幕朗读器(screen reader),是 Android Accessibility Suite 软件包的一部分。它朗读界面元素并允许通过手势控制设备,为盲人和弱视用户提供对智能手机功能的完全访问。根据 Google Accessibility Help (2025),TalkBack 预装在大多数 Android 设备上,支持超过 30 种语言和不同的语音引擎。
要点
TalkBack — 是适用于 Android 的屏幕朗读器(screen reader),由 Google 开发,是 Android Accessibility Suite 的一部分。它为有视力障碍的用户提供语音反馈和手势控制。TalkBack 可以在智能手机、平板电脑、Smart TV 以及 Wear OS 的可穿戴设备上运行。
TalkBack 首次出现在 Android 1.6(Donut)2009 年。最初它是一个独立项目,但随着 Android 4.0(Ice Cream Sandwich)的发布,它成为了 Android Accessibility Suite 的一部分——一个包含 Switch Access 和 Select to Speak 的服务集合。从 Android 10 开始,TalkBack 预装在所有具有 Google Play 服务的设备上,包括合作伙伴的设备——三星、小米、Oppo 等。
TalkBack 支持超过 30 种语言和不同的语音引擎:Google Text-to-Speech、Samsung TTS 和第三方引擎。中文使用 Google TTS 语音引擎,提供自然的发音和正确的语调。用户可以在 TalkBack 设置中调整语速、音高并选择语音性别。
TalkBack 基于无障碍服务(AccessibilityService)工作——这是一种 Android 系统机制,允许应用程序获取有关界面状态的信息并以编程方式与之交互。当 TalkBack 启用时,它会拦截所有触摸事件并将其转换为屏幕朗读器的特殊手势。
TalkBack 工作的关键元素是无障碍焦点(accessibility focus)。与可见为文本字段高亮的标准输入焦点不同,无障碍焦点显示为元素周围的黄色边框,对于没有 TalkBack 的用户不可见。当无障碍焦点落到一个元素上时,TalkBack 会朗读其内容、类型和状态。
用户通过手势移动无障碍焦点:向右滑动 — 下一个元素,向左滑动 — 上一个元素。元素按照 AccessibilityNodeInfo(Android 为每个屏幕构建的无障碍树)确定的顺序被遍历。开发者可以通过 accessibilityTraversalBefore 和 accessibilityTraversalAfter 属性影响顺序,这对于具有自定义布局的复杂屏幕尤其重要。
屏幕上的每个 View 都由无障碍树中的一个节点表示——一个 AccessibilityNodeInfo 对象。该对象包含:元素的文本(contentDescription 或 View 的文本)、元素类型(按钮、复选框、输入字段)、状态(启用/禁用/选中)、在屏幕上的位置以及可用操作列表。TalkBack 遍历此树并按遍历顺序朗读每个节点。
如果 View 没有文本内容(例如,没有描述的 ImageView),它对 TalkBack 不可见——用户不会知道其存在。为了解决这个问题,开发者设置 contentDescription —— TalkBack 代替沉默朗读的文本描述。Android 还支持状态可更改的元素的 stateDescription(选中/未选中)和带有提示的输入字段的 hintText。
TalkBack 将标准 Android 手势转换为屏幕朗读器的特殊手势。大多数操作使用一根或两根手指执行,三指手势保留用于全局操作。
| 操作 | 手势 | 结果 |
|---|---|---|
| 朗读元素 | 单指触摸 | 说出元素的名称和类型 |
| 激活 | 双击 | 按下按钮或导航 |
| 下一个 | 向右滑动 | 下一个元素 |
| 上一个 | 向左滑动 | 上一个元素 |
| 滚动 | 双指滑动 | 滚动列表 |
| TalkBack 菜单 | 向上-左滑动 | 全局设置菜单 |
“向上-左滑动” 手势(L 形滑动)打开 TalkBack 全局菜单,用户可以在其中更改语速、启用屏幕遮罩、启动教程或打开设置。TalkBack 还支持元素的上下文菜单:向上-右滑动打开当前元素的可用操作列表(例如,文本字段的 “复制”、“粘贴” 或聊天消息的 “删除”)。
Android 提供了丰富的 API 来配置无障碍功能。基础级别是 contentDescription,但要获得高质量的 TalkBack 支持,需要使用 AccessibilityNodeInfo、AccessibilityDelegate 和 LiveRegion。
android:contentDescription 属性设置元素对 TalkBack 的文本描述。对于 ImageView、ImageButton、FloatingActionButton 以及任何没有文本内容的自定义 View 是必需的。对于标准元素(TextView、Button),contentDescription 是可选的——TalkBack 会自动读取文本。
val avatarView = ImageView(this)
avatarView.contentDescription = "用户头像"
avatarView.importantForAccessibility =
IMPORTANT_FOR_ACCESSIBILITY_YES
val playButton = ImageButton(this)
playButton.contentDescription = "播放视频"
val progressBar = ProgressBar(this)
progressBar.importantForAccessibility =
IMPORTANT_FOR_ACCESSIBILITY_NO
importantForAccessibility 标志控制元素对 TalkBack 的可见性。值 NO 将元素从无障碍树中隐藏——适用于装饰性图像、指示器和自定义背景。值 YES 强制将元素包含在遍历中,即使它没有文本。重要的是不要滥用 NO:隐藏语义上重要的元素会使应用程序对 TalkBack 用户不可访问。
对于不使用标准点击处理程序的自定义 View,需要重写 AccessibilityDelegate —— 处理无障碍事件的类。委托允许设置自定义描述、元素类型和可用操作列表,TalkBack 将通过上下文菜单提供给用户。
class CustomButtonDelegate : View.AccessibilityDelegate() {
override fun onInitializeAccessibilityNodeInfo(
host: View, info: AccessibilityNodeInfoCompat
) {
super.onInitializeAccessibilityNodeInfo(host, info)
info.text = "自定义按钮"
info.className = Button::class.java.name
info.addAction(
AccessibilityNodeInfoCompat.AccessibilityActionCompat(
R.id.custom_action, "分享"
)
)
}
override fun performAccessibilityAction(
host: View, action: Int, args: Bundle?
): Boolean {
if (action == R.id.custom_action) {
shareContent()
return true
}
return super.performAccessibilityAction(host, action, args)
}
}
在示例中,委托告诉 TalkBack 该元素是一个按钮(className = Button),并提供将出现在 TalkBack 上下文菜单中的自定义操作 “分享”。performAccessibilityAction 方法处理此操作的调用。如果没有委托,TalkBack 会将自定义 View 视为没有交互性的简单区域,用户将无法与之交互。
全面的 TalkBack 支持不仅包括 contentDescription,还包括焦点管理、用于动态更新的 LiveRegion、使用启用的屏幕朗读器进行测试以及适应不同版本的 Android。
当屏幕内容在没有用户明确操作的情况下发生变化(例如,出现新消息通知或点赞计数器更新),TalkBack 应收到通知。为此,在 XML 中使用 View 的 android:accessibilityLiveRegion 属性或在代码中使用 setAccessibilityLiveRegion() 方法。值 polite 在当前朗读完成后添加公告,而值 assertive 则立即中断它。
val statusText = TextView(this)
statusText.accessibilityLiveRegion =
View.ACCESSIBILITY_LIVE_REGION_POLITE
// 文本更新时,TalkBack 将自动
// 宣布更改
statusText.text = "安娜的新消息"
// 对于关键通知 — assertive
errorBanner.accessibilityLiveRegion =
View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE
LiveRegion — 是 iOS 上 UIAccessibility.post 的对应物。大多数更新使用 polite(新消息、状态更新),只有关键错误使用 assertive(支付失败、连接丢失)。过度使用 assertive 会创建负面的用户体验——TalkBack 会不断中断当前的朗读。
对于多个 View 形成一个逻辑单元的复杂屏幕,使用 AccessibilityNodeProvider 或 focusSearch 来覆盖导航。例如,具有 42 个单元格的自定义日历(6 周 × 7 天)不应该强迫用户遍历所有 42 个元素才能进入下一个块。开发者可以将单元格合并为逻辑组:月 → 周 → 日。
对于 Jetpack Compose,使用 .semantics {} 修饰符,它提供类似的 API:contentDescription、liveRegion、stateDescription、disabled 和 customActions。Compose 还支持 mergeDescendants 用于将子语义合并为一个,这简化了元素的分组,无需为每个 View 手动配置 accessibilityDelegate。
Button(
onClick = { sendMessage() },
modifier = Modifier.semantics {
contentDescription("发送消息")
stateDescription("准备发送")
}
) {
Icon(Icons.Filled.Send, "发送")
}
TalkBack 的测试通过物理设备或启用了服务的模拟器进行。建议在屏幕关闭(Screen Curtain)的情况下完成关键用户场景——这模拟了完全没有视觉反馈的情况。Android 还提供 Accessibility Scanner——一个用于自动检测无障碍问题的工具,它突出显示没有 contentDescription 的元素、过小的触摸区域和低对比度。
常见问题
设置 → 无障碍 → TalkBack → 启用。快速启用方法是同时按下两个音量键 3 秒钟。Google Assistant 也可以通过语音命令 “打开 TalkBack” 来启用 TalkBack。
TalkBack 是 Android 的屏幕朗读器,VoiceOver 是 iOS 的。TalkBack 使用 AccessibilityService 和带有黄色边框的无障碍焦点,而 VoiceOver 使用 UIAccessibility 和转子。手势和菜单不同:TalkBack 有用于全局菜单的 L 形滑动。
为所有 ImageView 和自定义元素设置 contentDescription。使用 importantForAccessibility 隐藏装饰性元素。为动态更新配置 accessibilityLiveRegion 并通过 Accessibility Scanner 检查。在 Compose 中应用 .semantics{} 修饰符。
它是一个表示无障碍树中界面元素的对象。包含文本、类型、状态、位置和操作列表。TalkBack 遍历此树进行导航。开发者可以通过 AccessibilityDelegate 或 XML 中的属性更改它。
检查 importantForAccessibility —— 可能设置为 NO。确保为没有文本的元素设置了 contentDescription。对于自定义 View,使用 onInitializeAccessibilityNodeInfo 实现 AccessibilityDelegate。使用 Accessibility Scanner 进行诊断。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。