am 945b7cb3: Merge "docs: Accessibility Dev Guide (subsumes Accessibility Best Practices)" into ics-mr1

* commit '945b7cb324f3bdfcf13efbe7bdf6a60f7163ed9a':
  docs: Accessibility Dev Guide (subsumes Accessibility Best Practices)
This commit is contained in:
Joe Fernandez
2012-04-03 10:04:54 -07:00
committed by Android Git Automerger
14 changed files with 994 additions and 355 deletions

View File

@@ -35,6 +35,14 @@ import com.android.internal.os.HandlerCaller;
* etc. Such a service can optionally request the capability for querying the content
* of the active window. Development of an accessibility service requires extending this
* class and implementing its abstract methods.
*
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>For more information about creating AccessibilityServices, read the
* <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
* developer guide.</p>
* </div>
*
* <h3>Lifecycle</h3>
* <p>
* The lifecycle of an accessibility service is managed exclusively by the system and

View File

@@ -41,6 +41,13 @@ import java.io.IOException;
* {@link AccessibilityService} for {@link android.view.accessibility.AccessibilityEvent}s
* according to the information encapsulated in this class.
*
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>For more information about creating AccessibilityServices, read the
* <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
* developer guide.</p>
* </div>
*
* @see AccessibilityService
* @see android.view.accessibility.AccessibilityEvent
* @see android.view.accessibility.AccessibilityManager

View File

@@ -14804,6 +14804,12 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
* classes i.e. classes in package android.view, that would like their
* applications to be backwards compatible.
* </p>
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>For more information about making applications accessible, read the
* <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
* developer guide.</p>
* </div>
* <p>
* A scenario in which a developer would like to use an accessibility delegate
* is overriding a method introduced in a later API version then the minimal API

View File

@@ -59,6 +59,12 @@ import java.util.List;
* by this class. For each event type there is a corresponding constant defined
* in this class. Follows a specification of the event types and their associated properties:
* </p>
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>For more information about creating and processing AccessibilityEvents, read the
* <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
* developer guide.</p>
* </div>
* <p>
* <b>VIEW TYPES</b></br>
* </p>

View File

