
page.title=Developing Accessible Applications
parent.title=Implementing Accessibility
parent.link=index.html

trainingnavtop=true
next.title=Developing an Accessibility Service
next.link=service.html

@jd:body




<div id="tb-wrapper">
<div id="tb">

<h2>This lesson teaches you to</h2>
<ol>
  <li><a href="#contentdesc">Add Content Descriptions</a></li>
  <li><a href="#focus">Design for Focus Navigation</a></li>
  <li><a href="#events">Fire Accessibility Events</a></li>
  <li><a href="#testing">Test Your Application</a></li>
</ol>

<!-- other docs (NOT javadocs) -->
<h2>You should also read</h2>
<ul>
  <li><a href="{@docRoot}guide/topics/ui/accessibility/apps.html">Making
    Applications Accessible</a></li>
</ul>


</div>
</div>

<p>Android has several accessibility-focused features baked into the platform,
which make it easy to optimize your application for those with visual or
physical disabilities.  However, it's not always obvious what the correct
optimizations are, or the easiest way to leverage the framework toward this
purpose.  This lesson shows you how to implement the strategies and platform
features that make for a great accessibility-enabled Android application.</p>

<h2 id="contentdesc">Add Content Descriptions</h2>
<p>A well-designed user interface (UI) often has elements that don't require an explicit
label to indicate their purpose to the user.  A checkbox next to an item in a
task list application has a fairly obvious purpose, as does a trash can in a file
manager application.  However, to your users with vision impairment, other UI
cues are needed.</p>

<p>Fortunately, it's easy to add labels to UI elements in your application that
can be read out loud to your user by a speech-based accessibility service like <a
href="https://play.google.com/store/apps/details?id=com.google.android.marvin.talkback">TalkBack</a>
.
If you have a label that's likely not to change during the lifecycle of the
application (such as "Pause" or "Purchase"), you can add it via the XML layout,
by setting a UI element's <a
 
href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription"
>{@code android:contentDescription}</a> attribute, like in this
example:</p>
<pre>
&lt;Button
    android:id=”@+id/pause_button”
    android:src=”@drawable/pause”
    android:contentDescription=”@string/pause”/&gt;
</pre>

<p>However, there are plenty of situations where it's desirable to base the content
description on some context, such as the state of a toggle button, or a piece
selectable data like a list item.  To edit the content description at runtime,
use the {@link android.view.View#setContentDescription(CharSequence)
setContentDescription()} method, like this:</p>

<pre>
String contentDescription = "Select " + strValues[position];
label.setContentDescription(contentDescription);
</pre>

<p>This addition to your code is the simplest accessibility improvement you can make to your
application, but one of the most useful.  Try to add content descriptions
wherever there's useful information, but avoid the web-developer pitfall of
labelling <em>everything</em> with useless information.  For instance, don't set
an application icon's content description to "app icon".  That just increases
the noise a user needs to navigate in order to pull useful information from your
interface.</p>

<p>Try it out!  Download <a
href="https://play.google.com/store/apps/details?id=com.google.android.marvin.talkback">TalkBack</a>
(an accessibility service published by Google) and enable it in <strong>Settings
  &gt; Accessibility &gt; TalkBack</strong>.  Then navigate around your own
application and listen for the audible cues provided by TalkBack.</p>

<h2 id="focus">Design for Focus Navigation</h2>
<p>Your application should support more methods of navigation than the
touch screen alone.  Many Android devices come with navigation hardware other
than the touchscreen, like a D-Pad, arrow keys, or a trackball.  In addition,
later Android releases also support connecting external devices like keyboards
via USB or bluetooth.</p>

<p>In order to enable this form of navigation, all navigational elements that
the user should be able to navigate to need to be set as focusable.  This
modification can be
done at runtime using the
{@link android.view.View#setFocusable View.setFocusable()} method on that UI
control, or by setting the <a
  href="{@docRoot}reference/android/view/View.html#attr_android:focusable">{@code
  android:focusable}</a>
attrubute in your XML layout files.</p>

<p>Also, each UI control has 4 attributes,
<a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusUp">{@code
  android:nextFocusUp}</a>,
<a
  href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown">{@code
  android:nextFocusDown}</a>,
<a
  href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusLeft">{@code
  android:nextFocusLeft}</a>,
and <a
  href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusRight">{@code
  android:nextFocusRight}</a>,
which you can use to designate
the next view to receive focus when the user navigates in that direction.  While
the platform determines navigation sequences automatically based on layout
proximity, you can use these attributes to override that sequence if it isn't
appropriate in your application. </p>

<p>For instance, here's how you represent a button and label, both
focusable, such that pressing down takes you from the button to the text view, and
pressing up would take you back to the button.</p>


<pre>
&lt;Button android:id="@+id/doSomething"
    android:focusable="true"
    android:nextFocusDown=”@id/label”
    ... /&gt;
&lt;TextView android:id="@+id/label"
    android:focusable=”true”
    android:text="@string/labelText"
    android:nextFocusUp=”@id/doSomething”
    ... /&gt;
</pre>

<p>Verify that your application works intuitively in these situations.  The
easiest way is to simply run your application in the Android emulator, and
navigate around the UI with the emulator's arrow keys, using the OK button as a
replacement for touch to select UI controls.</p>

<h2 id="events">Fire Accessibility Events</h2>
<p>If you're using the view components in the Android framework, an
{@link android.view.accessibility.AccessibilityEvent} is created whenever you
select an item or change focus in your UI.  These events are examined by the
accessibility service, enabling it to provide features like text-to-speech to
the user.</p>

<p>If you write a custom view, make sure it fires events at the appropriate
times. Generate events by calling {@link
android.view.View#sendAccessibilityEvent(int)}, with a parameter representing
the type of event that occurred.  A complete list of the event types currently
supported can be found in the {@link
android.view.accessibility.AccessibilityEvent} reference documentation.

<p>As an example, if you want to extend an image view such that you can write
captions by typing on the keyboard when it has focus, it makes sense to fire an 
{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}
event, even though that's not normally built into image views.  The code to
generate that event would look like this:</p>
<pre>
public void onTextChanged(String before, String after) {
    ...
    if (AccessibilityManager.getInstance(mContext).isEnabled()) {
        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
    }
    ...
}
</pre>

<h2 id="testing">Test Your Application</h2>
<p>Be sure to test the accessibility functionality as you add it to your
application.  In order to test the content descriptions and Accessibility
events, install and enable an accessibility service.  One option is <a
href="https://play.google.com/store/apps/details?id=com.google.android.marvin.talkback">Talkback</a>
,
a free, open source screen reader available on Google Play.  With the service
enabled, test all the navigation flows through your application and listen to
the spoken feedback.</p>

<p>Also, attempt to navigate your application using a directional controller,
instead of the touch screen.  You can use a physical device with a d-pad or
trackball if one is available.  If not, use the Android emulator and it's
simulated keyboard controls.</p>

<p>Between the service providing feedback and the directional navigation through
your application, you should get a sense of what your application is like to
navigate without any visual cues.  Fix problem areas as they appear, and you'll
end up with with a more accessible Android application.</p>
