diff options
author | Joe Fernandez <joefernandez@google.com> | 2012-04-03 10:11:59 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2012-04-03 10:11:59 -0700 |
commit | 110414928ae13674b7ec6b816a45cf70ed521683 (patch) | |
tree | f6956e7a836d764b75eb4a07a0d61eb6e2d075a7 | |
parent | 234a369b8de56fa418f8d92ee732b930bfc9cf54 (diff) | |
parent | c1a0e54de12aee41163b84a25ea8dfc8b64304dc (diff) | |
download | frameworks_base-110414928ae13674b7ec6b816a45cf70ed521683.zip frameworks_base-110414928ae13674b7ec6b816a45cf70ed521683.tar.gz frameworks_base-110414928ae13674b7ec6b816a45cf70ed521683.tar.bz2 |
am c1a0e54d: am b459b619: am 945b7cb3: Merge "docs: Accessibility Dev Guide (subsumes Accessibility Best Practices)" into ics-mr1
* commit 'c1a0e54de12aee41163b84a25ea8dfc8b64304dc':
docs: Accessibility Dev Guide (subsumes Accessibility Best Practices)
14 files changed, 994 insertions, 355 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index 9ebbe03..ddd7f7c 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -37,6 +37,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 diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java index b55fda4..8e53431 100644 --- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java @@ -42,6 +42,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 diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 18e1697..69d7655 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -15901,6 +15901,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 diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java index 58844fc..0998c80 100644 --- a/core/java/android/view/accessibility/AccessibilityEvent.java +++ b/core/java/android/view/accessibility/AccessibilityEvent.java @@ -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> diff --git a/core/java/android/view/accessibility/AccessibilityEventSource.java b/core/java/android/view/accessibility/AccessibilityEventSource.java index f11880b..525ba9e 100644 --- a/core/java/android/view/accessibility/AccessibilityEventSource.java +++ b/core/java/android/view/accessibility/AccessibilityEventSource.java @@ -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 { diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index 03c6211..f616dca 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -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 diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java index bc6074f..d25b3db 100644 --- a/core/java/android/view/accessibility/AccessibilityRecord.java +++ b/core/java/android/view/accessibility/AccessibilityRecord.java @@ -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 diff --git a/core/java/android/view/accessibility/package.html b/core/java/android/view/accessibility/package.html index 4afafd3..c2da0ae 100644 --- a/core/java/android/view/accessibility/package.html +++ b/core/java/android/view/accessibility/package.html @@ -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> diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index 92bc83e..ec87de8 100644 --- a/docs/html/guide/guide_toc.cs +++ b/docs/html/guide/guide_toc.cs @@ -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> diff --git a/docs/html/guide/practices/design/accessibility.html b/docs/html/guide/practices/design/accessibility.html new file mode 100644 index 0000000..0fa7b32 --- /dev/null +++ b/docs/html/guide/practices/design/accessibility.html @@ -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>
\ No newline at end of file diff --git a/docs/html/guide/practices/design/accessibility.jd b/docs/html/guide/practices/design/accessibility.jd deleted file mode 100644 index 72da04e..0000000 --- a/docs/html/guide/practices/design/accessibility.jd +++ /dev/null @@ -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 Application’s 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 that’s 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> -<LinearLayout android:orientation="horizontal" - ... > - <EditText android:id="@+id/edit" - android:nextFocusDown=”@+id/text” - ... /> - <TextView android:id="@+id/text" - android:focusable=”true” - android:text="Hello, I am a focusable TextView" - android:nextFocusUp=”@id/edit” - ... /> -</LinearLayout> -</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> -<ImageButton - android:id=”@+id/add_entry_button” - android:src=”@drawable/plus” - android:contentDescription=”@string/add_note”/> -</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 application’s 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> -@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 view’s 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> -@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 Application’s 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> diff --git a/docs/html/guide/topics/ui/accessibility/apps.jd b/docs/html/guide/topics/ui/accessibility/apps.jd new file mode 100644 index 0000000..ff34be6 --- /dev/null +++ b/docs/html/guide/topics/ui/accessibility/apps.jd @@ -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> +<ImageButton + android:id=”@+id/add_note_button” + android:src=”@drawable/add_note” + android:contentDescription=”@string/add_note”/> +</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 control’s 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> +<LinearLayout android:orientation="horizontal" + ... > + <EditText android:id="@+id/edit" + android:nextFocusDown=”@+id/text” + ... /> + <TextView android:id="@+id/text" + android:focusable=”true” + android:text="Hello, I am a focusable TextView" + android:nextFocusUp=”@id/edit” + ... /> +</LinearLayout> +</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 <sdk>/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> +@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 view’s 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> +@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() { + @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); + } + } + @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()); + } + @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 <sdk>/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> diff --git a/docs/html/guide/topics/ui/accessibility/index.jd b/docs/html/guide/topics/ui/accessibility/index.jd new file mode 100644 index 0000000..414d5f3 --- /dev/null +++ b/docs/html/guide/topics/ui/accessibility/index.jd @@ -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>
\ No newline at end of file diff --git a/docs/html/guide/topics/ui/accessibility/services.jd b/docs/html/guide/topics/ui/accessibility/services.jd new file mode 100644 index 0000000..0dad4ec --- /dev/null +++ b/docs/html/guide/topics/ui/accessibility/services.jd @@ -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> +<application> + <service android:name=".MyAccessibilityService" + android:label="@string/accessibility_service_label"> + <intent-filter> + <action android:name="android.accessibilityservice.AccessibilityService" /> + </intent-filter> + </service> +</application> +</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 <meta-data>} 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> +<service android:name=".MyAccessibilityService"> + ... + <meta-data + android:name="android.accessibilityservice" + android:resource="@xml/accessibility_service_config" /> +</service> +</pre> + +<p>This meta-data element refers to an XML file that you create in your application’s resource +directory ({@code <project_dir>/res/xml/accessibility_service_config.xml}). The following code +shows example contents for the service configuration file:</p> + +<pre> +<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" + android:description="@string/accessibility_service_description" + android:packageNames="com.example.android.apis" + android:accessibilityEventTypes="typeAllMask" + android:accessibilityFlags="flagDefault" + android:accessibilityFeedbackType="feedbackSpoken" + android:notificationTimeout="100" + android:canRetrieveWindowContent="true" + android:settingsActivity="com.example.android.accessibility.ServiceSettingsActivity" +/> +</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 service’s +{@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 <sdk>/samples/<platform>/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> |