사전 TalkBack
구현체

TalkBack

gabury1고친 사람 github-actions[bot]

TalkBack 은 Android 휴대폰의 화면을 소리로 읽어 줍니다. 눈이 안 보이는 사용자는 이것을 켜고 손가락 동작만으로 앱을 씁니다. Google 이 만들어 대부분의 Android 기기에 기본으로 들어 있습니다.

쉽고 빠른 이해

무슨 일을 하는 물건인가 — 화면에 있는 버튼과 글자를 하나씩 소리 내어 읽어 줍니다. 손가락이 공유 아이콘에 닿으면 「공유 버튼」이라고 말합니다.

왜 이렇게 하나 — 화면을 못 보는 사람에게 터치 화면은 아무 표시 없는 유리판입니다. 무엇이 어디 있는지 소리로 듣지 못하면 앱을 하나도 쓸 수 없습니다.

어떻게 도나

  1. 한 번 누르면 실행하지 않고 그 부품을 골라 읽어 줍니다
  2. 화면을 옆으로 쓸면 다음 부품으로 넘어가 읽습니다
  3. 두 번 누르면 방금 고른 부품을 실행합니다

대가 — 앱이 부품마다 이름을 달아 두어야 읽을 수 있습니다. 글자 없는 아이콘에 이름이 빠지면 사용자는 「버튼」이라는 소리만 듣습니다.

상세

Android 휴대폰에 기본으로 들어 있는 스크린 리더가 TalkBack 입니다. 스크린 리더는 화면에 그려진 글자와 부품을 소리로 바꿔 읽어 주는 프로그램입니다. 화면을 못 보는 사람은 이 소리를 듣고 기기를 씁니다. 아이폰에서는 VoiceOver 가 같은 일을 합니다.

접근성은 눈이나 손이 불편한 사람도 기기와 앱을 쓸 수 있게 만드는 일입니다. TalkBack 은 Android 접근성 기능의 대표 격입니다.

이 절은 사용자의 손동작이 어떻게 바뀌는지부터 봅니다. 다음으로 TalkBack 이 남의 앱 화면을 어떻게 읽어 내는지 봅니다. 마지막으로 앱 개발자와 백엔드 개발자가 무엇을 챙겨야 읽히는 화면이 되는지 봅니다.

한 번 누름과 두 번 누름

TalkBack 을 켜면 터치 화면의 규칙이 바뀝니다. 평소에는 버튼을 한 번 누르면 바로 실행됩니다. 화면이 안 보이는 사람에게 이 규칙은 위험합니다. 무엇인지 모르는 버튼을 손이 닿자마자 눌러 버리기 때문입니다.

그래서 TalkBack 은 고르기와 실행을 둘로 나눕니다. 한 번 누르면 손가락 밑의 부품을 고르고 그 이름을 읽어 줍니다. 실행은 두 번 눌러야 일어납니다.

지금 골라 둔 부품을 접근성 포커스라고 부릅니다. TalkBack 은 이 부품 둘레에 테두리를 그려 옆 사람도 알아보게 합니다. 두 번 누르기는 화면 어디를 눌러도 포커스가 놓인 부품을 실행합니다. 작은 버튼을 다시 찾아 정확히 누를 필요가 없습니다.

다른 손동작도 함께 바뀝니다. 자주 쓰는 것만 추리면 아래와 같습니다.

손동작 TalkBack 이 켜졌을 때
한 번 누르기 손가락 밑 부품을 고르고 읽는다
손가락을 댄 채 끌기 손가락이 지나가는 부품을 차례로 읽는다
오른쪽으로 쓸기 다음 부품으로 포커스를 옮기고 읽는다
왼쪽으로 쓸기 이전 부품으로 포커스를 옮기고 읽는다
두 번 누르기 포커스가 놓인 부품을 실행한다
두 손가락으로 쓸기 화면을 스크롤한다

쓸기로 옮겨 다니면 화면 구조를 몰라도 처음부터 끝까지 빠짐없이 훑을 수 있습니다. 대신 부품이 서른 개인 화면은 서른 번을 쓸어야 끝납니다. TalkBack 이 쓸기 한 번에 읽을 묶음을 앱이 잘 짜 두어야 하는 까닭입니다. 묶는 법은 아래 「부품에 이름 달기」 절에서 봅니다.

접근성 서비스라는 통로

TalkBack 은 홈 화면부터 다른 회사가 만든 앱까지 휴대폰의 모든 화면을 읽습니다. 그런데 보통의 Android 앱은 다른 앱의 화면을 들여다볼 수 없습니다. 앱끼리 서로의 화면을 엿보면 비밀번호나 메시지가 새기 때문입니다.

