Programming an accessible Android app is not technically difficult, but is often skipped in the rush of a deadline. With the right tools, skipping accessibility is a compromise you don’t have to make. Here are some ways to help your team ensure that accessibility is added and part of testing your final product.
Accessibility Scanner application
Last month at the CSUN International Technology and Persons with Disabilities Conference, Google’s accessibility team announced a new tool called Accessibility Scanner. This app is free to download, and is the easiest way to quickly find issues with your application’s accessibility.
Download the app to your test device, turn on accessibility scanner in Settings → Accessibility → Accessibility Scanner. Open up the app you’d like to test, then tap on the floating blue check mark.
Once the scanner is running, open up the application you’d like to test, and tap the floating blue circle. This will scan the current screen and display an orange box around potential accessibility issues. Tapping on the orange box displays a summary about that specific issue, and even a link to detailed documentation about how to fix it.
The scanner app is a great tool for quick sanity checks, but it does not cover everything. For example, in the previous screenshot the scanner did not pick up that the image of the robot was actually missing a content description. You’ll definitely want to manually test your app as well.
Manual testing
To perform manual testing turn on TalkBack, the Android screen reader. This will help you navigate your application the same way visually impaired users do. It will also help you understand how mobility impaired users navigate your application; any elements highlighted by a green box in TalkBack is also accessible using a d-pad or switch.
To turn on TalkBack, go to Settings → Accessibility → TalkBack and switch it on.
When TalkBack is on, navigating through the app will be slightly different than usual. Navigate to different elements by swiping right or left across the screen. Double tap anywhere to select an item, and scroll through lists using two fingers at once.
As you navigate through your app, be on the lookout for any pieces of your application that may be hidden to a user relying on assistive technology.
Lint rules
While manual testing is the best way to perform accessibility testing, there are
some pieces you can automate as well. One easy way is to modify your linter to
fail the build if you have any ImageView
or ImageButton
elements missing a
contentDescription
. There’s no excuse for not including contentDescription
on images. If your image is decorative only, set your contentDescription
to
@null
so TalkBack explicitly knows to skip it.
First, set the lint severity for missing contentDescription
via the GUI by
going to Preferences → Editor → Inspections → Android > Lint > Accessibility →
Image without contentDescription
, and set the Severity to Error.
Now you will see a red underline on any code which is missing a
contentDescription
. The Android lint documentation states that this step
will also automatically create a lint.xml
file for you, but as of Android
Studio 2.1, this still does not happen. To finish your lint setup, create a new
lint.xml
file manually at the top level in your module, and set the severity
like this:
<?xml version="1.0" encoding="UTF-8"?>
<lint>
<issue id="ContentDescription" severity="error" />
</lint>
Now that the issue severity is set, you just need to fail the build on a lint
error. In your module level build.gradle
file, within the android
task, add
the following code:
lintOptions {
abortOnError true
}
Remember that the green play button on Android Studio runs the assembleDebug
task by default (which does not include lint checking), so check your setup by
running a command line gradle build
.
While lint rules are great in helping you to add a contentDescription
, they
don’t check if the description is meaningful. For that we can use Espresso
tests.
Espresso tests
Espresso is the automated UI testing framework for Android. This can allow us
to verify that our contentDescription
s are meaningful, and also allow us to
verify situations where we must dynamically modify the contentDescription
. An
example of a dynamic contentDescription
is shown below, with the Play/Pause
button. This ImageButton
contains no words, so a screen reader won’t be able
to convey its meaning without a contentDescription
. Based on the state of the
media player, the button will either be a Play symbol or a Pause symbol. As the
symbol on the button changes, so should the contentDescription
.
We want to verify that our contentDescription
begins as “Play,”, matching the
initial symbol. When we click the button, we want to verify that the
contentDescription
then changes to “Pause”. When we click the button again,
we want to verify the contentDescription
changes back to “Play”.
Here is an example Espresso test method in Kotlin which will verify this for us:
@Test
fun testPlayPauseDescription() {
val playPauseInteraction = onView(withId(R.id.button_play_pause))
playPauseInteraction.check(matches(withContentDescription("Play")))
playPauseInteraction.perform(click())
playPauseInteraction.check(matches(withContentDescription("Pause")))
playPauseInteraction.perform(click())
playPauseInteraction.check(matches(withContentDescription("Play")))
}
The hardest part of adding accessibility support to your Android application is just remembering to do it! Use these suggestions and your team can build Android applications that everyone can use.