@@ -18,6 +18,13 @@ package android.view.accessibility;
/**
* This interface is implemented by classes source of {@link AccessibilityEvent}s.
*
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>For more information about making applications accessible, read the
* <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
* developer guide.</p>
* </div>
*/
public interface AccessibilityEventSource {

View File

@@ -43,6 +43,12 @@ import java.util.List;
* details about how to obtain a handle to window content as a tree of accessibility
* node info as well as familiarizing with the security model.
* </p>
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>For more information about making applications accessible, read the
* <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
* developer guide.</p>
* </div>
*
* @see android.accessibilityservice.AccessibilityService
* @see AccessibilityEvent

View File

@@ -41,6 +41,13 @@ import java.util.List;
* event types. For detailed information please refer to {@link AccessibilityEvent}.
* </p>
*
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>For more information about creating and processing AccessibilityRecords, read the
* <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
* developer guide.</p>
* </div>
*
* @see AccessibilityEvent
* @see AccessibilityManager
* @see android.accessibilityservice.AccessibilityService

View File

@@ -35,5 +35,12 @@
changes etc. Parties interested in handling accessibility events implement and register an
accessibility service which extends {@link android.accessibilityservice.AccessibilityService}.
</p>
<div class="special reference">
<h3>Developer Guides</h3>
<p>For more information about making applications accessible, read the
<a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
developer guide.</p>
</div>
</body>
</html>

View File

@@ -160,6 +160,20 @@
<li><a href="<?cs var:toroot ?>guide/topics/ui/custom-components.html">
<span class="en">Custom Components</span>
</a></li>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/topics/ui/accessibility/index.html">
<span class="en">Accessibility</span>
<span class="new">new!</span>
</a></div>
<ul>
<li><a href="<?cs var:toroot ?>guide/topics/ui/accessibility/apps.html">
<span class="en">Making Applications Accessible</span>
</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/ui/accessibility/services.html">
<span class="en">Building Accessibility Services</span>
</a></li>
</ul>
</li>
<li><a href="<?cs var:toroot ?>guide/topics/ui/binding.html">
<span class="en">Binding to Data with AdapterView</span>
</a></li>
@@ -833,9 +847,6 @@ applications</span>
</li>
</ul>
<ul>
<li><a href="<?cs var:toroot ?>guide/practices/design/accessibility.html">
<span class="en">Designing for Accessibility</span>
</a></li>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/practices/design/performance.html">
<span class="en">Designing for Performance</span>

View File

@@ -0,0 +1,11 @@
<html>
<head>
<meta http-equiv="refresh"
content="0;url=http://developer.android.com/guide/topics/ui/accessibility/index.html">
<title>Redirecting...</title>
</head>
<body>
<p>You should be redirected. Please <a
href="http://developer.android.com/guide/topics/ui/accessibility/index.html">click here</a>.</p>
</body>
</html>

View File

@@ -1,352 +0,0 @@
page.title=Designing for Accessibility
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>Quickview</h2>
<ul>
<li>To make your application more accessible, you should make sure your UI is navigable
using a directional controller and your widgets provide content descriptions</li>
<li>If you implement a custom view, you should ensure that it delivers the appropriate
accessibility events during user interaction</li>
</ul>
<h2>In this document</h2>
<ol>
<li><a href="#Navigation">Allow Navigation with a Directional Controller</a>
<ol>
<li><a href="#FocusOrder">Controlling focus order</a></li>
<li><a href="#ClickingDpad">Clicking with a directional controller</a></li>
</ol>
</li>
<li><a href="#LabelInputs">Label Your Input Widgets</a></li>
<li><a href="#UiBestPractices">Follow Android UI Best Practices</a></li>
<li><a href="#CustomViews">Send Accessibility Events from Custom View Components</a></li>
<li><a href="#Test">Test Your Applications Accessibility</a></li>
</ol>
<h2>Key classes</h2>
<ol>
<li>{@link android.view.accessibility.AccessibilityEvent}</li>
<li>{@link android.view.accessibility.AccessibilityEventSource}</li>
</ol>
<h2>Related samples</h2>
<ol>
<li><a
href="{@docRoot}resources/samples/AccessibilityService/index.html">Accessibility Service</a></li>
</ol>
</div>
</div>
<p>Many Android users have disabilities that require them to interact with their Android devices in
different ways. These include users who have visual, physical or age-related disabilities that
prevent them from fully using or seeing a touchscreen.</p>
<p>Android provides an accessibility layer that helps these users navigate their Android-powered
devices more easily. Android's accessibility services provide things like text-to-speech, haptic
feedback, and trackball/d-pad navigation that augment the user experience.</p>
<p>Your application should follow the guidelines in this document to ensure that it provides a
good experience for users with disabilities. Following these two basic rules will solve most
access-related problems:</p>
<ul>
<li>Make all of your user interface controls accessible with a trackball or directional
controller (d-pad).</li>
<li>Label your {@link android.widget.ImageButton}, {@link android.widget.EditText}, and other input
widgets using the <a
href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">{@code
android:contentDescription}</a> attribute.</li>
</ul>
<h2 id="Navigation">Allow Navigation with a Directional Controller</h2>
<p>Many Android devices come with some sort of directional controller, such as:</p>
<ul>
<li>A clickable trackball that users can move in any direction</li>
<li>A clickable d-pad that allows users to navigate in four directions.</li>
<li>Arrow keys and an OK button thats equivalent to clicking a trackball or d-pad.</li>
</ul>
<p>All of these directional controllers allow users to navigate the screen without using the
touchscreen. On some devices, a user can also navigate to the top or bottom of a list by holding
down the <em>alt</em> key while pressing a discrete key for up or down.</p>
<p>A directional controller is the primary means of navigation for users with visual or some
physical impairments (and also for users without impairments when using devices that don't
have a touchscreen). You should verify that all UI controls in your application are
accessible without using the touchscreen and that clicking with the center button (or OK button) has
the same effect as touching the controls on the touchscreen.</p>
<p>A UI control (also called a "widget") is accessible using directional controls when it's
"focusable" property is "true." This means that users can focus on the widget using the directional
controls and then interact with it. Widgets provided by the Android APIs are focusable by default
and visually indicate focus by changing the widget visual appearance in some way.</p>
<p>Android provides several APIs that let you control whether a widget is focusable and even
request that a widget be given focus. Such methods include:</p>
<ul>
<li>{@link android.view.View#setFocusable setFocusable()}</li>
<li>{@link android.view.View#isFocusable isFocusable()}</li>
<li>{@link android.view.View#requestFocus requestFocus()}</li>
</ul>
<p>When working with a view that is not focusable by default, you can make it focusable from the XML
layout file by setting the <a
href="{@docRoot}reference/android/view/View.html#attr_android:focusable">{@code
android:focusable}</a> attribute to {@code "true"}.</p>
<h3 id="FocusOrder">Controlling focus order</h3>
<p>When the user navigates in any direction using the directional controls, focus is passed from one
view to another, as determined by the focus ordering. The ordering of the focus movement is based on
an algorithm that finds the nearest neighbor in a given direction. In rare cases, the default
algorithm may not match the order that you intended for your UI. In these situations, you can
provide explicit overrides to the ordering using the following XML attributes in the layout
file:</p>
<dl>
<dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown"
>{@code android:nextFocusDown}</a></dt>
<dd>Defines the next view to receive focus when the user navigates down.</dd>
<a><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusLeft"
>{@code android:nextFocusLeft}</a></dt>
<dd>Defines the next view to receive focus when the user navigates left.</dd>
<dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusRight"
>{@code android:nextFocusRight}</a></dt>
<dd>Defines the next view to receive focus when the user navigates right.</dd>
<dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusUp"
>{@code android:nextFocusUp}</a></dt>
<dd>Defines the next view to receive focus when the user navigates up.</dd>
</dl>
<p>For example, here is an XML layout that contains a focusable {@link android.widget.TextView}.
While the {@link android.widget.TextView} is located to the right of the {@link
android.widget.EditText}, it can now be reached by pressing the down arrow when focus is on the
{@link android.widget.EditText}: </p>
<pre>
&lt;LinearLayout android:orientation="horizontal"
... &gt;
&lt;EditText android:id="@+id/edit"
android:nextFocusDown=”@+id/text”
... /&gt;
&lt;TextView android:id="@+id/text"
android:focusable=”true”
android:text="Hello, I am a focusable TextView"
android:nextFocusUp=”@id/edit”
... /&gt;
&lt;/LinearLayout&gt;
</pre>
<p>When modifying this ordering, be sure that the navigation works as expected in all directions
from each widget and when navigating in reverse (to get back to where you came from).</p>
<p>You can also modify the focus ordering at runtime, using methods in the {@link
android.view.View} class, such as {@link android.view.View#setNextFocusDownId
setNextFocusDownId()} and {@link android.view.View#setNextFocusRightId
setNextFocusRightId()}.</p>
<h3 id="ClickingDpad">Clicking with a directional controller</h3>
<p>On most devices, clicking a view using a directional controller sends a {@link
android.view.KeyEvent} with {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER} to the view currently
in focus. Make sure this event has the same effect as touching the view on the touchscreen. All
standard Android views already handle {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER}
appropriately.</p>
<p>If possible, also treat the {@link android.view.KeyEvent#KEYCODE_ENTER} event the same as
{@link android.view.KeyEvent#KEYCODE_DPAD_CENTER}. That makes interaction much easier from a full
keyboard.</p>
<h2 id="LabelInputs">Label Your Input Widgets</h2>
<p>Many input widgets rely on visual cues to inform the user of their meaning. For example, a
notepad application might use an {@link android.widget.ImageButton} with a picture of a plus sign to
indicate that the user can add a new note. Or, an {@link android.widget.EditText} may have
a label near it that indicates its purpose. When a visually impaired user accesses your
application, these visual cues are often useless.</p>
<p>To provide textual information about these widgets (as an alternative to the visual cues), you
should use the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription"
>{@code android:contentDescription}</a> attribute. The text you provide in this attribute
is not visible on the screen, but if a user has enabled accessibility speech tools then the
description in this attribute is read aloud to the user.</p>
<p>You should set the <a
href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription" >{@code
android:contentDescription}</a> attribute on every {@link android.widget.ImageButton}, {@link
android.widget.EditText}, {@link android.widget.CheckBox}, and on any other input widgets that might
benefit users with extra information.</p>
<p>For example, the following {@link android.widget.ImageButton} sets the content description for
the plus button to the {@code add_note} string resource, which might be defined in English as
“Add note":</p>
<pre>
&lt;ImageButton
android:id=”@+id/add_entry_button”
android:src=”@drawable/plus”
android:contentDescription=”@string/add_note”/&gt;
</pre>
<p>This way, when using speech accessibility tools, the user hears "Add note" when focused on
this widget.</p>
<h2 id="UiBestPractices">Follow Android UI Best Practices</h2>
<p>You can make it easier for users to learn how to use your application by developing a user
interface that complies with Android's standard interaction patterns, instead of creating your own
or using interaction patterns from another platform. This consistency is especially important for
many disabled users, as they may have less contextual information available to try to understand
your applications interface.</p>
<p>Specifically, you should:</p>
<ul>
<li>Use the platform's built-in widgets and layouts whenever possible, as these views provide
accessibility support by default.</li>
<li>Use the <a href="{@docRoot}guide/topics/ui/menus.html#options-menu">Options Menu</a> as an
alternative to complex touchscreen tasks.</li>
<li>Make sure the BACK button correctly moves the user back one logical step in the <a
href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">task's back stack</a> or the
activity's back stack of fragments (when <a
href="{@docRoot}guide/topics/fundamentals/fragments.html#Transactions">performing fragment
transactions</a>), as appropriate.</li>
</ul>
<h2 id="CustomViews">Send Accessibility Events from Custom View Components</h2>
<p>If your application requires that you create a <a
href="{@docRoot}guide/topics/ui/custom-components.html">custom view component</a>, you may need to
do some additional work to ensure that your view is accessible. Specifically, you should make sure
that your view implements the {@link android.view.accessibility.AccessibilityEventSource}
interface and emits {@link android.view.accessibility.AccessibilityEvent}s at the proper times,
and that each {@link android.view.accessibility.AccessibilityEvent} contains relevant information
about the state of the view.</p>
<p>Events are emitted whenever something notable happens in the user interface. Currently, there
are five types of accessibility events that a view should send to the system as the user interacts
with it:</p>
<dl>
<dt>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED}</dt>
<dd>Indicates that the user clicked on the view (for example, the user selects a button).</dd>
<dt>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}</dt>
<dd>Indicates that the user performed a long press on the view. </dd>
<dt>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SELECTED}</dt>
<dd>Indicates that the user selected an item from within the view. This is usually used in the
context of an {@link android.widget.AdapterView}.</dd>
<dt>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_FOCUSED}</dt>
<dd>Indicates that the user moved the focus to the view.</dd>
<dt>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}</dt>
<dd>Indicates that the text or contents of the view changed.</dd>
</dl>
<p>The basic {@link android.view.View} class implements {@link
android.view.accessibility.AccessibilityEventSource} and emits these events at the proper time in
the standard cases. Your custom view should extend from {@link android.view.View} (or one of its
subclasses) to take advantage of these default implementations.</p>
<p>Depending on the specifics of your custom view, your view may need to emit one of these events at
a different time than the default {@link android.view.View} implementation. To do so, simply call
{@link android.view.accessibility.AccessibilityEventSource#sendAccessibilityEvent
sendAccessibilityEvent()} with the specific event type at the correct time.</p>
<p>For example, say you are implementing a custom slider bar that allows the user to select a
numeric value by pressing the left or right arrows. This view should emit an event of type {@link
android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED} whenever the slider value
changes:</p>
<pre>
&#64;Override
public boolean onKeyUp (int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
mCurrentValue--;
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
return true;
}
...
}
</pre>
<p>Each {@link android.view.accessibility.AccessibilityEvent} has a set of required properties that
describe the current state of the view. These properties include things like the views class name,
text and checked state. The specific properties required for each event type are described in the
{@link android.view.accessibility.AccessibilityEvent} documentation. The {@link android.view.View}
implementation will fill in default values for these properties. Most of these values, like the
class name and event timestamp, will not need to be changed. However, depending on the specifics of
your custom view, you may want to provide a different value for one or more of the properties. For
example, your view may have additional state information that you want to add to the event text.</p>
<p>The {@link android.view.View#dispatchPopulateAccessibilityEvent
dispatchPopulateAccessibilityEvent()} method in {@link android.view.View} provides a hook for making
changes to the {@link android.view.accessibility.AccessibilityEvent} object before it is
emitted.</p>
<p>In the above slider bar example, the view should add the current value of the slider bar to the
text of the event:</p>
<pre>
&#64;Override
public boolean dispatchPopulateAccessibilityEvent(final AccessibilityEvent event) {
super.dispatchPopulateAccessibilityEvent(event);
if (!isShown()) {
return false;
}
CharSequence text = String.valueOf(mCurrentValue);
if (text.length() > AccessibilityEvent.MAX_TEXT_LENGTH) {
text = text.subSequence(0, AccessiblityEvent.MAX_TEXT_LENGTH);
}
event.getText().add(text);
return true;
}
</pre>
<h2 id="Test">Test Your Applications Accessibility</h2>
<p>You can simulate the experience for many users by enabling an accessibility service that speaks
as you move around the screen. One such service is <a
href="https://play.google.com/store/details?id=com.google.android.marvin.talkback">TalkBack</a>, by the
<a href="http://code.google.com/p/eyes-free/">Eyes-Free Project</a>. It comes preinstalled on many
Android-powered devices, but is also available for free from the <a
href="https://play.google.com/store/details?id=com.google.android.marvin.talkback">Google Play</a> store.</p>
<p>This service requires that you have a text-to-speech engine installed on your phone. You can
verify if you have one installed in the <strong>Text-to-speech</strong> settings menu by selecting
<strong>Listen to an example</strong>. If you do not hear anything spoken, install the required
voice data by selecting <strong>Install voice data</strong>.</p>
<p>Once text-to-speech is functioning correctly, you can enable TalkBack (or another accessibility
service) in the <strong>Accessibility</strong> settings menu. Enable both
<strong>Accessibility</strong> and <strong>TalkBack</strong>. As you navigate about the device, you
should now hear spoken feedback.</p>
<p>You can now attempt to use your application as a blind user would. As you move around using only
the directional controller, make sure that the spoken feedback you hear makes sense and is
sufficient to navigate the application without any visual cues.</p>