Android 는 이 벽에 문을 하나 냅니다. 접근성 서비스는 다른 앱의 화면 내용을 받아 보고 대신 누를 수 있게 운영체제가 허락한 앱입니다. TalkBack 이 바로 이 접근성 서비스로 만들어져 있습니다. 같은 통로를 쓰는 다른 접근성 서비스로는 스위치 하나로 휴대폰을 조작하게 해 주는 스위치 제어가 있습니다.

권한이 큰 만큼 켜는 절차가 따로 있습니다. 사용자가 설정의 접근성 메뉴에 들어가 직접 켜야 합니다. 켤 때는 이 앱이 화면을 읽고 조작할 수 있다는 경고가 뜹니다.

노드를 읽어 소리로

Android 앱의 화면은 부품이 부품을 품는 나무 모양으로 짜여 있습니다. 목록 안에 줄이 있습니다. 줄 안에는 사진과 글자와 버튼이 들어 있습니다.

Android 는 이 나무에서 TalkBack 이 쓸 정보만 뽑아 넘깁니다. 이렇게 뽑은 부품 하나하나를 접근성 노드라고 부릅니다.

노드에는 그 부품의 역할과 이름, 상태, 할 수 있는 동작이 담깁니다. 공유 아이콘 버튼이라면 역할은 버튼, 이름은 「공유」, 할 수 있는 동작은 누르기입니다. 체크박스라면 「선택됨」 같은 상태가 더 붙습니다.

노드도 원래 화면처럼 부품이 부품을 품는 나무 모양으로 이어집니다. 이 노드의 나무를 접근성 트리라고 부릅니다.

TalkBack 은 소리를 직접 만들지 않습니다. 노드에서 읽을 문장을 만들어 음성 합성 엔진에 넘깁니다. 음성 합성 엔진은 글자를 사람 목소리로 바꿔 주는 프로그램입니다. 엔진은 설정에서 고르므로 목소리를 바꿔도 TalkBack 쪽은 손댈 것이 없습니다.

실행은 같은 통로를 거꾸로 지납니다. 사용자가 두 번 누르면 TalkBack 이 Android 에게 포커스가 놓인 노드를 눌러 달라고 요청합니다. 앱은 이 요청을 평소의 버튼 누름과 똑같이 받습니다. 그래서 앱 코드 대부분은 TalkBack 이 켜져 있는지 몰라도 됩니다.

화면이 바뀔 때도 Android 가 먼저 알립니다. 새 화면이 열리거나 글자가 바뀌면 접근성 서비스에게 그 소식이 갑니다. TalkBack 은 이 알림을 받고 바뀐 내용을 읽습니다.

공유 버튼 하나를 고르고 누르기까지를 순서대로 그리면 이렇습니다.

sequenceDiagram
    participant 사용자
    participant TalkBack
    participant Android
    participant 앱
    participant 엔진 as 음성 합성 엔진
    Note over 앱: 공유 버튼에 이름 「공유」를 달아 둔다
    사용자->>TalkBack: 오른쪽으로 쓸기
    TalkBack->>Android: 다음 노드를 묻는다
    Android-->>TalkBack: 역할 버튼 · 이름 공유
    TalkBack->>엔진: 「공유 버튼」
    엔진-->>사용자: 소리로 읽는다
    사용자->>TalkBack: 두 번 누르기
    TalkBack->>Android: 이 노드를 눌러 달라
    Android->>앱: 평소의 버튼 누름으로 전한다

앱 쪽에서 보면 쓸기부터 소리로 읽기까지는 할 일이 없습니다. 앱이 하는 일은 노드에 이름을 제대로 달아 두는 것과 마지막 누름을 받는 것뿐입니다. 그래서 TalkBack 이 잘 읽느냐는 대부분 이름 달기에 달려 있습니다.

부품에 이름 달기

TalkBack 은 노드에 담긴 것만 읽을 수 있습니다. 글자가 적힌 버튼은 그 글자가 이름이 됩니다. 걸리는 것은 글자 없이 그림만 있는 아이콘 버튼입니다.

아이콘 버튼에 이름이 빠지면 TalkBack 은 「버튼」 정도만 말합니다. 사용자는 그것이 공유인지 삭제인지 모른 채 눌러 봐야 합니다. 이를 막으려면 개발자가 아이콘에 이름을 직접 달아 줘야 합니다.

Android 화면을 짜는 방식은 둘입니다. 오래된 방식은 XML(Extensible Markup Language) 파일에 부품을 적습니다. 이때 이름은 contentDescription 속성에 넣습니다.

다른 방식은 Jetpack Compose 입니다. 화면을 코틀린 함수로 짜는 Android 의 도구입니다. 여기서도 이름은 contentDescription 인자로 넘깁니다. 아래는 Compose 로 짠 공유 버튼입니다. 오른쪽 주석이 TalkBack 이 읽는 말입니다.

