Home | History | Annotate | Download | only in accessibility
      1 page.title=Making Applications Accessible
      2 parent.title=Accessibility
      3 parent.link=index.html
      4 @jd:body
      5 
      6 <div id="qv-wrapper">
      7 <div id="qv">
      8 
      9   <h2>In this document</h2>
     10   <ol>
     11     <li><a href="#label-ui">Labeling User Interface Elements</a></li>
     12     <li><a href="#focus-nav">Enabling Focus Navigation</a>
     13       <ol>
     14         <li><a href="#focus-enable">Enabling view focus</a></li>
     15         <li><a href="#focus-order">Controlling focus order</a></li>
     16       </ol>
     17     </li>
     18     <li><a href="#custom-views">Building Accessible Custom Views</a>
     19       <ol>
     20         <li><a href="#directional-control">Handling directional controller clicks</a></li>
     21         <li><a href="#accessibility-methods">Implementing accessibility API methods</a></li>
     22         <li><a href="#send-events">Sending accessibility events</a></li>
     23         <li><a href="#populate-events">Populating accessibility events</a></li>
     24       </ol>
     25     </li>
     26     <li><a href="#test">Testing Accessibility</a>
     27       <ol>
     28         <li><a href="#test-audibles">Testing audible feedback</a></li>
     29         <li><a href="#test-navigation">Testing focus navigation</a></li>
     30       </ol>
     31     </li>
     32   </ol>
     33 
     34   <h2>Key classes</h2>
     35   <ol>
     36     <li>{@link android.view.accessibility.AccessibilityEvent}</li>
     37     <li>{@link android.view.accessibility.AccessibilityNodeInfo}</li>
     38     <li>{@link android.support.v4.view.accessibility.AccessibilityNodeInfoCompat}</li>
     39     <li>{@link android.view.View.AccessibilityDelegate}</li>
     40     <li>{@link android.support.v4.view.AccessibilityDelegateCompat}</li>
     41   </ol>
     42 
     43   <h2>See also</h2>
     44   <ol>
     45     <li><a href="{@docRoot}training/accessibility/index.html">Implementing Accessibility</a></li>
     46     <li><a href="{@docRoot}training/design-navigation/index.html">Designing Effective Navigation</a>
     47       </li>
     48     <li><a href="{@docRoot}design/index.html">Android Design</a></li>
     49   </ol>
     50 
     51 </div>
     52 </div>
     53 
     54 <p>Applications built for Android are accessible to users with visual, physical or age-related
     55 disabilities when they activate accessibility features and services on a device. By default,
     56 these services make your application more accessible. However, there are further steps you should
     57 take to optimize the accessibility of your application and ensure a pleasant experience for all your
     58 users.</p>
     59 
     60 <p>Making sure your application is accessible to all users is relatively easy, particularly when you
     61 use framework-provided user interface components. If you only use these standard components for your
     62 application, there are just a few steps required to ensure your application is accessible:</p>
     63 
     64 <ol>
     65   <li>Label your {@link android.widget.ImageButton}, {@link android.widget.ImageView}, {@link
     66 android.widget.EditText}, {@link android.widget.CheckBox} and other user interface controls using
     67 the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
     68     {@code android:contentDescription}</a> attribute.</li>
     69   <li>Make all of your user interface elements accessible with a directional controller,
     70     such as a trackball or D-pad.</li>
     71   <li>Test your application by turning on accessibility services like TalkBack and Explore by
     72     Touch, and try using your application using only directional controls.</li>
     73 </ol>
     74 
     75 <p>Developers who create custom controls that extend from the {@link android.view.View} class have
     76 some additional responsibilities for making sure their components are accessible for users. This
     77 document also discusses how to make custom view controls compatible with accessibility services.</p>
     78 
     79 
     80 <h2 id="label-ui">Labeling User Interface Elements</h2>
     81 
     82 <p>Many user interface controls rely on visual cues to inform users of their meaning. For
     83 example, a note-taking application might use an {@link android.widget.ImageButton} with a
     84 picture of a plus sign to indicate that the user can add a new note. Or, an {@link
     85 android.widget.EditText} component may have a label near it that indicates its purpose. When a user
     86 with impaired vision accesses your application, these visual cues are often useless.</p>
     87 
     88 <p>To provide textual information about interface controls (as an alternative to the visual cues),
     89 use the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
     90 {@code android:contentDescription}</a> attribute. The text you provide in this attribute is not
     91 visible on the screen, but if a user has enabled accessibility services that provide audible
     92 prompts, then the description in this attribute is read aloud to the user.</p>
     93 
     94 <p>Set the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
     95 {@code android:contentDescription}</a> attribute for every {@link android.widget.ImageButton},
     96 {@link android.widget.ImageView}, {@link android.widget.EditText}, {@link android.widget.CheckBox}
     97 in your application's user interface, and on any other input controls that might require additional
     98 information for users who are not able to see it.</p>
     99 
    100 <p>For example, the following {@link android.widget.ImageButton} sets the content description for
    101 the plus button to the {@code add_note} string resource, which could be defined as Add note" for an
    102 English language interface:</p>
    103 
    104 <pre>
    105 &lt;ImageButton
    106     android:id=@+id/add_note_button
    107     android:src=@drawable/add_note
    108     android:contentDescription=@string/add_note/&gt;
    109 </pre>
    110 
    111 <p>By including the description, speech-based accessibility services can announce "Add note" when a
    112 user moves focus to this button or hovers over it.</p>
    113 
    114 <p class="note"><strong>Note:</strong> For {@link android.widget.EditText} fields, provide an
    115 <a href="{@docRoot}reference/android/widget/TextView.html#attr_android:hint">android:hint</a>
    116 attribute to help users understand what content is expected.</p>
    117 
    118 <h2 id="focus-nav">Enabling Focus Navigation</h2>
    119 
    120 <p>Focus navigation allows users with disabilities to step through user interface controls using a
    121 directional controller. Directional controllers can be physical, such as a clickable trackball,
    122 directional pad (D-pad) or arrow keys, tab key navigation with an attached keyboard or a software
    123 application, such as the
    124 <a href="https://play.google.com/store/apps/details?id=com.googlecode.eyesfree.inputmethod.latin">
    125 Eyes-Free Keyboard</a>, that provides an on-screen directional control.</p>
    126 
    127 <p>A directional controller is a primary means of navigation for many users.
    128 Verify that all user interface (UI) controls in your application are accessible
    129 without using the touchscreen and that clicking with the center button (or OK button) of a
    130 directional controller has the same effect as touching the controls on the touchscreen. For
    131 information on testing directional controls, see <a href="#test-navigation">Testing focus
    132 navigation</a>.</p>
    133 
    134 <h3 id="focus-enable">Enabling view focus</h3>
    135 
    136 <p>A user interface element is accessible using directional controls when its
    137 <a href="{@docRoot}reference/android/view/View.html#attr_android:focusable">
    138 {@code android:focusable}</a> attribute is set to {@code true}. This setting allows users to focus
    139 on the element using the directional controls and then interact with it. The user interface controls
    140 provided by the Android framework are focusable by default and visually indicate focus by changing
    141 the controls appearance.</p>
    142 
    143 <p>Android provides several APIs that let you control whether a user interface control is focusable
    144 and even request that a control be given focus:</p>
    145 
    146 <ul>
    147   <li>{@link android.view.View#setFocusable setFocusable()}</li>
    148   <li>{@link android.view.View#isFocusable isFocusable()}</li>
    149   <li>{@link android.view.View#requestFocus requestFocus()}</li>
    150 </ul>
    151 
    152 <p>When working with a view that is not focusable by default, you can make it focusable from the XML
    153 layout file by setting the
    154 <a href="{@docRoot}reference/android/view/View.html#attr_android:focusable">
    155 {@code android:focusable}</a> attribute to {@code true} or by using the {@link
    156 android.view.View#setFocusable setFocusable()} method.</p>
    157 
    158 <h3 id="focus-order">Controlling focus order</h3>
    159 
    160 <p>When users navigate in any direction using directional controls, focus is passed from one
    161 user interface element (View) to another, as determined by the focus ordering. The ordering of the
    162 focus movement is based on an algorithm that finds the nearest neighbor in a given direction. In
    163 rare cases, the default algorithm may not match the order that you intended for your UI. In these
    164 situations, you can provide explicit overrides to the ordering using the following XML attributes in
    165 the layout file:</p>
    166 
    167 <dl>
    168  <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown"
    169 >{@code android:nextFocusDown}</a></dt>
    170   <dd>Defines the next view to receive focus when the user navigates down.</dd>
    171  <a><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusLeft"
    172 >{@code android:nextFocusLeft}</a></dt>
    173   <dd>Defines the next view to receive focus when the user navigates left.</dd>
    174  <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusRight"
    175 >{@code android:nextFocusRight}</a></dt>
    176   <dd>Defines the next view to receive focus when the user navigates right.</dd>
    177  <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusUp"
    178 >{@code android:nextFocusUp}</a></dt>
    179   <dd>Defines the next view to receive focus when the user navigates up.</dd>
    180 </dl>
    181 
    182 <p>The following example XML layout shows two focusable user interface elements where the <a
    183 href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown"
    184 >{@code android:nextFocusDown}</a> and <a
    185 href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusUp"
    186 >{@code android:nextFocusUp}</a> attributes have been explicitly set. The {@link android.widget.TextView} is
    187 located to the right of the {@link android.widget.EditText}. However, since these properties have
    188 been set, the {@link android.widget.TextView} element can now be reached by pressing the down arrow
    189 when focus is on the {@link android.widget.EditText} element: </p>
    190 
    191 <pre>
    192 &lt;LinearLayout android:orientation="horizontal"
    193         ... &gt;
    194     &lt;EditText android:id="@+id/edit"
    195         android:nextFocusDown=@+id/text
    196         ... /&gt;
    197     &lt;TextView android:id="@+id/text"
    198         android:focusable=true
    199         android:text="Hello, I am a focusable TextView"
    200         android:nextFocusUp=@id/edit
    201         ... /&gt;
    202 &lt;/LinearLayout&gt;
    203 </pre>
    204 
    205 <p>When modifying focus order, be sure that the navigation works as expected in all directions from
    206 each user interface control and when navigating in reverse (to get back to where you came from).</p>
    207 
    208 <p class="note"><strong>Note:</strong> You can modify the focus order of user interface components
    209 at runtime, using methods such as {@link android.view.View#setNextFocusDownId setNextFocusDownId()}
    210 and {@link android.view.View#setNextFocusRightId setNextFocusRightId()}.</p>
    211 
    212 
    213 <h2 id="custom-views">Building Accessible Custom Views</h2>
    214 
    215 <p>If your application requires a <a href="{@docRoot}guide/topics/ui/custom-components.html">custom
    216 view component</a>, you must do some additional work to ensure that your custom view is accessible.
    217 These are the main tasks for ensuring the accessibility of your view:</p>
    218 
    219 <ul>
    220   <li>Handle directional controller clicks</li>
    221   <li>Implement Accessibility API methods</li>
    222   <li>Send {@link android.view.accessibility.AccessibilityEvent} objects specific to your custom view</li>
    223   <li>Populate {@link android.view.accessibility.AccessibilityEvent} and {@link
    224     android.view.accessibility.AccessibilityNodeInfo} for your view</li>
    225 </ul>
    226 
    227 
    228 <h3 id="directional-control">Handling directional controller clicks</h3>
    229 
    230 <p>On most devices, clicking a view using a directional controller sends a {@link
    231 android.view.KeyEvent} with {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER} to the view currently
    232 in focus. All standard Android views already handle {@link
    233 android.view.KeyEvent#KEYCODE_DPAD_CENTER} appropriately. When building a custom {@link
    234 android.view.View} control, make sure this event has the same effect as touching the view on the
    235 touchscreen. </p>
    236 
    237 <p>Your custom control should also treat the {@link android.view.KeyEvent#KEYCODE_ENTER} event the
    238 same as {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER}. This approach makes interaction from a
    239 full keyboard much easier for users.</p>
    240 
    241 
    242 <h3 id="accessibility-methods">Implementing accessibility API methods</h3>
    243 
    244 <p>Accessibility events are messages about users interaction with visual interface components in
    245 your application. These messages are handled by <a href="services.html">Accessibility Services</a>,
    246 which use the information in these events to produce supplemental feedback and prompts when users
    247 have enabled accessibility services. As of Android 4.0 (API Level 14) and higher, the methods for
    248 generating accessibility events have been expanded to provide more detailed information beyond the
    249 {@link android.view.accessibility.AccessibilityEventSource} interface introduced in Android 1.6 (API
    250 Level 4). The expanded accessibility methods are part of the {@link android.view.View} class as well
    251 as the {@link android.view.View.AccessibilityDelegate} class. The methods are as follows:</p>
    252 
    253 <dl>
    254  <dt>{@link android.view.View#sendAccessibilityEvent sendAccessibilityEvent()}</dt>
    255   <dd>(API Level 4) This method is called when a user takes action on a view. The event is
    256 classified with a user action type such as {@link
    257 android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED TYPE_VIEW_CLICKED}. You typically do
    258 not need to implement this method unless you are creating a custom view.</dd>
    259 
    260   <dt>{@link android.view.View#sendAccessibilityEventUnchecked
    261 sendAccessibilityEventUnchecked()}</dt>
    262   <dd>(API Level 4) This method is used when the calling code needs to directly control the check
    263 for accessibility being enabled on the device ({@link
    264 android.view.accessibility.AccessibilityManager#isEnabled AccessibilityManager.isEnabled()}). If
    265 you do implement this method, you must assume that the calling method has already checked that
    266 accessibility is enabled and the result is {@code true}. You typically do not need to implement this
    267 method for a custom view.</dd>
    268 
    269   <dt>{@link android.view.View#dispatchPopulateAccessibilityEvent
    270 dispatchPopulateAccessibilityEvent()} </dt>
    271   <dd>(API Level 4) The system calls this method when your custom view generates an
    272 accessibility event. As of API Level 14, the default implementation of this method calls {@link
    273 android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} for this view and
    274 then the {@link android.view.View#dispatchPopulateAccessibilityEvent
    275 dispatchPopulateAccessibilityEvent()} method for each child of this view. In order to support
    276 accessibility services on revisions of Android <em>prior</em> to 4.0 (API Level 14) you
    277 <em>must</em> override this method and populate {@link
    278 android.view.accessibility.AccessibilityEvent#getText} with descriptive text for your custom
    279 view.</dd>
    280 
    281   <dt>{@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()}</dt>
    282   <dd>(API Level 14) This method sets the text output of an {@link
    283 android.view.accessibility.AccessibilityEvent} for your view. This method is also called if the
    284 view is a child of a view which generates an accessibility event.
    285 
    286   <p class="note"><strong>Note:</strong> Modifying additional attributes beyond the text within
    287 this method potentially overwrites properties set by other methods. So, while you are able modify
    288 attributes of the accessibility event with this method, you should limit these changes
    289 to text content only and use the {@link android.view.View#onInitializeAccessibilityEvent
    290 onInitializeAccessibilityEvent()} method to modify other properties of the event.</p>
    291 
    292   <p class="note"><strong>Note:</strong> If your implementation of this event calls for completely
    293 overiding the output text without allowing other parts of your layout to modify its content, then
    294 do not call the super implementation of this method in your code.</p>
    295   </dd>
    296 
    297   <dt>{@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}</dt>
    298   <dd>(API Level 14) The system calls this method to obtain additional information about the
    299 state of the view, beyond text content. If your custom view provides interactive control beyond a
    300 simple {@link android.widget.TextView} or {@link android.widget.Button}, you should override this
    301 method and set the additional information about your view into the event using this method, such as
    302 password field type, checkbox type or states that provide user interaction or feedback. If you
    303 do override this method, you must call its super implementation and then only modify properties
    304 that have not been set by the super class.</dd>
    305 
    306   <dt>{@link android.view.View#onInitializeAccessibilityNodeInfo
    307 onInitializeAccessibilityNodeInfo()}</dt>
    308   <dd>(API Level 14) This method provides accessibility services with information about the state of
    309 the view. The default {@link android.view.View} implementation sets a standard set of view
    310 properties, but if your custom view provides interactive control beyond a simple {@link
    311 android.widget.TextView} or {@link android.widget.Button}, you should override this method and set
    312 the additional information about your view into the {@link
    313 android.view.accessibility.AccessibilityNodeInfo} object handled by this method.</dd>
    314 
    315   <dt>{@link android.view.ViewGroup#onRequestSendAccessibilityEvent
    316 onRequestSendAccessibilityEvent()}</dt>
    317   <dd>(API Level 14) The system calls this method when a child of your view has generated an
    318 {@link android.view.accessibility.AccessibilityEvent}. This step allows the the parent view to amend
    319 the accessibility event with additional information. You should implement this method only if your
    320 custom view can have child views and if the parent view can provide context information to the
    321 accessibility event that would be useful to accessibility services.</dd>
    322 </dl>
    323 
    324 <p>In order to support these accessibility methods for a custom view, you should take one of the
    325 following approaches:</p>
    326 
    327 <ul>
    328   <li>If your application targets Android 4.0 (API level 14) and higher, override and implement the
    329 accessibility methods listed above directly in your custom view class.</li>
    330   <li>If your custom view is intended to be compatible with Android 1.6 (API Level 4) and above, add
    331 the Android <a href="{@docRoot}tools/extras/support-library.html">Support Library</a>, revision 5 or
    332 higher, to your project. Then, within your custom view class, call the
    333 {@link android.support.v4.view.ViewCompat#setAccessibilityDelegate
    334 ViewCompat.setAccessibilityDelegate()} method to implement the accessibility methods
    335 above. For an example of this approach, see the Android Support Library (revision 5 or higher)
    336 sample {@code AccessibilityDelegateSupportActivity} in 
    337 ({@code &lt;sdk&gt;/extras/android/support/v4/samples/Support4Demos/})
    338   </li>
    339 </ul>
    340 
    341 <p>In either case, you should implement the following accessibility methods for your custom view
    342 class:</p>
    343 
    344 <ul>
    345   <li>{@link android.view.View#dispatchPopulateAccessibilityEvent
    346     dispatchPopulateAccessibilityEvent()}</li>
    347   <li>{@link android.view.View#onPopulateAccessibilityEvent
    348     onPopulateAccessibilityEvent()}</li>
    349   <li>{@link android.view.View#onInitializeAccessibilityEvent
    350     onInitializeAccessibilityEvent()}</li>
    351   <li>{@link android.view.View#onInitializeAccessibilityNodeInfo
    352     onInitializeAccessibilityNodeInfo()}</li>
    353 </ul>
    354 
    355 <p>For more information about implementing these methods, see <a href="#populate-events">Populating
    356 Accessibility Events</a>.</p>
    357 
    358 
    359 <h3 id="send-events">Sending accessibility events</h3>
    360 
    361 <p>Depending on the specifics of your custom view, it may need to send {@link
    362 android.view.accessibility.AccessibilityEvent} objects at a different times or for events not
    363 handled by the default implementation. The {@link android.view.View} class provides a default
    364 implementation for these event types:</p>
    365 
    366 <ul>
    367   <li>Starting with API Level 4:
    368     <ul>
    369       <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED}</li>
    370 
    371       <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}</li>
    372 
    373       <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_FOCUSED}</li>
    374     </ul>
    375   </li>
    376   <li>Starting with API Level 14:
    377     <ul>
    378       <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SCROLLED}</li>
    379 
    380       <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}</li>
    381 
    382       <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_EXIT}</li>
    383     </ul>
    384   </li>
    385 </ul>
    386 
    387 <p class="note"><strong>Note:</strong> Hover events are associated with the Explore by
    388 Touch feature, which uses these events as triggers for providing audible prompts for user interface
    389 elements.</p>
    390 
    391 <p>In general, you should send an {@link android.view.accessibility.AccessibilityEvent} whenever the
    392 content of your custom view changes. For example, if you are implementing a custom slider bar that
    393 allows a user to select a numeric value by pressing the left or right arrows, your custom view
    394 should emit an event of type {@link
    395 android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED} whenever the slider
    396 value changes. The following sample code demonstrates the use of the {@link
    397 android.view.accessibility.AccessibilityEventSource#sendAccessibilityEvent
    398 sendAccessibilityEvent()} method to report this event.</p>
    399 
    400 <pre>
    401 &#64;Override
    402 public boolean onKeyUp (int keyCode, KeyEvent event) {
    403     if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
    404         mCurrentValue--;
    405         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
    406         return true;
    407     }
    408     ...
    409 }
    410 </pre>
    411 
    412 
    413 <h3 id="populate-events">Populating accessibility events</h3>
    414 
    415 <p>Each {@link android.view.accessibility.AccessibilityEvent} has a set of required properties that
    416 describe the current state of the view. These properties include things such as the views class
    417 name, content description and checked state. The specific properties required for each event type
    418 are described in the {@link android.view.accessibility.AccessibilityEvent} reference documentation.
    419 The {@link android.view.View} implementation provides default values for these properties. Many of
    420 these values, including the class name and event timestamp, are provided automatically. If you are
    421 creating a custom view component, you must provide some information about the content and
    422 characteristics of the view. This information may be as simple as a button label, but may also
    423 include additional state information that you want to add to the event.</p>
    424 
    425 <p>The minimum requirement for providing information to accessibility services with a custom
    426 view is to implement {@link android.view.View#dispatchPopulateAccessibilityEvent
    427 dispatchPopulateAccessibilityEvent()}. This method is called by the system to request
    428 information for an {@link android.view.accessibility.AccessibilityEvent} and makes your custom
    429 view compatible with accessibility services on Android 1.6 (API Level 4) and higher. The
    430 following example code demonstrates a basic implementation of this method.</p>
    431 
    432 <pre>
    433 &#64;Override
    434 public void dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
    435     super.dispatchPopulateAccessibilityEvent(event);
    436     // Call the super implementation to populate its text to the event, which
    437     // calls onPopulateAccessibilityEvent() on API Level 14 and up.
    438 
    439     // In case this is running on a API revision earlier that 14, check
    440     // the text content of the event and add an appropriate text
    441     // description for this custom view:
    442     CharSequence text = getText();
    443     if (!TextUtils.isEmpty(text)) {
    444         event.getText().add(text);
    445     }
    446 }
    447 </pre>
    448 
    449 <p>On Android 4.0 (API Level 14) and higher, the {@link
    450 android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} and
    451 {@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}
    452 methods are the recommended way to populate or modify the information in an {@link
    453 android.view.accessibility.AccessibilityEvent}. Use the 
    454 {@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} method
    455 specifically for adding or modifying the text content of the event, which is turned into audible
    456 prompts by accessibility services such as TalkBack. Use the
    457 {@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()} method for
    458 populating additional information about the event, such as the selection state of the view.</p>
    459 
    460 <p>In addition, you should also implement the
    461 {@link android.view.View#onInitializeAccessibilityNodeInfo onInitializeAccessibilityNodeInfo()}
    462 method. {@link android.view.accessibility.AccessibilityNodeInfo} objects populated by this method
    463 are used by accessibility services to investigate the view hierarchy that generated an accessibility
    464 event after receiving that event, to obtain a more detailed context information and provide
    465 appropriate feedback to users.</p>
    466 
    467 <p>The example code below shows how override these three methods by using
    468 {@link android.support.v4.view.ViewCompat#setAccessibilityDelegate
    469 ViewCompat.setAccessibilityDelegate()}. Note that this sample code requires that the Android
    470 <a href="{@docRoot}tools/extras/support-library.html">Support Library</a> for API Level 4 (revision 5
    471 or higher) is added to your project.</p>
    472 
    473 <pre>
    474 ViewCompat.setAccessibilityDelegate(new AccessibilityDelegateCompat() {
    475     &#64;Override
    476     public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
    477         super.onPopulateAccessibilityEvent(host, event);
    478         // We call the super implementation to populate its text for the
    479         // event. Then we add our text not present in a super class.
    480         // Very often you only need to add the text for the custom view.
    481         CharSequence text = getText();
    482         if (!TextUtils.isEmpty(text)) {
    483             event.getText().add(text);
    484         }
    485     }
    486     &#64;Override
    487     public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
    488         super.onInitializeAccessibilityEvent(host, event);
    489         // We call the super implementation to let super classes
    490         // set appropriate event properties. Then we add the new property
    491         // (checked) which is not supported by a super class.
    492         event.setChecked(isChecked());
    493     }
    494     &#64;Override
    495     public void onInitializeAccessibilityNodeInfo(View host,
    496             AccessibilityNodeInfoCompat info) {
    497         super.onInitializeAccessibilityNodeInfo(host, info);
    498         // We call the super implementation to let super classes set
    499         // appropriate info properties. Then we add our properties
    500         // (checkable and checked) which are not supported by a super class.
    501         info.setCheckable(true);
    502         info.setChecked(isChecked());
    503         // Quite often you only need to add the text for the custom view.
    504         CharSequence text = getText();
    505         if (!TextUtils.isEmpty(text)) {
    506             info.setText(text);
    507         }
    508     }
    509 }
    510 </pre>
    511 
    512 <p>On applications targeting Android 4.0 (API Level 14) and higher, these methods can be implemented
    513 directly in your custom view class. For another example of this approach, see the Android
    514 <a href="{@docRoot}tools/extras/support-library.html">Support Library</a> (revision 5 or higher) sample
    515 {@code AccessibilityDelegateSupportActivity} in 
    516 ({@code &lt;sdk&gt;/extras/android/support/v4/samples/Support4Demos/}).</p>
    517 
    518 <p class="note"><strong>Note:</strong> You may find information on implementing accessibility for
    519 custom views written prior to Android 4.0 that describes the use of the
    520 {@link android.view.View#dispatchPopulateAccessibilityEvent dispatchPopulateAccessibilityEvent()}
    521 method for populating AccessibilityEvents. As of the Android 4.0 release, however, the recommended
    522 approach is to use the
    523 {@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} and
    524 {@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}
    525 methods.</p>
    526 
    527 
    528 <h2 id="test">Testing Accessibility</h2>
    529 
    530 <p>Testing the accessibility of your application is an important part of ensuring your users have a
    531 great experience. You can test the most important parts of accessibility by testing your application
    532 with audible feedback enabled and testing navigation within your application using directional
    533 controls.</p>
    534 
    535 <h3 id="test-audibles">Testing audible feedback</h3>
    536 <p>You can simulate the experience for many users by enabling an accessibility service that speaks
    537 as you move around the screen. The Explore by Touch accessibility service, which is available on
    538 devices with Android 4.0 and later. The <a
    539 href="https://play.google.com/store/apps/details?id=com.google.android.marvin.talkback">TalkBack</a>
    540 accessibility service, by the <a href="http://code.google.com/p/eyes-free/">Eyes-Free
    541 Project</a> comes preinstalled on many Android devices.</p>
    542 
    543 <p>To enable TalkBack on revisions of Android prior to Android 4.0:</p>
    544 <ol>
    545   <li>Launch the Settings application.</li>
    546   <li>Navigate to the <strong>Accessibility</strong> category and select it.</li>
    547   <li>Select <strong>Accessibility</strong> to enable it.</li>
    548   <li>Select <strong>TalkBack</strong> to enable it.</li>
    549 </ol>
    550 
    551 <p class="note"><strong>Note:</strong> If the TalkBack accessibility service is not available, you
    552 can install it for free from <a href="http://play.google.com">Google Play</a>.</p>
    553 
    554 <p>To enable Explore by Touch on Android 4.0 and later:</p>
    555 <ol>
    556   <li>Launch the Settings application.</li>
    557   <li>Navigate to the <strong>Accessibility</strong> category and select it.</li>
    558   <li>Select the <strong>TalkBack</strong> to enable it.</li>
    559   <li>Return to the <strong>Accessibility</strong> category and select <strong>Explore by
    560 Touch</strong> to enable it.
    561     <p class="note"><strong>Note:</strong> You must turn on TalkBack <em>first</em>, otherwise this
    562 option is not available.</p>
    563   </li>
    564 </ol>
    565 
    566 <h3 id="test-navigation">Testing focus navigation</h3>
    567 
    568 <p>As part of your accessibility testing, you can test navigation of your application using focus,
    569 even if your test devices does not have a directional controller. The <a
    570 href="{@docRoot}tools/help/emulator.html">Android Emulator</a> provides a
    571 simulated directional controller that you can easily use to test navigation. You can also use a
    572 software-based directional controller, such as the one provided by the
    573 <a href="https://play.google.com/store/apps/details?id=com.googlecode.eyesfree.inputmethod.latin">
    574 Eyes-Free Keyboard</a> to simulate use of a D-pad.</p>
    575