開発者コンソール

Fire OSにユーザー補助機能を実装する方法

Fire OSにユーザー補助機能を実装する方法

このページでは、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」というテキストが表示されている簡単なアプリがあるとします。このとき、TextViewRelativeLayoutの子であるとします。RelativeLayoutは、常にアプリのビュー階層のルートとなるクラスViewRootImplの子です。TextViewは標準のAndroidビューであるため、TextViewは、デフォルトの動作として、VoiceView実行時に適切なユーザー補助機能イベントを送信します。

次のプロセスは、この簡単なアプリ内で作成されたユーザー補助機能イベントの伝達経路を示します。 

  1. アプリが開かれてから数秒後に、アプリのコードがtextView.setText("new text")を呼び出します。
  2. TextViewTYPE_WINDOW_CONTENT_CHANGEDというAccessibilityEventを作成し、このイベントを送信するよう親のRelativeLayoutに要求します。
  3. RelativeLayoutがイベントを親のViewRootImplに渡し、フレームワークに送信するよう要求します。
  4. ViewRootImplが、AccessibilityManagersendAccessibilityEvent()を呼び出して、イベントをユーザー補助機能フレームワークに送信します。
  5. AccessibilityManagerがイベントをAccessibilityManagerServiceに渡し、AccessibilityManagerServiceはユーザー補助機能フレームワークからVoiceViewにイベントを渡します。
  6. VoiceViewはTYPE_WINDOW_CONTENT_CHANGED AccessibilityEventを処理する際に、イベントオブジェクトのgetSource()メソッドを呼び出します。
  7. 次に、ユーザー補助機能フレームワークがTextViewのcreateAccessibilityNodeInfo()メソッドを呼び出します。このメソッドは、「new text」というテキストが含まれたAccessibilityNodeInfoオブジェクトを返します。
  8. ユーザー補助機能フレームワークが、AccessibilityNodeInfoオブジェクトをVoiceViewに返します。
  9. 最後に、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_descendantsauto(デフォルト)です。重要と設定されていないビューには、対応するユーザー補助機能ノードが作成されません。また、そのビューから送信されたユーザー補助機能イベントは、フレームワークによって破棄されます。

ビューが適切なユーザー補助機能イベントを送信していても、VoiceViewが正しく応答していないと思われる場合は、ビューがユーザー補助機能にとって重要であると設定されているかどうかを確認してください。

AccessibilityNodeInfoオブジェクトの管理

Fire OSとAndroidのユーザー補助機能の重要な要素の1つは、AccessibilityNodeInfoオブジェクトの管理です。アプリのプロセスで実行されるAndroidのユーザー補助機能フレームワークが特定のノードの要求を受け取ると、フレームワークはまずそのノードがキャッシュ内にあるかどうかを確認します。

  • ノードがキャッシュに存在する場合はそれが返され、アプリでノードを作成する呼び出しは行われません。そのため、コンポーネントに関するユーザー補助機能情報が変更されるたびに、アプリはフレームワークとユーザー補助機能に通知する必要があります。通知しない場合、フレームワークは古い情報をユーザー補助機能に返します。
  • ノードが変更されて無効になったことを示すには、AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGEDタイプのユーザー補助機能イベントを送信します。
  • ノードがまだキャッシュにない場合は、要求された方法に応じてノードが作成されます。ユーザー補助機能による次のアクションがAccessibilityNodeInfoオブジェクトの作成をトリガーできます。
    • ユーザー補助機能イベントを受け取り、そのソースを要求する。
    • アクティブなウィンドウのルートノードを要求する。
    • 特定のノードの親ノードまたは子ノードを要求する。

仮想的にアクセス可能な子孫の実装

このセクションでは、仮想的にアクセス可能な子孫ビューを実装する方法について説明します。

仮想的にアクセス可能な子孫ビューの作成

AccessibilityDelegateAccessibilityNodeProviderはどちらも、基盤のビューで表現されない画面コンポーネントにユーザー補助機能を提供できます。このようなコンポーネントの例には、キーがキャンバス上に描画される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への変更を組み合わせて使用することが推奨されます。