Android TV의 맞춤 뷰 접근성 지원

많은 Android TV 앱이 기본 Android 구성요소로 빌드되지만 서드 파티 프레임워크 또는 구성요소의 접근성도 고려하는 것이 중요합니다. 특히 맞춤 뷰를 사용하는 경우에 그렇습니다.

OpenGL 또는 Canvas와 직접 상호작용하는 맞춤 뷰 구성요소는 TalkBack 및 스위치 제어와 같은 접근성 서비스와 잘 작동하지 않을 수 있습니다.

TalkBack이 사용 설정된 상태에서 발생할 수 있는 다음 문제를 고려하세요.

  • 접근성 포커스 (녹색 직사각형)가 앱에서 사라질 수 있습니다.
  • 접근성 포커스가 전체 화면의 경계를 선택할 수 있습니다.
  • 접근성 포커스를 이동할 수 없을 수 있습니다.
  • 코드가 D패드 방향 키를 처리하더라도 D패드의 4방향 키가 아무런 영향을 미치지 않을 수 있습니다.

앱에서 이러한 문제가 관찰되면 앱이 AccessibilityNodeInfo 트리를 접근성 서비스에 노출하는지 확인하세요.

이 가이드의 나머지 부분에서는 이러한 문제를 해결하기 위한 몇 가지 솔루션과 권장사항을 제공합니다.

D패드 이벤트는 접근성 서비스에서 사용됩니다.

이 문제의 근본 원인은 키 이벤트가 접근성 서비스에서 사용되기 때문입니다.

Dpad 이벤트 소비 및 Talkback
그림 1. TalkBack이 사용 설정 및 사용 중지된 상태에서 시스템이 작동하는 방식을 보여주는 다이어그램

그림 1에 나와 있듯이 TalkBack이 사용 설정되면 D패드 이벤트가 개발자가 정의한 D패드 핸들러에 전달되지 않습니다. 대신 접근성 서비스는 접근성 포커스를 이동할 수 있도록 키 이벤트를 수신합니다. 맞춤 Android 구성요소는 기본적으로 화면에서의 위치에 관한 정보를 접근성 서비스에 노출하지 않으므로 접근성 서비스는 접근성 포커스를 이동하여 강조표시할 수 없습니다.

다른 접근성 서비스도 마찬가지로 영향을 받습니다. 스위치 제어를 사용할 때 D패드 이벤트가 사용될 수도 있습니다.

D패드 이벤트가 접근성 서비스에 제출되고 서비스가 맞춤 뷰에서 UI 구성요소가 있는 위치를 알지 못하므로 앱이 키 이벤트를 올바르게 전달하려면 AccessibilityNodeInfo를 구현해야 합니다.

접근성 서비스에 정보 노출

맞춤 뷰의 위치 와 설명에 관한 충분한 정보를 접근성 서비스에 제공하려면 AccessibilityNodeInfo를 구현하여 각 구성요소의 세부정보를 노출하세요. 접근성 서비스가 포커스를 관리할 수 있도록 뷰의 논리적 관계를 정의하려면 ExploreByTouchHelper를 구현하고 맞춤 뷰에 ViewCompat.setAccessibilityDelegate(View, AccessibilityDelegateCompat) 를 사용하여 설정하세요.

ExploreByTouchHelper를 구현할 때는 추상 메서드 4개를 재정의합니다.

Kotlin

// Return the virtual view ID whose view is covered by the input point (x, y).
protected fun getVirtualViewAt(x: Float, y: Float): Int

// Fill the virtual view ID list into the input parameter virtualViewIds.
protected fun getVisibleVirtualViews(virtualViewIds: List<Int>)

// For the view whose virtualViewId is the input virtualViewId, populate the
// accessibility node information into the AccessibilityNodeInfoCompat parameter.
protected fun onPopulateNodeForVirtualView(virtualViewId: Int, @NonNull node: AccessibilityNodeInfoCompat)

// Set the accessibility handling when perform action.
protected fun onPerformActionForVirtualView(virtualViewId: Int, action: Int, @Nullable arguments: Bundle): Boolean

자바

// Return the virtual view ID whose view is covered by the input point (x, y).
protected int getVirtualViewAt(float x, float y)

// Fill the virtual view ID list into the input parameter virtualViewIds.
protected void getVisibleVirtualViews(List<Integer> virtualViewIds)

// For the view whose virtualViewId is the input virtualViewId, populate the
// accessibility node information into the AccessibilityNodeInfoCompat parameter.
protected void onPopulateNodeForVirtualView(int virtualViewId, @NonNull AccessibilityNodeInfoCompat node)

// Set the accessibility handling when perform action.
protected boolean onPerformActionForVirtualView(int virtualViewId, int action, @Nullable Bundle arguments)

자세한 내용은 Google I/O 2013 - Android에서 시각장애인 접근성 사용 설정 동영상을 시청하거나 접근성 이벤트 채우기에 관해 자세히 알아보세요.

권장사항

샘플

맞춤 뷰를 사용하는 앱에 접근성 지원을 추가하는 권장사항을 알아보려면 Android TV용 맞춤 뷰 접근성 샘플을 참고하세요.