AndroidのBasic Android Accessibilityコードラボのメモ

アクセシビリティについて、少し触れる機会があったので、メモを残しておきます。

このコードラボです。
https://codelabs.developers.google.com/codelabs/basic-android-accessibility/#0

このコードラボの目的は以下

* 障害のある方がどのようにAndroidのアプリケーションを使うのかを学ぶ。
* TalkBackやAccessibility Scannerを使って、どのようにアクセシビリティのissueを確認、テスト、デバッグするのか
* アクセシビリティに対してどのようなAPIが使われるのか

## サンプルコード

https://github.com/googlecodelabs/basic-android-accessibility
のmasterがアクセシビリティができていない状態で、以下のブランチができている状態になっている
https://github.com/googlecodelabs/android-accessibility/tree/accessible



## 障害のある方がどのようにAndroidのアプリケーションを使うのか

### TalkBackを使う
TalkBackを使うことで聴覚、触覚、音声によるフィードバックを提供する。目を使わずにアプリを利用できる。

* TalkBackの有効化  
設定でTalkBackで検索して有効化できる。
有効化するとチュートリアルが始まるって使い方を学べる。

* TalkBackの無効化
音量の上げるボタンと下げるボタンを同時押しでできるメニューが出てくるみたいなんですが、できなかったので、GoogleアシスタントにTalkBackをオフしてとお願いしました。
他にも以下の2本指操作で普通に設定画面からオフにできます。

* TalkBack中にスワイプやクリックする
2本指で操作するとTalkBackでないときみたいに通常通りクリックできるので設定画面にたどり着けます。 (目が見えない方にもこの機能は半分ぐらい使われるみたいです。)

* 次の要素や前の要素にアクセスする。
左にスワイプまたは右にスワイプ

他にもたくさんのジェスチャーがあるようです。
https://support.google.com/accessibility/android/answer/6151827


## TalkBackやAccessibility Scannerを使って、どのようにアクセシビリティのissueを確認、テスト、デバッグするのか

TalkBackを使って確認する。例えば`contentDescription="@null"`にしていると "ラベルなし"と言われる。



## アクセシビリティに対してどのようなAPIが使われるのか

### ラベルをつける
基本的にxmlではandroid:contentDescription=""をつける、コードではsetContentDescriptionを使う。 EditTextではhintを使う。

ラベルをつけるためのベストプラクティス

* 内容を簡潔にする (点字の場合に40文字しか読むことができないため)
* コンテンツの説明にタップなどの言葉を使わない。ユーザーによっては画面に触れない場合がある。AccessibilityServiceがそこをサポートする。
* 最も意味的に重要な情報がコンテンツラベルの最初に来るようにする。

### コンテンツのグループ化

例えば一つずつ分かれてしまっていると、
「アーティスト」って読み上げられて、ユーザーが右にスワイプして、「ビートルズ」みたいになってしまって、すごく非効率な感じで読み上げが行われてしまいます。
読み上げさせたいスコープでViewGroupで囲って、そのViewGroupにforcusableをつけることで対応できるらしい。
(ただ、レイアウトが深くなるとAndroid的にはパフォーマンスが若干悪くなるので、一旦はラベルを付けることを優先で良いかも。)

### ライブリージョン
例えば、ラジオボタンがあって、下にあっているか表示されるときに、フォーカスだけでは、あっているみたいな表示がされても分からないですよね？そういうときに使えるのが、 `android:accessibilityLiveRegion` です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27388/8efbe79e-c2c8-d1a7-dd0a-82e8bf411f6a.png)


android:accessibilityLiveRegion="polite"のように指定し、politeとassertiveがあります。
android:accessibilityLiveRegionがViewに設定されていると、テキストが変わったタイミングで読み上げがされます。
assertiveは今読み上げようとしているキューの最初に割り込んで読み上げがされ、politeはキューに積まれます。
うざくなってしまうので、politeを基本的には使うと良いそうです。

### CustomViewへの対応
このコードラボでは触れられないが、いくつかのAPIへの紹介がありました。
AccessibilityNodeProvider classを使って`virtual view hierarchy`を提供できる。
ExploreByTouchHelperでいくつものコレクションがある場合に、アクセシビリティサービスに情報を提供し、フォーカスを指定するのに役立つ。
AccessibilityDelegate classはViewにセットすることができ、互換性を保つことができるそうです。

## タッチエリアを広くする
指が大きかったり、運動能力の症状があったりするので、大きくしたほうがよい。48dp以上だと良い。
Settings > System > Developer Optionsで `Show layout bounds`でデバッグする
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27388/7d3beade-8241-5ac0-5e04-7cbf6c15641b.png" width="320px" />
https://codelabs.developers.google.com/codelabs/basic-android-accessibility/#9 より

単純に大きさをpaddingなどで変えるか、[TouchDelegate API](https://developer.android.com/reference/android/view/TouchDelegate.html)を使う。

## コントラストの確保
コントラスト比が低いと一部のユーザーにとってぼやけて表示されてしまう。
[Web Content Accessibility Guidelines](https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html) では4.5:1がテキストに対して最低限必要で、3.0:1で大きい文字や太い文字に対して必要となっている。
比率は以下でみられる。 (luma符号化して、割り算して割合を出すみたい。)
https://webaim.org/resources/contrastchecker/

Accessibility Scannerを使っても確認できる。

## Accessibility Scanner
このアプリを入れることで、コントラストや文字の大きさなどを確認できる。
https://play.google.com/store/apps/details?id=com.google.android.apps.accessibility.auditor
ただ、これだけだと手動テストの代わりにはならないので、talkbackを使ってちゃんと確認しましょうと書いてありました。