Kotlin
IconButton(onClick = { share() }) {
  Icon(
    imageVector = Icons.Default.Share,
    contentDescription = "공유" // 공유 버튼
  )
}

IconButton 이 역할을 버튼으로 정합니다. contentDescription 은 이름을 정합니다. TalkBack 은 이름 뒤에 역할을 붙여 읽습니다.

반대로 읽지 말아야 할 그림도 있습니다. 배경 무늬처럼 꾸미기만 하는 그림에 포커스가 멈추면 사용자는 쓸기 한 번을 헛되게 씁니다. 이런 그림은 이름을 null 로 비워 TalkBack 이 건너뛰게 합니다.

Kotlin
Image(
  painter = painterResource(R.drawable.bg),
  contentDescription = null // 건너뜀
)

부품을 묶는 일도 개발자 몫입니다. 메시지 목록의 한 줄에 보낸 사람, 미리보기 글, 시각이 각각 있으면 TalkBack 은 셋에 하나씩 멈춰 읽습니다. 줄 전체를 한 노드로 묶어 두면 쓸기 한 번에 「김철수, 내일 봬요, 오후 세 시」를 한꺼번에 읽습니다.

직접 칠한 화면

TalkBack 이 못 읽는 화면도 있습니다. 차트나 게임처럼 앱이 부품을 쓰지 않고 화면에 선과 색을 직접 칠한 경우입니다. 이런 화면은 Android 가 보기에 그림 한 장이라 노드가 하나뿐입니다.

이때는 앱이 눈에 안 보이는 노드를 직접 만들어 넘겨야 합니다. 막대그래프라면 막대마다 「3월 매출」 같은 이름을 단 노드를 하나씩 세웁니다. 품이 많이 들어 빠뜨리기 쉬운 대목입니다.

웹 페이지와 서버가 내려주는 글

TalkBack 은 앱만 읽지 않습니다. Chrome 같은 브라우저와 앱 안에 웹 페이지를 띄우는 웹뷰도 읽습니다. 브라우저가 HTML(HyperText Markup Language) 문서로 접근성 트리를 세웁니다. TalkBack 은 그 트리를 받아 읽습니다.

그래서 서버가 내려보내는 HTML 이 그대로 TalkBack 이 읽을 내용이 됩니다. 클릭을 받는 요소를 div 로 만들면 TalkBack 은 그것이 버튼인 줄 모릅니다. button 태그를 쓰거나 ARIA(Accessible Rich Internet Applications) 속성으로 역할과 이름을 적어야 버튼으로 읽힙니다.

이미지도 같습니다. HTML 의 이미지 태그에는 그림을 글로 옮긴 이름을 적는 alt 속성이 있습니다. TalkBack 은 이 글을 읽습니다. 앱의 contentDescription 과 같은 몫입니다.

서버 응답도 마찬가지입니다. 서버가 상품 사진의 주소만 응답에 실으면 앱도 웹도 그 사진에 붙일 이름이 없습니다. 사진마다 짧은 이름을 응답에 함께 실어야 화면이 그 이름을 읽힐 수 있습니다.

개발자가 켜 보는 법

앱이 제대로 읽히는지는 개발자가 직접 TalkBack 을 켜고 써 보면 압니다. 설정의 접근성 메뉴에서 켭니다. 그다음 화면을 보지 않은 채 쓸기와 두 번 누르기만으로 주요 기능을 끝까지 써 봅니다.

켜 둔 채로는 한 번 눌러도 실행이 안 되어 설정 메뉴로 돌아가는 일부터 번거롭습니다. 접근성 단축키를 켜 두면 볼륨 키 두 개를 함께 길게 눌러 TalkBack 을 켜고 끌 수 있습니다.

관련 항목

TalkBack 이 속하는 보조 기술 분류

스크린 리더 · 접근성 · 보조 기술 · 접근성 서비스

TalkBack 과 같은 일을 하는 다른 스크린 리더

VoiceOver · NVDA · JAWS · Narrator · Orca · ChromeVox

TalkBack 이 읽어 내는 화면 정보

접근성 트리 · 접근성 노드 · 접근성 이벤트 · contentDescription · 시맨틱스

TalkBack 사용자의 조작 방식

터치 탐색 · 접근성 포커스 · 접근성 단축키 · 제스처 · 점자 디스플레이

TalkBack 이 기대는 Android 부품

Android · 음성 합성 · Jetpack Compose · 웹뷰 · Chrome

TalkBack 과 다른 불편을 돕는 Android 보조 기능

스위치 제어 · 화면 확대 · 음성 제어 · 실시간 자막

TalkBack 이 읽게 만드는 웹 기술

HTML · 시맨틱 마크업 · ARIA · aria-label · alt 속성 · 대체 텍스트 · WCAG

다른 이름: talkback · 토크백 · Android TalkBack