Fire OSにユーザー補助機能を実装する方法
このページでは、Fire OSのユーザー補助機能の実装に関連する概念と用語について説明します。
- Fire OSのユーザー補助機能オブジェクトおよびイベントの概要
- ユーザー補助機能イベントの伝達経路
- ビューの重要度の設定
- AccessibilityNodeInfoオブジェクトの管理
- 仮想的にアクセス可能な子孫の実装
- Fire OSのユーザー補助機能に関するベストプラクティス
- 関連リソース
Fire OSのユーザー補助機能オブジェクトおよびイベントの概要
このセクションでは、アプリにユーザー補助機能を実装するときに使用するオブジェクトやイベントに関する用語とそれらの定義を紹介します。
AccessibilityEvent
AccessibilityEvent
は、UIを使って操作が行われたことを表す、アプリからユーザー補助機能へのメッセージです。ユーザー補助機能イベントをトリガーするUIの変化には、フォーカスの変化、ウィンドウの表示や非表示、画面上のオブジェクトの位置の変化などがあります。
AndroidドキュメントのAccessibilityEvent
を参照してください。
AccessibilityNodeInfo
AccessibilityNodeInfo
は、画面上のコンポーネントに関するユーザー補助機能情報のスナップショットです。ほとんどの場合、アプリからユーザー補助機能への一方向の通信です。ごくまれですが、ユーザー補助機能アクションを介してユーザー補助機能からアプリに情報が返されることもあります。
アプリによってAccessibilityNodeInfo
が作成されて返されると、そのノードでそれ以降行われる変更は、ユーザー補助機能とユーザー補助フレームワークによって認識されないため、その時点でノードを破棄できます。ノードで表される基礎オブジェクトが変更された場合は、その変更を示す適切なユーザー補助機能イベントを送信してください。その際、createAccessibilityNodeInfo
またはonInitializeAccessibilityNodeInfo
の次回の呼び出しで返されるノードに、基礎オブジェクトの特性の更新内容を反映してください。
アプリでは、サーバー側でのノードの参照に、Androidビューと仮想子孫番号を組み合わせて使用してください。ノードがビュー自体を表している場合、仮想子孫番号は-1 (AccessibilityNodeProvider.HOST_VIEW_ID)
になります。
アプリでは、AccessibilityNodeInfo
オブジェクトに関する説明情報をそのオブジェクトのgetExtras
Bundleに追加できます。VoiceViewは、AccessibilityNodeInfo.getExtras()を呼び出して、この情報を読み取ることができます。
AndroidドキュメントのAccessibilityNodeInfo
を参照してください。
AccessibilityNodeProvider
AccessibilityNodeProvider
は、あるビューの、またはあるビューの仮想的にアクセス可能な子孫のAccessibilityNodeInfo
を作成するインターフェイスです。
AndroidドキュメントのAccessibilityNodeProvider
を参照してください。
AccessibilityDelegate
AccessibilityDelegate
は、ユーザー補助機能イベント、ビューのノード、または仮想的にアクセス可能な子孫を初期化できるインターフェイスです。AccessibilityDelegates
を使用すると、あるビューのユーザー補助機能情報を別のビューで代替や補完として利用することができます。たとえば、親リストでリスト項目のユーザー補助機能情報を提供できます。
AndroidドキュメントのAccessibilityDelegate
を参照してください。
ユーザー補助機能イベントの伝達経路
このセクションでは、標準ビューおよびカスタムビューのユーザー補助機能イベントの伝達経路について説明します。
標準ビュー
Fire OSアプリのユーザーインターフェイスを構成する視覚的要素をビューと呼びます。たとえば、1つのテキスト要素TextView
に「hello world」というテキストが表示されている簡単なアプリがあるとします。このとき、TextView
はRelativeLayout
の子であるとします。RelativeLayout
は、常にアプリのビュー階層のルートとなるクラスViewRootImpl
の子です。TextView
は標準のAndroidビューであるため、TextView
は、デフォルトの動作として、VoiceView実行時に適切なユーザー補助機能イベントを送信します。
次のプロセスは、この簡単なアプリ内で作成されたユーザー補助機能イベントの伝達経路を示します。
- アプリが開かれてから数秒後に、アプリのコードが
textView.setText("new text")
を呼び出します。 TextView
がTYPE_WINDOW_CONTENT_CHANGED
というAccessibilityEvent
を作成し、このイベントを送信するよう親のRelativeLayout
に要求します。RelativeLayout
がイベントを親のViewRootImpl
に渡し、フレームワークに送信するよう要求します。ViewRootImpl
が、AccessibilityManager
のsendAccessibilityEvent()
を呼び出して、イベントをユーザー補助機能フレームワークに送信します。AccessibilityManager
がイベントをAccessibilityManagerService
に渡し、AccessibilityManagerServiceはユーザー補助機能フレームワークからVoiceViewにイベントを渡します。- VoiceViewは
TYPE_WINDOW_CONTENT_CHANGED AccessibilityEvent
を処理する際に、イベントオブジェクトのgetSource()
メソッドを呼び出します。 - 次に、ユーザー補助機能フレームワークが
TextViewのcreateAccessibilityNodeInfo()
メソッドを呼び出します。このメソッドは、「new text」というテキストが含まれたAccessibilityNodeInfo
オブジェクトを返します。 - ユーザー補助機能フレームワークが、
AccessibilityNodeInfo
オブジェクトをVoiceViewに返します。 - 最後に、
TextView
が「hello world」から「new text」に変更されたことを、VoiceViewが認識します。ユーザーがリニアナビゲーションを使用してTextView
のテキストを読み上げさせると、VoiceViewは「new text」を正しく読み上げます。
カスタムビュー
アプリで標準ビューの代わりにカスタムビューを使用する場合も、VoiceViewにウィジェットの状態を通知する上記のパターンを維持する必要があります。通知する際、AccessibilityNodeInfo
オブジェクトをVoiceViewに送信したり、アプリ内のAccessibilityNodeInfo
のローカルコピーを更新したりしないでください。これらの方法は機能しません。
カスタムウィジェットの状態を変更する場合は、以下の点に留意してください。
必須事項
- カスタムビューの親で
requestSendAccessibilityEvent()
を呼び出して、AccessibilityEvent
を送信します。 - カスタムビューの
createAccessibilityNodeInfo()
関数内で参照されている変数に、更新された値が含まれていることを確認してください。VoiceViewはAccessibilityEvent
を受け取ると、createAccessibilityNodeInfo()
を呼び出します。
禁止事項
- VoiceViewに
AccessibilityNodeInfo
を送信しないでください。 AccessibilityNodeInfo
オブジェクトへの参照がcreateAccessibilityNodeInfo()
関数に含まれていない状態で、このオブジェクトを更新しないでください。VoiceViewにはこのオブジェクトを参照する手段がないため、このオブジェクトの更新を認識できません。
Androidのドキュメントで、AccessibilityDelegate
クラスと、createAccessibilityNodeInfo()
関数が実装されているAccessibilityNodeProvider
クラスの正しい使用方法を示したコード例を確認してください。
ビューの重要度の設定
ユーザー補助機能イベントが適切に処理されるように、Androidビューごとにユーザー補助機能における重要度を設定してください。
ユーザー補助機能におけるビューの重要度は、XMLレイアウトでandroid:importantForAccessibility
属性を使用するか、プログラムでView.setImportantForAccessibility
メソッドを使用して設定します。設定できる値は、yes、no、no_hide_descendants
、auto
(デフォルト)です。重要と設定されていないビューには、対応するユーザー補助機能ノードが作成されません。また、そのビューから送信されたユーザー補助機能イベントは、フレームワークによって破棄されます。
ビューが適切なユーザー補助機能イベントを送信していても、VoiceViewが正しく応答していないと思われる場合は、ビューがユーザー補助機能にとって重要であると設定されているかどうかを確認してください。
AccessibilityNodeInfoオブジェクトの管理
Fire OSとAndroidのユーザー補助機能の重要な要素の1つは、AccessibilityNodeInfo
オブジェクトの管理です。アプリのプロセスで実行されるAndroidのユーザー補助機能フレームワークが特定のノードの要求を受け取ると、フレームワークはまずそのノードがキャッシュ内にあるかどうかを確認します。
- ノードがキャッシュに存在する場合はそれが返され、アプリでノードを作成する呼び出しは行われません。そのため、コンポーネントに関するユーザー補助機能情報が変更されるたびに、アプリはフレームワークとユーザー補助機能に通知する必要があります。通知しない場合、フレームワークは古い情報をユーザー補助機能に返します。
- ノードが変更されて無効になったことを示すには、
AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
タイプのユーザー補助機能イベントを送信します。 - ノードがまだキャッシュにない場合は、要求された方法に応じてノードが作成されます。ユーザー補助機能による次のアクションが
AccessibilityNodeInfo
オブジェクトの作成をトリガーできます。- ユーザー補助機能イベントを受け取り、そのソースを要求する。
- アクティブなウィンドウのルートノードを要求する。
- 特定のノードの親ノードまたは子ノードを要求する。
仮想的にアクセス可能な子孫の実装
このセクションでは、仮想的にアクセス可能な子孫ビューを実装する方法について説明します。
仮想的にアクセス可能な子孫ビューの作成
AccessibilityDelegate
とAccessibilityNodeProvider
はどちらも、基盤のビューで表現されない画面コンポーネントにユーザー補助機能を提供できます。このようなコンポーネントの例には、キーがキャンバス上に描画されるAOSPのオンスクリーンキーボードがあります。仮想ノードツリーを実装すると、Androidが提供するExploreByTouchHelper
サポートライブラリが期待どおりに動作しないことがあります。
アプリは、ノードをホストしているビューと仮想ビューIDを使用してAccessibilityNodeInfo
オブジェクトを参照します。仮想ビューIDが-1 (AccessibilityNodeProvider.HOST_VIEW_ID)
の場合は、ホストビュー自体が参照されます。ノードを作成する際に仮想子を追加するには、AccessibilityNodeInfo.addChild()
メソッドを使用し、ホストビューと、仮想子の仮想ビューIDを指定します。同様に、子ノードを作成する際に仮想親を設定するには、AccessibilityNodeInfo.setParent()
を呼び出してホストビューと仮想親の仮想ビューIDを指定します。
仮想的にアクセス可能な子孫ビューの管理
仮想ビューは、初回作成時にはそのIDのみで参照され、ユーザー補助機能情報(テキスト、コンテンツの説明など)は関連付けられていません。ユーザー補助機能フレームワークが適切なノードを作成するようアプリに要求すると、対応するユーザー補助機能情報がAccessibilityNodeInfo
に入力されます。そのため、どの仮想ビューIDがカスタムウィジェットのどの部分を表しているかをアプリが追跡するようにしてください。
子ノードまたは親ノードのIDを追加すると、フレームワークは実際にこれらのノードを作成するようアプリに要求します。コンテナノードに子ノードを追加しないでください。
Fire OSのユーザー補助機能に関するベストプラクティス
ユーザー補助機能が搭載されたアプリのユーザーエクスペリエンスを高めるには、次のガイドラインに従います。
- AccessibilityNodeInfoのテキスト:
AccessibilityNodeInfo
のテキストが、オブジェクトの画面上のテキストのみを返すようにしてください。 - 画面上のアイテムのラベル: 画面上の重要なアイテムには、すべてラベルを付けてください。VoiceViewをテストするときは、すべての画面上のアイテムをタッチして、適切な説明が読み上げられるかを確認してください。説明が欠けている場合は、適切なテキストやコンテンツの説明をアイテムの
AccessibilityNodeInfo
に追加する必要があります。 - コンテンツの説明: 画面上のテキストがないアイテムには、コンテンツの説明(画像の代替テキストなど)を使用してください。または、画面上のテキストを補完するために、追加の文脈情報をユーザーに提供することもできます。ただし、コンテンツの説明に大量の情報が表示されないようにしてください。
- ユーザー補助機能イベントの使用: 画面上のアクティビティを伝えるために、
AccessibilityEvent.TYPE_ANNOUNCEMENT
イベントタイプを使用しないでください。画面上の変化に関する情報を伝達する方法としては、ユーザー補助機能イベントと、それに対応するAccessibilityNodeInfo
への変更を組み合わせて使用することが推奨されます。