本指南提供 Android TV 無障礙功能的最佳做法,並針對原生和非原生應用程式提供建議。
為何無障礙服務對我的 TV 應用程式如此重要?
在電視觀看人數中,視覺障礙並不常見。 世界衛生組織 (WHO) 的資料指出,全球約有 22 億人有視力障礙。根據 2018 年國家健康訪談問卷調查,在美國,3,200 萬名 18 歲以上的美國人曾經歷重大的視力損失。根據歐洲盲議會 (EBU) 的預測,歐洲地區估計達到 3,000 萬名失明及部分視障人士。
最重要的是,視障人士喜歡的媒體內容 與完全視障者一樣重要。Comcast 委託 2017 進行的一項問卷調查顯示,96% 失明或低視能使用者經常觀看電視,且每天觀看超過 1 小時超過 1 小時。但有 65% 的人表示查詢電視內容時有問題。在英國的 2020 年問卷調查中,80% 的身心障礙人士表示隨選影片串流服務有無障礙功能方面的問題。
雖然輔助技術可幫助低視能使用者提供協助,但在 TV 應用程式的內容探索歷程中,支援無障礙功能還是很重要。舉例來說,請特別留意提供導航指引和適當的元素標籤,並確保 TV 應用程式能和 TalkBack 等無障礙功能順利搭配運作。這些步驟可大幅提升視障使用者的體驗。
提升無障礙體驗的第一步是提升知名度。本指南可協助您和團隊找出 TV 應用程式的無障礙功能問題。
Android 無障礙資源
如要進一步瞭解 Android 的無障礙工具,請參閱無障礙開發資源。
文字縮放
Android TV 應用程式應支援不同的像素密度,以尊重使用者偏好的文字縮放方式。
請特別留意以下幾點:
- 針對 UI 元件中的維度使用
wrap_content
。 - 確保版面配置會隨著文字縮放比例改變,重新排列元件。
- 確保使用較大的文字時,元件仍可在畫面上清楚顯示。
- 請勿使用 sp 文字大小單位做為無法彈性的元件。
檢查
FONT_SCALE
的值以調整自訂檢視中的調整項:// Checking font scale with Context val scale = resources.configuration.fontScale Log.d(TAG, "Text scale is: " + scale)
文字比例可以透過下列指令變更:
adb shell settings put system font_scale 1.2f
在 Android 12 以上版本中,使用者可以透過裝置設定變更文字縮放。
鍵盤配置
在 Android 13 (API 級別 33) 以上版本中,您可以使用 getKeyCodeForKeyLocation()
查詢預期金鑰位置的按鍵碼。如果使用者已重新對應某些重要位置,或使用沒有一般版面配置的鍵盤,就可能需要這個狀態。
口述影像
在 Android 13 (API 級別 33) 以上版本中,新的系統通用無障礙偏好設定可讓使用者在所有應用程式中啟用口述影像。Android TV 應用程式可以使用 isAudioDescriptionRequested()
查詢使用者偏好設定,藉此確認使用者的偏好。
Kotlin
private lateinit var accessibilityManager: AccessibilityManager // In onCreate(): accessibilityManager = getSystemService(AccessibilityManager::class.java) // Where your media player is initialized if (am.isAudioDescriptionRequested) { // User has requested to enable audio descriptions }
Java
private AccessibilityManager accessibilityManager; // In onCreate(): accessibilityManager = getSystemService(AccessibilityManager.class); // Where your media player is initialized if(accessibilityManager.isAudioDescriptionRequested()) { // User has requested to enable audio descriptions }
透過在 AccessbilityManager
中加入事件監聽器,Android TV 應用程式可以監控使用者偏好設定何時變更:
Kotlin
private val listener = AccessibilityManager.AudioDescriptionRequestedChangeListener { enabled -> // Preference changed; reflect its state in your media player } override fun onStart() { super.onStart() accessibilityManager.addAudioDescriptionRequestedChangeListener(mainExecutor, listener) } override fun onStop() { super.onStop() accessibilityManager.removeAudioDescriptionRequestedChangeListener(listener) }
Java
private AccessibilityManager.AudioDescriptionRequestedChangeListener listener = enabled -> { // Preference changed; reflect its state in your media player }; @Override protected void onStart() { super.onStart(); accessibilityManager.addAudioDescriptionRequestedChangeListener(getMainExecutor(), listener); } @Override protected void onStop() { super.onStop(); accessibilityManager.removeAudioDescriptionRequestedChangeListener(listener); }