View File

@@ -0,0 +1,570 @@
page.title=Making Applications Accessible
parent.title=Accessibility
parent.link=index.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<li><a href="#label-ui">Labeling User Interface Elements</a></li>
<li><a href="#focus-nav">Enabling Focus Navigation</a>
<ol>
<li><a href="#focus-enable">Enabling view focus</a></li>
<li><a href="#focus-order">Controlling focus order</a></li>
</ol>
</li>
<li><a href="#custom-views">Building Accessible Custom Views</a>
<ol>
<li><a href="#directional-control">Handling directional controller clicks</a></li>
<li><a href="#accessibility-methods">Implementing accessibility API methods</a></li>
<li><a href="#send-events">Sending accessibility events</a></li>
<li><a href="#populate-events">Populating accessibility events</a></li>
</ol>
</li>
<li><a href="#test">Testing Accessibility</a>
<ol>
<li><a href="#test-audibles">Testing audible feedback</a></li>
<li><a href="#test-navigation">Testing focus navigation</a></li>
</ol>
</li>
</ol>
<h2>Key classes</h2>
<ol>
<li>{@link android.view.accessibility.AccessibilityEvent}</li>
<li>{@link android.view.accessibility.AccessibilityNodeInfo}</li>
<li>{@link android.support.v4.view.accessibility.AccessibilityNodeInfoCompat}</li>
<li>{@link android.view.View.AccessibilityDelegate}</li>
<li>{@link android.support.v4.view.AccessibilityDelegateCompat}</li>
</ol>
<h2>See also</h2>
<ol>
<li><a href="{@docRoot}training/accessibility/index.html">Implementing Accessibility</a></li>
<li><a href="{@docRoot}training/design-navigation/index.html">Designing Effective Navigation</a>
</li>
<li><a href="{@docRoot}design/index.html">Android Design</a></li>
</ol>
</div>
</div>
<p>Applications built for Android are accessible to users with visual, physical or age-related
disabilities when they activate accessibility features and services on a device. By default,
these services make your application more accessible. However, there are further steps you should
take to optimize the accessibility of your application and ensure a pleasant experience for all your
users.</p>
<p>Making sure your application is accessible to all users is relatively easy, particularly when you
use framework-provided user interface components. If you only use these standard components for your
application, there are just a few steps required to ensure your application is accessible:</p>
<ol>
<li>Label your {@link android.widget.ImageButton}, {@link android.widget.ImageView}, {@link
android.widget.EditText}, {@link android.widget.CheckBox} and other user interface controls using
the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
{@code android:contentDescription}</a> attribute.</li>
<li>Make all of your user interface elements accessible with a directional controller,
such as a trackball or D-pad.</li>
<li>Test your application by turning on accessibility services like TalkBack and Explore by
Touch, and try using your application using only directional controls.</li>
</ol>
<p>Developers who create custom controls that extend from the {@link android.view.View} class have
some additional responsibilities for making sure their components are accessible for users. This
document also discusses how to make custom view controls compatible with accessibility services.</p>
<h2 id="label-ui">Labeling User Interface Elements</h2>
<p>Many user interface controls rely on visual cues to inform users of their meaning. For
example, a note-taking application might use an {@link android.widget.ImageButton} with a
picture of a plus sign to indicate that the user can add a new note. Or, an {@link
android.widget.EditText} component may have a label near it that indicates its purpose. When a user
with impaired vision accesses your application, these visual cues are often useless.</p>
<p>To provide textual information about interface controls (as an alternative to the visual cues),
use the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
{@code android:contentDescription}</a> attribute. The text you provide in this attribute is not
visible on the screen, but if a user has enabled accessibility services that provide audible
prompts, then the description in this attribute is read aloud to the user.</p>
<p>Set the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
{@code android:contentDescription}</a> attribute for every {@link android.widget.ImageButton},
{@link android.widget.ImageView}, {@link android.widget.EditText}, {@link android.widget.CheckBox}
in your application's user interface, and on any other input controls that might require additional
information for users who are not able to see it.</p>
<p>For example, the following {@link android.widget.ImageButton} sets the content description for
the plus button to the {@code add_note} string resource, which could be defined as “Add note" for an
English language interface:</p>
<pre>
&lt;ImageButton
android:id=”@+id/add_note_button”
android:src=”@drawable/add_note”
android:contentDescription=”@string/add_note”/&gt;
</pre>
<p>By including the description, speech-based accessibility services can announce "Add note" when a
user moves focus to this button or hovers over it.</p>
<p class="note">Note: For {@link android.widget.EditText} fields, provide an
<a href="{@docRoot}reference/android/widget/TextView.html#attr_android:hint">android:hint</a>
attribute to help users understand what content is expected.</p>
<h2 id="focus-nav">Enabling Focus Navigation</h2>
<p>Focus navigation allows users with disabilities to step through user interface controls using a
directional controller. Directional controllers can be physical, such as a clickable trackball,
directional pad (D-Pad) or arrow keys, tab key navigation with an attached keyboard or a software
application that provides an on-screen directional control.</p>
<p>A directional controller is a primary means of navigation for many users.
Verify that all user interface (UI) controls in your application are accessible
without using the touchscreen and that clicking with the center button (or OK button) of a
directional controller has the same effect as touching the controls on the touchscreen. For
information on testing directional controls, see <a href="#test-navigation">Testing focus
navigation</a>.</p>
<h3 id="focus-enable">Enabling view focus</h3>
<p>A user interface element is accessible using directional controls when its
<a href="{@docRoot}reference/android/view/View.html#attr_android:focusable">
{@code android:focusable}</a> attribute is set to {@code true}. This setting allows users to focus
on the element using the directional controls and then interact with it. The user interface controls
provided by the Android framework are focusable by default and visually indicate focus by changing
the controls appearance.</p>
<p>Android provides several APIs that let you control whether a user interface control is focusable
and even request that a control be given focus:</p>
<ul>
<li>{@link android.view.View#setFocusable setFocusable()}</li>
<li>{@link android.view.View#isFocusable isFocusable()}</li>
<li>{@link android.view.View#requestFocus requestFocus()}</li>
</ul>
<p>When working with a view that is not focusable by default, you can make it focusable from the XML
layout file by setting the
<a href="{@docRoot}reference/android/view/View.html#attr_android:focusable">
{@code android:focusable}</a> attribute to {@code true} or by using the {@link
android.view.View#setFocusable setFocusable()} method.</p>
<h3 id="focus-order">Controlling focus order</h3>
<p>When users navigate in any direction using directional controls, focus is passed from one
user interface element (View) to another, as determined by the focus ordering. The ordering of the
focus movement is based on an algorithm that finds the nearest neighbor in a given direction. In
rare cases, the default algorithm may not match the order that you intended for your UI. In these
situations, you can provide explicit overrides to the ordering using the following XML attributes in
the layout file:</p>
<dl>
<dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown"
>{@code android:nextFocusDown}</a></dt>
<dd>Defines the next view to receive focus when the user navigates down.</dd>
<a><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusLeft"
>{@code android:nextFocusLeft}</a></dt>
<dd>Defines the next view to receive focus when the user navigates left.</dd>
<dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusRight"
>{@code android:nextFocusRight}</a></dt>
<dd>Defines the next view to receive focus when the user navigates right.</dd>
<dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusUp"
>{@code android:nextFocusUp}</a></dt>
<dd>Defines the next view to receive focus when the user navigates up.</dd>
</dl>
<p>The following example XML layout shows two focusable user interface elements where the <a
href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown"
>{@code android:nextFocusDown}</a> and <a
href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusUp"
>{@code android:nextFocusUp}</a> attributes have been explicitly set. The {@link android.widget.TextView} is
located to the right of the {@link android.widget.EditText}. However, since these properties have
been set, the {@link android.widget.TextView} element can now be reached by pressing the down arrow
when focus is on the {@link android.widget.EditText} element: </p>
<pre>
&lt;LinearLayout android:orientation="horizontal"
... &gt;
&lt;EditText android:id="@+id/edit"
android:nextFocusDown=”@+id/text”
... /&gt;
&lt;TextView android:id="@+id/text"
android:focusable=”true”
android:text="Hello, I am a focusable TextView"
android:nextFocusUp=”@id/edit”
... /&gt;
&lt;/LinearLayout&gt;
</pre>
<p>When modifying focus order, be sure that the navigation works as expected in all directions from
each user interface control and when navigating in reverse (to get back to where you came from).</p>
<p class="note"><strong>Note:</strong> You can modify the focus order of user interface components
at runtime, using methods such as {@link android.view.View#setNextFocusDownId setNextFocusDownId()}
and {@link android.view.View#setNextFocusRightId setNextFocusRightId()}.</p>
<h2 id="custom-views">Building Accessible Custom Views</h2>
<p>If your application requires a <a href="{@docRoot}guide/topics/ui/custom-components.html">custom
view component</a>, you must do some additional work to ensure that your custom view is accessible.
These are the main tasks for ensuring the accessibility of your view:</p>
<ul>
<li>Handle directional controller clicks</li>
<li>Implement Accessibility API methods</li>
<li>Send {@link android.view.accessibility.AccessibilityEvent} objects specific to your custom view</li>
<li>Populate {@link android.view.accessibility.AccessibilityEvent} and {@link
android.view.accessibility.AccessibilityNodeInfo} for your view</li>
</ul>
<h3 id="directional-control">Handling directional controller clicks</h3>
<p>On most devices, clicking a view using a directional controller sends a {@link
android.view.KeyEvent} with {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER} to the view currently
in focus. All standard Android views already handle {@link
android.view.KeyEvent#KEYCODE_DPAD_CENTER} appropriately. When building a custom {@link
android.view.View} control, make sure this event has the same effect as touching the view on the
touchscreen. </p>
<p>Your custom control should also treat the {@link android.view.KeyEvent#KEYCODE_ENTER} event the
same as {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER}. This approach makes interaction from a
full keyboard much easier for users.</p>
<h3 id="accessibility-methods">Implementing accessibility API methods</h3>
<p>Accessibility events are messages about users interaction with visual interface components in
your application. These messages are handled by <a href="services.html">Accessibility Services</a>,
which use the information in these events to produce supplemental feedback and prompts when users
have enabled accessibility services. As of Android 4.0 (API Level 14) and higher, the methods for
generating accessibility events have been expanded to provide more detailed information beyond the
{@link android.view.accessibility.AccessibilityEventSource} interface introduced in Android 1.6 (API
Level 4). The expanded accessibility methods are part of the {@link android.view.View} class as well
as the {@link android.view.View.AccessibilityDelegate} class. The methods are as follows:</p>
<dl>
<dt>{@link android.view.View#sendAccessibilityEvent sendAccessibilityEvent()}</dt>
<dd>(API Level 4) This method is called when a user takes action on a view. The event is
classified with a user action type such as {@link
android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED TYPE_VIEW_CLICKED}. You typically do
not need to implement this method unless you are creating a custom view.</dd>
<dt>{@link android.view.View#sendAccessibilityEventUnchecked
sendAccessibilityEventUnchecked()}</dt>
<dd>(API Level 4) This method is used when the calling code needs to directly control the check
for accessibility being enabled on the device ({@link
android.view.accessibility.AccessibilityManager#isEnabled AccessibilityManager.isEnabled()}). If
you do implement this method, you must assume that the calling method has already checked that
accessibility is enabled and the result is {@code true}. You typically do not need to implement this
method for a custom view.</dd>
<dt>{@link android.view.View#dispatchPopulateAccessibilityEvent
dispatchPopulateAccessibilityEvent()} </dt>
<dd>(API Level 4) The system calls this method when your custom view generates an
accessibility event. As of API Level 14, the default implementation of this method calls {@link
android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} for this view and
then the {@link android.view.View#dispatchPopulateAccessibilityEvent
dispatchPopulateAccessibilityEvent()} method for each child of this view. In order to support
accessibility services on revisions of Android <em>prior</em> to 4.0 (API Level 14) you
<em>must</em> override this method and populate {@link
android.view.accessibility.AccessibilityEvent#getText} with descriptive text for your custom
view.</dd>
<dt>{@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()}</dt>
<dd>(API Level 14) This method sets the text output of an {@link
android.view.accessibility.AccessibilityEvent} for your view. This method is also called if the
view is a child of a view which generates an accessibility event.
<p class="note"><strong>Note:</strong> Modifying additional attributes beyond the text within
this method potentially overwrites properties set by other methods. So, while you are able modify
attributes of the accessibility event with this method, you should limit these changes
to text content only and use the {@link android.view.View#onInitializeAccessibilityEvent
onInitializeAccessibilityEvent()} method to modify other properties of the event.</p>
<p class="note"><strong>Note:</strong> If your implementation of this event calls for completely
overiding the output text without allowing other parts of your layout to modify its content, then
do not call the super implementation of this method in your code.</p>
</dd>
<dt>{@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}</dt>
<dd>(API Level 14) The system calls this method to obtain additional information about the
state of the view, beyond text content. If your custom view provides interactive control beyond a
simple {@link android.widget.TextView} or {@link android.widget.Button}, you should override this
method and set the additional information about your view into the event using this method, such as
password field type, checkbox type or states that provide user interaction or feedback. If you
do override this method, you must call its super implementation and then only modify properties
that have not been set by the super class.</dd>
<dt>{@link android.view.View#onInitializeAccessibilityNodeInfo
onInitializeAccessibilityNodeInfo()}</dt>
<dd>(API Level 14) This method provides accessibility services with information about the state of
the view. The default {@link android.view.View} implementation sets a standard set of view
properties, but if your custom view provides interactive control beyond a simple {@link
android.widget.TextView} or {@link android.widget.Button}, you should override this method and set
the additional information about your view into the {@link
android.view.accessibility.AccessibilityNodeInfo} object handled by this method.</dd>
<dt>{@link android.view.ViewGroup#onRequestSendAccessibilityEvent
onRequestSendAccessibilityEvent()}</dt>
<dd>(API Level 14) The system calls this method when a child of your view has generated an
{@link android.view.accessibility.AccessibilityEvent}. This step allows the the parent view to amend
the accessibility event with additional information. You should implement this method only if your
custom view can have child views and if the parent view can provide context information to the
accessibility event that would be useful to accessibility services.</dd>
</dl>
<p>In order to support these accessibility methods for a custom view, you should take one of the
following approaches:</p>
<ul>
<li>If your application targets Android 4.0 (API level 14) and higher, override and implement the
accessibility methods listed above directly in your custom view class.</li>
<li>If your custom view is intended to be compatible with Android 1.6 (API Level 4) and above, add
the Android <a href="{@docRoot}sdk/compatibility-library.html">Support Library</a>, revision 5 or
higher, to your project. Then, within your custom view class, call the
{@link android.support.v4.view.ViewCompat#setAccessibilityDelegate
ViewCompat.setAccessibilityDelegate()} method to implement the accessibility methods
above. For an example of this approach, see the Android Support Library (revision 5 or higher)
sample {@code AccessibilityDelegateSupportActivity} in
({@code &lt;sdk&gt;/extras/android/support/v4/samples/Support4Demos/})
</li>
</ul>
<p>In either case, you should implement the following accessibility methods for your custom view
class:</p>
<ul>
<li>{@link android.view.View#dispatchPopulateAccessibilityEvent
dispatchPopulateAccessibilityEvent()}</li>
<li>{@link android.view.View#onPopulateAccessibilityEvent
onPopulateAccessibilityEvent()}</li>
<li>{@link android.view.View#onInitializeAccessibilityEvent
onInitializeAccessibilityEvent()}</li>
<li>{@link android.view.View#onInitializeAccessibilityNodeInfo
onInitializeAccessibilityNodeInfo()}</li>
</ul>
<p>For more information about implementing these methods, see <a href="#populate-events">Populating
Accessibility Events</a>.</p>
<h3 id="send-events">Sending accessibility events</h3>
<p>Depending on the specifics of your custom view, it may need to send {@link
android.view.accessibility.AccessibilityEvent} objects at a different times or for events not
handled by the default implementation. The {@link android.view.View} class provides a default
implementation for these event types:</p>
<ul>
<li>Starting with API Level 4:
<ul>
<li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED}</li>
<li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}</li>
<li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_FOCUSED}</li>
</ul>
</li>
<li>Starting with API Level 14:
<ul>
<li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SCROLLED}</li>
<li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}</li>
<li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_EXIT}</li>
</ul>
</li>
</ul>
<p class="note"><strong>Note:</strong> Hover events are associated with the Explore by
Touch feature, which uses these events as triggers for providing audible prompts for user interface
elements.</p>
<p>In general, you should send an {@link android.view.accessibility.AccessibilityEvent} whenever the
content of your custom view changes. For example, if you are implementing a custom slider bar that
allows a user to select a numeric value by pressing the left or right arrows, your custom view
should emit an event of type {@link
android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED} whenever the slider
value changes. The following sample code demonstrates the use of the {@link
android.view.accessibility.AccessibilityEventSource#sendAccessibilityEvent
sendAccessibilityEvent()} method to report this event.</p>
<pre>
&#64;Override
public boolean onKeyUp (int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
mCurrentValue--;
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
return true;
}
...
}
</pre>
<h3 id="populate-events">Populating accessibility events</h3>
<p>Each {@link android.view.accessibility.AccessibilityEvent} has a set of required properties that
describe the current state of the view. These properties include things such as the views class
name, content description and checked state. The specific properties required for each event type
are described in the {@link android.view.accessibility.AccessibilityEvent} reference documentation.
The {@link android.view.View} implementation provides default values for these properties. Many of
these values, including the class name and event timestamp, are provided automatically. If you are
creating a custom view component, you must provide some information about the content and
characteristics of the view. This information may be as simple as a button label, but may also
include additional state information that you want to add to the event.</p>
<p>The minimum requirement for providing information to accessibility services with a custom
view is to implement {@link android.view.View#dispatchPopulateAccessibilityEvent
dispatchPopulateAccessibilityEvent()}. This method is called by the system to request
information for an {@link android.view.accessibility.AccessibilityEvent} and makes your custom
view compatible with accessibility services on Android 1.6 (API Level 4) and higher. The
following example code demonstrates a basic implementation of this method.</p>
<pre>
&#64;Override
public void dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
super.dispatchPopulateAccessibilityEvent(event);
// Call the super implementation to populate its text to the event, which
// calls onPopulateAccessibilityEvent() on API Level 14 and up.
// In case this is running on a API revision earlier that 14, check
// the text content of the event and add an appropriate text
// description for this custom view:
CharSequence text = getText();
if (!TextUtils.isEmpty(text)) {
event.getText().add(text);
}
}
</pre>
<p>On Android 4.0 (API Level 14) and higher, the {@link
android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} and
{@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}
methods are the recommended way to populate or modify the information in an {@link
android.view.accessibility.AccessibilityEvent}. Use the
{@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} method
specifically for adding or modifying the text content of the event, which is turned into audible
prompts by accessibility services such as TalkBack. Use the
{@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()} method for
populating additional information about the event, such as the selection state of the view.</p>
<p>In addition, you should also implement the
{@link android.view.View#onInitializeAccessibilityNodeInfo onInitializeAccessibilityNodeInfo()}
method. {@link android.view.accessibility.AccessibilityNodeInfo} objects populated by this method
are used by accessibility services to investigate the view hierarchy that generated an accessibility
event after receiving that event, to obtain a more detailed context information and provide
appropriate feedback to users.</p>
<p>The example code below shows how override these three methods by using
{@link android.support.v4.view.ViewCompat#setAccessibilityDelegate
ViewCompat.setAccessibilityDelegate()}. Note that this sample code requires that the Android
<a href="{@docRoot}sdk/compatibility-library.html">Support Library</a> for API Level 4 (revision 5
or higher) is added to your project.</p>
<pre>
ViewCompat.setAccessibilityDelegate(new AccessibilityDelegateCompat() {
&#64;Override
public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
super.onPopulateAccessibilityEvent(host, event);
// We call the super implementation to populate its text for the
// event. Then we add our text not present in a super class.
// Very often you only need to add the text for the custom view.
CharSequence text = getText();
if (!TextUtils.isEmpty(text)) {
event.getText().add(text);
}
}
&#64;Override
public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(host, event);
// We call the super implementation to let super classes
// set appropriate event properties. Then we add the new property
// (checked) which is not supported by a super class.
event.setChecked(isChecked());
}
&#64;Override
public void onInitializeAccessibilityNodeInfo(View host,
AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(host, info);
// We call the super implementation to let super classes set
// appropriate info properties. Then we add our properties
// (checkable and checked) which are not supported by a super class.
info.setCheckable(true);
info.setChecked(isChecked());
// Quite often you only need to add the text for the custom view.
CharSequence text = getText();
if (!TextUtils.isEmpty(text)) {
info.setText(text);
}
}
}
</pre>
<p>On applications targeting Android 4.0 (API Level 14) and higher, these methods can be implemented
directly in your custom view class. For another example of this approach, see the Android
<a href="{@docRoot}sdk/compatibility-library.html">Support Library</a> (revision 5 or higher) sample
{@code AccessibilityDelegateSupportActivity} in
({@code &lt;sdk&gt;/extras/android/support/v4/samples/Support4Demos/}).</p>
<p class="note"><strong>Note:</strong> You may find information on implementing accessibility for
custom views written prior to Android 4.0 that describes the use of the
{@link android.view.View#dispatchPopulateAccessibilityEvent dispatchPopulateAccessibilityEvent()}
method for populating AccessibilityEvents. As of the Android 4.0 release, however, the recommended
approach is to use the
{@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} and
{@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}
methods.</p>
<h2 id="test">Testing Accessibility</h2>
<p>Testing the accessibility of your application is an important part of ensuring your users have a
great experience. You can test the most important parts of accessibility by testing your application
with audible feedback enabled and testing navigation within your application using directional
controls.</p>
<h3 id="test-audibles">Testing audible feedback</h3>
<p>You can simulate the experience for many users by enabling an accessibility service that speaks
as you move around the screen. The Explore by Touch accessibility service, which is available on
devices with Android 4.0 and later. The <a
href="https://play.google.com/store/apps/details?id=com.google.android.marvin.talkback">TalkBack</a>
accessibility service, by the <a href="http://code.google.com/p/eyes-free/">Eyes-Free
Project</a> comes preinstalled on many Android devices.</p>
<p>To enable TalkBack on revisions of Android prior to Android 4.0:</p>
<ol>
<li>Launch the Settings application.</li>
<li>Navigate to the <strong>Accessibility</strong> category and select it.</li>
<li>Select <strong>Accessibility</strong> to enable it.</li>
<li>Select <strong>TalkBack</strong> to enable it.</li>
</ol>
<p class="note"><strong>Note:</strong> If the TalkBack accessibility service is not available, you
can install it for free from <a href="http://play.google.com">Google Play</a>.</p>
<p>To enable Explore by Touch on Android 4.0 and later:</p>
<ol>
<li>Launch the Settings application.</li>
<li>Navigate to the <strong>Accessibility</strong> category and select it.</li>
<li>Select the <strong>TalkBack</strong> to enable it.</li>
<li>Return to the <strong>Accessibility</strong> category and select <strong>Explore by
Touch</strong> to enable it.
<p class="note"><strong>Note:</strong> You must turn on TalkBack <em>first</em>, otherwise this
option is not available.</p>
</li>
</ol>
<h3 id="test-navigation">Testing focus navigation</h3>
<p>As part of your accessibility testing, you can test navigation of your application using focus,
even if your test devices does not have a directional controller. The <a
href="{@docRoot}guide/developing/tools/emulator.html">Android Emulator</a> provides a
simulated directional controller that you can easily use to test navigation. You can also use the
arrow keys and Enter key on your keyboard with the Emulator to simulate use of a D-pad.</p>

View File

@@ -0,0 +1,55 @@
page.title=Accessibility
parent.title=User Interface
parent.link=../index.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>Topics</h2>
<ol>
<li><a href="{@docRoot}guide/topics/ui/accessibility/apps.html">Making Applications Accessible</a>
</li>
<li><a href="{@docRoot}guide/topics/ui/accessibility/services.html">Building Accessibility
Services</a></li>
</ol>
<h2>Key classes</h2>
<ol>
<li>{@link android.view.accessibility.AccessibilityEvent}</li>
<li>{@link android.accessibilityservice.AccessibilityService}</li>
</ol>
<h2>See also</h2>
<ol>
<li><a href="{@docRoot}training/accessibility/index.html">Implementing Accessibility</a></li>
</ol>
</div>
</div>
<p>Many Android users have disabilities that require them to interact with their Android devices in
different ways. These include users who have visual, physical or age-related disabilities that
prevent them from fully seeing or using a touchscreen.</p>
<p>Android provides accessibility features and services for helping these users navigate their
devices more easily, including text-to-speech, haptic feedback, trackball and D-pad navigation that
augment their experience. Android application developers can take advantage of these services to
make their applications more accessible and also build their own accessibility services.</p>
<p>The following topics show you how to use the Android framework to make applications more
accessible.</p>
<dl>
<dt><strong><a href="{@docRoot}guide/topics/ui/accessibility/apps.html">Making Applications
Accessible</a></strong>
</dt>
<dd>Development practices and API features to ensure your application is accessible to users with
disabilities.</dd>
<dt><strong><a href="{@docRoot}guide/topics/ui/accessibility/service.html">Building Accessibility
Services</a></strong>
</dt>
<dd>How to use API features to build services that make other applications more accessible for
users.</dd>
</dl>

View File

@@ -0,0 +1,290 @@
page.title=Building Accessibility Services
parent.title=Accessibility
parent.link=index.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>Topics</h2>
<ol>
<li><a href="#manifest">Manifest Declarations and Permissions</a>
<ol>
<li><a href="service-declaration">Accessibility service declaration</a></li>
<li><a href="#service-config">Accessibility service configuration</a></li>
</ol>
</li>
<li><a href="#methods">AccessibilityService Methods</a></li>
<li><a href="#event-details">Getting Event Details</a></li>
<li><a href="#examples">Example Code</a></li>
</ol>
<h2>Key classes</h2>
<ol>
<li>{@link android.accessibilityservice.AccessibilityService}</li>
<li>{@link android.accessibilityservice.AccessibilityServiceInfo}</li>
<li>{@link android.view.accessibility.AccessibilityEvent}</li>
<li>{@link android.view.accessibility.AccessibilityRecord}</li>
<li>{@link android.view.accessibility.AccessibilityNodeInfo}</li>
</ol>
<h2>See also</h2>
<ol>
<li><a href="{@docRoot}training/accessibility/index.html">Implementing Accessibility</a></li>
</ol>
</div>
</div>
<p>An accessibility service is an application that provides user interface enhancements to
assist users with disabilities, or who may temporarily be unable to fully interact with a device.
For example, users who are driving, taking care of a young child or attending a very loud party
might need additional or alternative interface feedback.</p>
<p>Android provides standard accessibility services, including TalkBack, and developers can
create and distribute their own services. This document explains the basics of building an
accessibility service.</p>
<p>The ability for you to build and deploy accessibility services was introduced with Android
1.6 (API Level 4) and received significant improvements with Android 4.0 (API Level 14). The Android
Support Library was also updated with the release of Android 4.0 to provide support for these
enhanced accessibility features back to Android 1.6. Developers aiming for widely compatible
accessibility services are encouraged to use the
<a href="{@docRoot}sdk/compatibility-library.html">Support Library</a> and develop for the more
advanced accessibility features introduced in Android 4.0.</p>
<h2 id="manifest">Manifest Declarations and Permissions</h2>
<p>Applications that provide accessibility services must include specific declarations in their
application manifests in order to be treated as an accessibility service by an Android system.
This section explains the required and optional settings for accessibility services.</p>
<h3 id="service-declaration">Accessibility service declaration</h3>
<p>In order to be treated as an accessibility service, your application must include the
{@code service} element (rather than the {@code activity} element) within the {@code application}
element in its manifest. In addition, within the {@code service} element, you must also include an
accessibility service intent filter, as shown in the following sample:</p>
<pre>
&lt;application&gt;
&lt;service android:name=&quot;.MyAccessibilityService&quot;
android:label=&quot;@string/accessibility_service_label&quot;&gt;
&lt;intent-filter&gt;
&lt;action android:name=&quot;android.accessibilityservice.AccessibilityService&quot; /&gt;
&lt;/intent-filter&gt;
&lt;/service&gt;
&lt;/application&gt;
</pre>
<p>These declarations are required for all accessibility services deployed on Android 1.6 (API Level
4) or higher.</p>
<h3 id="service-config">Accessibility service configuration</h3>
<p>Accessibility services must also provide a configuration which specifies the types of
accessibility events that the service handles and additional information about the service. The
configuration of an accessibility service is contained in the {@link
android.accessibilityservice.AccessibilityServiceInfo} class. Your service can build and set a
configuration using an instance of this class and {@link
android.accessibilityservice.AccessibilityService#setServiceInfo setServiceInfo()} at runtime.
However, not all configuration options are available using this method.</p>
<p>Beginning with Android 4.0, you can include a {@code &lt;meta-data&gt;} element in your manifest
with a reference to a configuration file, which allows you to set the full range of options for
your accessibility service, as shown in the following example:</p>
<pre>
&lt;service android:name=&quot;.MyAccessibilityService&quot;&gt;
...
&lt;meta-data
android:name=&quot;android.accessibilityservice&quot;
android:resource=&quot;@xml/accessibility_service_config&quot; /&gt;
&lt;/service&gt;
</pre>
<p>This meta-data element refers to an XML file that you create in your applications resource
directory ({@code &lt;project_dir&gt;/res/xml/accessibility_service_config.xml}). The following code
shows example contents for the service configuration file:</p>
<pre>
&lt;accessibility-service xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
android:description=&quot;@string/accessibility_service_description&quot;
android:packageNames=&quot;com.example.android.apis&quot;
android:accessibilityEventTypes=&quot;typeAllMask&quot;
android:accessibilityFlags=&quot;flagDefault&quot;
android:accessibilityFeedbackType=&quot;feedbackSpoken&quot;
android:notificationTimeout=&quot;100&quot;
android:canRetrieveWindowContent=&quot;true&quot;
android:settingsActivity=&quot;com.example.android.accessibility.ServiceSettingsActivity&quot;
/&gt;
</pre>
<p>One of the most important functions of the accessibility service configuration parameters is to
allow you to specify what types of accessibility events your service can handle. Being able to
specify this information enables accessibility services to cooperate with each other, and allows you
as a developer the flexibility to handle only specific events types from specific applications. The
event filtering can include the following criteria:</p>
<ul>
<li><strong>Package Names</strong> - Specify the package names of applications whose accessibility
events you want your service to handle. If this parameter is omitted, your accessibility service is
considered available to service accessibility events for any application. This parameter can be set
in the accessibility service configuration files with the {@code android:packageNames} attribute as
a comma-separated list, or set using the {@link
android.accessibilityservice.AccessibilityServiceInfo#packageNames
AccessibilityServiceInfo.packageNames} member.</li>
<li><strong>Event Types</strong> - Specify the types of accessibility events you want your service
to handle. This parameter can be set in the accessibility service configuration files with the
{@code android:accessibilityEventTypes} attribute as a comma-separated list, or set using the
{@link android.accessibilityservice.AccessibilityServiceInfo#eventTypes
AccessibilityServiceInfo.eventTypes} member. </li>
</ul>
<p>For more information about the XML attributes which can be used in the accessibility service
configuration file, follow these links to the reference documentation:</p>
<ul>
<li><a href="{@docRoot}reference/android/R.styleable.html#AccessibilityService_description">{@code android:description}</a></li>
<li><a href="{@docRoot}reference/android/R.styleable.html#AccessibilityService_packageNames">{@code android:packageNames}</a></li>
<li><a href="{@docRoot}reference/android/R.styleable.html#AccessibilityService_accessibilityEventTypes">{@code android:accessibilityEventTypes}</a></li>
<li><a href="{@docRoot}reference/android/R.styleable.html#AccessibilityService_accessibilityFlags">{@code android:accessibilityFlags}</a></li>
<li><a href="{@docRoot}reference/android/R.styleable.html#AccessibilityService_accessibilityFeedbackType">{@code android:accessibilityFeedbackType}</a></li>
<li><a href="{@docRoot}reference/android/R.styleable.html#AccessibilityService_notificationTimeout">{@code android:notificationTimeout}</a></li>
<li><a href="{@docRoot}reference/android/R.styleable.html#AccessibilityService_canRetrieveWindowContent">{@code android:canRetrieveWindowContent}</a></li>
<li><a href="{@docRoot}reference/android/R.styleable.html#AccessibilityService_settingsActivity">{@code android:settingsActivity}</a></li>
</ul>
<p>For more information about which configuration settings can be dynamically set at runtime, see
the {@link android.accessibilityservice.AccessibilityServiceInfo} reference documentation.</p>
<h2 id="methods">AccessibilityService Methods</h2>
<p>An application that provides accessibility service must extend the {@link
android.accessibilityservice.AccessibilityService} class and override the following methods from
that class. These methods are presented in the order in which they are called by the Android system,
from when the service is started
({@link android.accessibilityservice.AccessibilityService#onServiceConnected onServiceConnected()}),
while it is running ({@link android.accessibilityservice.AccessibilityService#onAccessibilityEvent
onAccessibilityEvent()},
{@link android.accessibilityservice.AccessibilityService#onInterrupt onInterrupt()}) to when it is
shut down ({@link android.accessibilityservice.AccessibilityService#onUnbind onUnbind()}).</p>
<ul>
<li>{@link android.accessibilityservice.AccessibilityService#onServiceConnected
onServiceConnected()} - (optional) This system calls this method when it successfully connects to
your accessibility service. Use this method to do any one-time setup steps for your service,
including connecting to user feedback system services, such as the audio manager or device vibrator.
If you want to set the configuration of your service at runtime or make one-time adjustments, this
is a convenient location from which to call {@link
android.accessibilityservice.AccessibilityService#setServiceInfo setServiceInfo()}.</li>
<li>{@link android.accessibilityservice.AccessibilityService#onAccessibilityEvent
onAccessibilityEvent()} - (required) This method is called back by the system when it detects an
{@link android.view.accessibility.AccessibilityEvent} that matches the event filtering parameters
specified by your accessibility service. For example, when the user clicks a button or focuses on a
user interface control in an application for which your accessibility service is providing feedback.
When this happens, the system calls this method of your service with the associated {@link
android.view.accessibility.AccessibilityEvent}, which you can then interpret and provide feedback to
the user. This method may be called many times over the lifecycle of your service.</li>
<li>{@link android.accessibilityservice.AccessibilityService#onInterrupt onInterrupt()} -
(required) This method is called when the system wants to interrupt the feedback your service is
providing, usually in response to a user taking action, such as moving focus to a different user
interface control than the one for which you are currently providing feedback. This method may be
called many times over the lifecycle of your service.</li>
<li>{@link android.accessibilityservice.AccessibilityService#onUnbind onUnbind()} - (optional)
This method is called when the system is about to shutdown the accessibility service. Use this
method to do any one-time shutdown procedures, including de-allocating user feedback system
services, such as the audio manager or device vibrator.</li>
</ul>
<p>These callback methods provide the basic structure for your accessibility service. It is up to
you to decide on how to process data provided by the Android system in the form of {@link
android.view.accessibility.AccessibilityEvent} objects and provide feedback to the user.</p>
<h2 id="event-details">Getting Event Details</h2>
<p>The Android system provides information to accessibility services about the user interface
interaction through {@link android.view.accessibility.AccessibilityEvent} objects. Prior to Android
4.0, the information available in an accessibility event, while providing a significant amount of
detail about a user interface control selected by the user, typically provided limited contextual
information. In many cases, this missing context information might be critical to understanding the
meaning of the selected control.</p>
<p>A typical example of an interface where context is of critical importance is a calendar or day
planner. If a user selects a 4:00 PM time slot in a Monday to Friday day list and the accessibility
service announces “4 PM”, but fails to indicate this is a Friday a Monday, the month or day, this is
hardly ideal feedback for the user. In this case, the context of a user interface control is of
critical importance to a user who wants to schedule a meeting.</p>
<p>Android 4.0 significantly extends the amount of information that an accessibility service can
obtain about an user interface interaction by composing accessibility events based on the view
hierarchy. A view hierarchy is the set of user interface components that contain the component (its
parents) and the user interface elements that may be contained by that component (its children). In
this way, the Android system can provide much richer detail about accessibility events, allowing
accessibility services to provide more useful feedback to users.</p>
<p>An accessibility service gets information about an user interface event through an {@link
android.view.accessibility.AccessibilityEvent} passed by the system to the services
{@link android.accessibilityservice.AccessibilityService#onAccessibilityEvent
onAccessibilityEvent()} callback method. This object provides details about the event, including the
type of object being acted upon, its descriptive text and other details. Starting in Android 4.0
(and supported in previous releases through the {@link
android.support.v4.view.accessibility.AccessibilityEventCompat} object in the Support Library), you
can obtain additional information about the event using these calls:</p>
<ul>
<li>{@link android.view.accessibility.AccessibilityEvent#getRecordCount
AccessibilityEvent.getRecordCount()} and {@link
android.view.accessibility.AccessibilityEvent#getRecord getRecord(int)} - These methods allow you to
retrieve the set of {@link android.view.accessibility.AccessibilityRecord} objects which contributed
to the {@link android.view.accessibility.AccessibilityEvent} passed to you by the system, which can
provide more context for your accessibility service.</li>
<li>{@link android.view.accessibility.AccessibilityEvent#getSource
AccessibilityEvent.getSource()} - This method returns an {@link
android.view.accessibility.AccessibilityNodeInfo} object. This object allows you to request the
parents and children of the component that originated the accessibility event and investigate their
contents and state in order to provide
<p class="caution"><strong>Important:</strong> The ability to investigate the full view
hierarchy from an {@link android.view.accessibility.AccessibilityEvent} potentially exposes private
user information to your accessibility service. For this reason, your service must request this
level of access through the accessibility <a href="#service-config">service configuration XML</a>
file, by including the {@code canRetrieveWindowContent} attribute and setting it to {@code true}. If
you do not include this setting in your service configuration xml file, calls to {@link
android.view.accessibility.AccessibilityEvent#getSource getSource()} fail.</p>
</li>
</ul>
<h2 id="examples">Example Code</h2>
<p>The API Demo project contains two samples which can be used as a starting point for generating
accessibility services
({@code &lt;sdk&gt;/samples/&lt;platform&gt;/ApiDemos/src/com/example/android/apis/accessibility}):
</p>
<ul>
<li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/accessibility/ClockBackService.html">ClockBackService</a>
- This service is based on the original implementation of {@link
android.accessibilityservice.AccessibilityService} and can be used as a base for developing basic
accessibility services that are compatible with Android 1.6 (API Level 4) and higher.</li>
<li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/accessibility/TaskBackService.html">TaskBackService</a>
- This service is based on the enhanced accessibility APIs introduced in Android 4.0 (API Level
14). However, you can use the Android <a href="{@docRoot}sdk/compatibility-library.html">Support
Libary</a> to substitute classes introduced in later API levels (e.g.,
{@link android.view.accessibility.AccessibilityRecord},
{@link android.view.accessibility.AccessibilityNodeInfo}
) with equivalent support package classes (e.g.,
{@link android.support.v4.view.accessibility.AccessibilityRecordCompat},
{@link android.support.v4.view.accessibility.AccessibilityNodeInfoCompat}
) to make this example work with API versions back to Android 1.6 (API Level 4).</li>
</ul>