apps.jd revision 1bf704bd1878fa372cfa50e7166d6ddcb1ba1369
1page.title=Making Applications Accessible
2parent.title=Accessibility
3parent.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
55disabilities when they activate accessibility features and services on a device. By default,
56these services make your application more accessible. However, there are further steps you should
57take to optimize the accessibility of your application and ensure a pleasant experience for all your
58users.</p>
59
60<p>Making sure your application is accessible to all users is relatively easy, particularly when you
61use framework-provided user interface components. If you only use these standard components for your
62application, 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
66android.widget.EditText}, {@link android.widget.CheckBox} and other user interface controls using
67the <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
76some additional responsibilities for making sure their components are accessible for users. This
77document 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
83example, a note-taking application might use an {@link android.widget.ImageButton} with a
84picture of a plus sign to indicate that the user can add a new note. Or, an {@link
85android.widget.EditText} component may have a label near it that indicates its purpose. When a user
86with 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),
89use 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
91visible on the screen, but if a user has enabled accessibility services that provide audible
92prompts, 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}
97in your application's user interface, and on any other input controls that might require additional
98information 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
101the plus button to the {@code add_note} string resource, which could be defined as “Add note" for an
102English language interface:</p>
103
104<pre>
105&lt;ImageButton
106    android:id=”@+id/add_note_button107    android:src=”@drawable/add_note108    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
112user 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>
116attribute 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
121directional controller. Directional controllers can be physical, such as a clickable trackball,
122directional pad (D-pad) or arrow keys, tab key navigation with an attached keyboard or a software
123application, such as the
124<a href="https://play.google.com/store/apps/details?id=com.googlecode.eyesfree.inputmethod.latin">
125Eyes-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.
128Verify that all user interface (UI) controls in your application are accessible
129without using the touchscreen and that clicking with the center button (or OK button) of a
130directional controller has the same effect as touching the controls on the touchscreen. For
131information on testing directional controls, see <a href="#test-navigation">Testing focus
132navigation</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
139on the element using the directional controls and then interact with it. The user interface controls
140provided by the Android framework are focusable by default and visually indicate focus by changing
141the control’s appearance.</p>
142
143<p>Android provides several APIs that let you control whether a user interface control is focusable
144and 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
153layout 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
156android.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
161user interface element (View) to another, as determined by the focus ordering. The ordering of the
162focus movement is based on an algorithm that finds the nearest neighbor in a given direction. In
163rare cases, the default algorithm may not match the order that you intended for your UI. In these
164situations, you can provide explicit overrides to the ordering using the following XML attributes in
165the 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
183href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown"
184>{@code android:nextFocusDown}</a> and <a
185href="{@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
187located to the right of the {@link android.widget.EditText}. However, since these properties have
188been set, the {@link android.widget.TextView} element can now be reached by pressing the down arrow
189when 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/text196        ... /&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/edit201        ... /&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
206each 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
209at runtime, using methods such as {@link android.view.View#setNextFocusDownId setNextFocusDownId()}
210and {@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
216view component</a>, you must do some additional work to ensure that your custom view is accessible.
217These 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
231android.view.KeyEvent} with {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER} to the view currently
232in focus. All standard Android views already handle {@link
233android.view.KeyEvent#KEYCODE_DPAD_CENTER} appropriately. When building a custom {@link
234android.view.View} control, make sure this event has the same effect as touching the view on the
235touchscreen. </p>
236
237<p>Your custom control should also treat the {@link android.view.KeyEvent#KEYCODE_ENTER} event the
238same as {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER}. This approach makes interaction from a
239full 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
245your application. These messages are handled by <a href="services.html">Accessibility Services</a>,
246which use the information in these events to produce supplemental feedback and prompts when users
247have enabled accessibility services. As of Android 4.0 (API Level 14) and higher, the methods for
248generating 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
250Level 4). The expanded accessibility methods are part of the {@link android.view.View} class as well
251as 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
256classified with a user action type such as {@link
257android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED TYPE_VIEW_CLICKED}. You typically do
258not need to implement this method unless you are creating a custom view.</dd>
259
260  <dt>{@link android.view.View#sendAccessibilityEventUnchecked
261sendAccessibilityEventUnchecked()}</dt>
262  <dd>(API Level 4) This method is used when the calling code needs to directly control the check
263for accessibility being enabled on the device ({@link
264android.view.accessibility.AccessibilityManager#isEnabled AccessibilityManager.isEnabled()}). If
265you do implement this method, you must assume that the calling method has already checked that
266accessibility is enabled and the result is {@code true}. You typically do not need to implement this
267method for a custom view.</dd>
268
269  <dt>{@link android.view.View#dispatchPopulateAccessibilityEvent
270dispatchPopulateAccessibilityEvent()} </dt>
271  <dd>(API Level 4) The system calls this method when your custom view generates an
272accessibility event. As of API Level 14, the default implementation of this method calls {@link
273android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} for this view and
274then the {@link android.view.View#dispatchPopulateAccessibilityEvent
275dispatchPopulateAccessibilityEvent()} method for each child of this view. In order to support
276accessibility 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
278android.view.accessibility.AccessibilityEvent#getText} with descriptive text for your custom
279view.</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
283android.view.accessibility.AccessibilityEvent} for your view. This method is also called if the
284view 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
287this method potentially overwrites properties set by other methods. So, while you are able modify
288attributes of the accessibility event with this method, you should limit these changes
289to text content only and use the {@link android.view.View#onInitializeAccessibilityEvent
290onInitializeAccessibilityEvent()} 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
293overiding the output text without allowing other parts of your layout to modify its content, then
294do 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
299state of the view, beyond text content. If your custom view provides interactive control beyond a
300simple {@link android.widget.TextView} or {@link android.widget.Button}, you should override this
301method and set the additional information about your view into the event using this method, such as
302password field type, checkbox type or states that provide user interaction or feedback. If you
303do override this method, you must call its super implementation and then only modify properties
304that have not been set by the super class.</dd>
305
306  <dt>{@link android.view.View#onInitializeAccessibilityNodeInfo
307onInitializeAccessibilityNodeInfo()}</dt>
308  <dd>(API Level 14) This method provides accessibility services with information about the state of
309the view. The default {@link android.view.View} implementation sets a standard set of view
310properties, but if your custom view provides interactive control beyond a simple {@link
311android.widget.TextView} or {@link android.widget.Button}, you should override this method and set
312the additional information about your view into the {@link
313android.view.accessibility.AccessibilityNodeInfo} object handled by this method.</dd>
314
315  <dt>{@link android.view.ViewGroup#onRequestSendAccessibilityEvent
316onRequestSendAccessibilityEvent()}</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
319the accessibility event with additional information. You should implement this method only if your
320custom view can have child views and if the parent view can provide context information to the
321accessibility 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
325following approaches:</p>
326
327<ul>
328  <li>If your application targets Android 4.0 (API level 14) and higher, override and implement the
329accessibility 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
331the Android <a href="{@docRoot}sdk/compatibility-library.html">Support Library</a>, revision 5 or
332higher, to your project. Then, within your custom view class, call the
333{@link android.support.v4.view.ViewCompat#setAccessibilityDelegate
334ViewCompat.setAccessibilityDelegate()} method to implement the accessibility methods
335above. For an example of this approach, see the Android Support Library (revision 5 or higher)
336sample {@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
342class:</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
356Accessibility 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
362android.view.accessibility.AccessibilityEvent} objects at a different times or for events not
363handled by the default implementation. The {@link android.view.View} class provides a default
364implementation 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
388Touch feature, which uses these events as triggers for providing audible prompts for user interface
389elements.</p>
390
391<p>In general, you should send an {@link android.view.accessibility.AccessibilityEvent} whenever the
392content of your custom view changes. For example, if you are implementing a custom slider bar that
393allows a user to select a numeric value by pressing the left or right arrows, your custom view
394should emit an event of type {@link
395android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED} whenever the slider
396value changes. The following sample code demonstrates the use of the {@link
397android.view.accessibility.AccessibilityEventSource#sendAccessibilityEvent
398sendAccessibilityEvent()} method to report this event.</p>
399
400<pre>
401&#64;Override
402public 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
416describe the current state of the view. These properties include things such as the view’s class
417name, content description and checked state. The specific properties required for each event type
418are described in the {@link android.view.accessibility.AccessibilityEvent} reference documentation.
419The {@link android.view.View} implementation provides default values for these properties. Many of
420these values, including the class name and event timestamp, are provided automatically. If you are
421creating a custom view component, you must provide some information about the content and
422characteristics of the view. This information may be as simple as a button label, but may also
423include 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
426view is to implement {@link android.view.View#dispatchPopulateAccessibilityEvent
427dispatchPopulateAccessibilityEvent()}. This method is called by the system to request
428information for an {@link android.view.accessibility.AccessibilityEvent} and makes your custom
429view compatible with accessibility services on Android 1.6 (API Level 4) and higher. The
430following example code demonstrates a basic implementation of this method.</p>
431
432<pre>
433&#64;Override
434public 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
450android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} and
451{@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}
452methods are the recommended way to populate or modify the information in an {@link
453android.view.accessibility.AccessibilityEvent}. Use the 
454{@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} method
455specifically for adding or modifying the text content of the event, which is turned into audible
456prompts by accessibility services such as TalkBack. Use the
457{@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()} method for
458populating 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()}
462method. {@link android.view.accessibility.AccessibilityNodeInfo} objects populated by this method
463are used by accessibility services to investigate the view hierarchy that generated an accessibility
464event after receiving that event, to obtain a more detailed context information and provide
465appropriate 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
469ViewCompat.setAccessibilityDelegate()}. Note that this sample code requires that the Android
470<a href="{@docRoot}sdk/compatibility-library.html">Support Library</a> for API Level 4 (revision 5
471or higher) is added to your project.</p>
472
473<pre>
474ViewCompat.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
513directly in your custom view class. For another example of this approach, see the Android
514<a href="{@docRoot}sdk/compatibility-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
519custom views written prior to Android 4.0 that describes the use of the
520{@link android.view.View#dispatchPopulateAccessibilityEvent dispatchPopulateAccessibilityEvent()}
521method for populating AccessibilityEvents. As of the Android 4.0 release, however, the recommended
522approach is to use the
523{@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} and
524{@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}
525methods.</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
531great experience. You can test the most important parts of accessibility by testing your application
532with audible feedback enabled and testing navigation within your application using directional
533controls.</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
537as you move around the screen. The Explore by Touch accessibility service, which is available on
538devices with Android 4.0 and later. The <a
539href="https://play.google.com/store/apps/details?id=com.google.android.marvin.talkback">TalkBack</a>
540accessibility service, by the <a href="http://code.google.com/p/eyes-free/">Eyes-Free
541Project</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
552can 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
560Touch</strong> to enable it.
561    <p class="note"><strong>Note:</strong> You must turn on TalkBack <em>first</em>, otherwise this
562option 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,
569even if your test devices does not have a directional controller. The <a
570href="{@docRoot}guide/developing/tools/emulator.html">Android Emulator</a> provides a
571simulated directional controller that you can easily use to test navigation. You can also use a
572software-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">
574Eyes-Free Keyboard</a> to simulate use of a D-pad.</p>
575