How VRT puts accessibility first

At VRT we have always had a focus on accessibility.
So it came only natural to us to give the same treatment to our mobile applications. This devotion from our mobile team did not go unnoticed. 
The accessibility-event held annually at the VRT consists of an external jury, judging new products.

In 2017 and again in 2018 we won the accessibility trophy for both the Sporza Voetbal — and the VRT NWS app respectively.

Historically accessibility users have always gravitated more toward iOS rather than Android since iOS at the time invested more into this field. 
However, a shift has been going on in recent years from Google that shows Android is catching up. 
The only thing needed to break this vicious circle is making Android developers aware and use the provided APIs. 
In this technical blog post I will therefore share our experiences and tools we used when we made our apps more accessible.

Developer vs OS

A first distinction to make is what should be handled on an OS level and what should be implemented by you as a developer.

Out of the box Android enables settings for users with the most common disabilities. Think about the elderly, or people with bad eyesight in general having trouble noticing small text and icons on screen.
Also people with color blindness should ideally have one setting that applies color correction.
Android has got your back and exposes these user settings for not just your app but system-wide.

Scale Text

You can find the font increasing system setting under Settings > Display > Font Size. One caveat though is that developers still need to specify explicitly that a certain text can scale in font size. More about this later.

Scaling the Whole UI

Scaling only text might not be enough. Likewise, icons and other important visual widgets might be rendered too small.
So one other (better?) idea is to scale the whole UI.
This feature can be enabled under Settings > Display > Display Size.

However, this feature was only introduced in Android 7.0 (Nougat) so only more recent devices can benefit from this.

The upside to this is that there is 0% extra work that needs to be done by the developer.

Color Correction

Another option Android provides is the color correction.
This allows color blind people to perceive the correct colors.
Android provides three most common color corrections:

  • Deuteranomaly (red-green)
  • Protanomally (red-green)
  • Tritanomally (blue-yellow)

You can apply this color correction system wide. So there is no need for you as a developer to implement this feature in your app.

The setting is under Settings > Accessibility > Color Correction

Your accessibility user

Just as there are different Android versions there are also a lot of different accessibility users:

  • Physical disability
  • Intellectual disability

Having one app to suit them all is ambitious therefore we took the physical disability as our main focus group.

To understand what you should do to improve your app for this group it is crucial to understand how they interact with their Android smartphone.

Blindness

Visual impaired users navigate your app by using another app that makes use of the accessibility APIs.

Most notably or best known is the Talkback app from Google.
Talkback is factory installed on any Android device and is updated just like any other app regardless of Android version.
This ensures you will always get to enjoy the latest features.
Talkback is what they call a screen reader and audibly informs the user of anything that is going on at the screen.

The way Talkback works is by simply touching the display, Talkback will first vibrate to let you know your touch has been registered and then tell you what is currently being touched on the screen.
More advanced users will most likely benefit from using gestures to navigate around an app.
These custom gestures include navigating up, go to the next/previous item, opening the context menu or simply read everything on screen.

Gesture based Talkback

Therefore making sure all your views have the correct content description and have a logical layout is paramount.
A blind user should be able to have a visual map inside their head of were things are placed on screen. 
This is yet another reason you can give your designer as to why you are better off sticking to the Material spec and maintain unity across the board. You wouldn’t want to confuse people having your hamburger icon in your app to be on the right instead of the usual left.

Pro-tip: When in development you might want to enable the Display Speech Output this way you can see what is being said without annoying everyone else in the room trying to concentrate. You can find the setting under the Talkback settings > Developer Settings > Display speech output.
Once enabled it will look like this.

Brailleback is another accessibility app. Again fully maintained by Google themselves and updates get distributed by the Google Play Store too.

It can run in conjunction with Talkback to provide either tactile feedback or both tactile and auditive simultaneously.

Instead of using Talkback the user can connect a small device that converts text into braille. It allows for full control over the device so it can also replace gestures to navigate the app.

I had the chance to witness a very proficient user on one of these devices and she could out type me any time.
These devices are quite an expensive purchase.

Fun fact: They mostly keep their smartphone screen off, this helps them enormously with battery life.

Switch Access is sort of similar to Brailleback except for the Braille integration. Switch Access can be helpful for people with dexterity impairments that prevent them from interacting directly with the Android device. 
Again a device is used to traverse through the different views on screen with the help of a connected button.

Therefore it is again important to provide logical traversal order in your app. More about this later.

The switch devices are generally cheaper than the Brailleback enabled devices.

New Blue 2 Switch

Tools for the developer

When you design and develop an Android app there are multiple tools available that can aid you.

The Accessibility Scanner App can help you identify opportunities to improve your app for accessibility.
Simply download the app and load up an app you want to scan.

While scanning your screen it provides suggestions on which you can improve:

  • Content labels
  • Touch target size
  • Clickable items
  • Text and image contrast

As you can see from the screenshot we have some work to do on text contrast in the VRT NWS app.

Accessibility Scanner Report for VRT NWS

Android Studio

Yes, even Android Studio will warn you about different aspects to be wary of when developing an accessible app.

If you open up the theme editor you will see Android Studio warns you when there is insufficient contrast between certain colors.

If you add an ImageView without a ContentDescription Android Studio will also warn you about this.

Or when you define a text size which is likely to be barely readable.

Even better is to enable a Lint check for missing content descriptions and fail your build when a content description is missing.

# Add to your build.gradle
android {
lintOptions {
abortOnError true
showAll true
lintConfig file("vrtnws-lint.xml")
}
}
# Custom Lint file (vrtnws-lint.xml)
<issue id="ContentDescription" severity="error"/>
# Run Checks
./gradlew lint

When using the Color Tool to compose your theme the tool dedicates a whole tab to accessibility.

Even in the prelaunch reports on Google Play Console you get tips


VRT Sauce

As you can already tell there are lots of great APIs and tools available for developers and the Android ecosystem is becoming increasingly more friendly for accessibility users.

What’s more is that when you stick to default implementations of the Android framework you will already have a minimum of accessibility features enabled in your app.

So what does VRT do extra on top to provide an even better experience?

I tried ordering them according to their importance.
With the tips on the bottom being the ones with lower priority.

Content descriptions

Make sure that every view that a user can touch has a correct label.
This will ensure that it gets picked up correctly by the screen reader.
If it is a static view you can do this in XML or programmatically.

# XML
<TextView
android:contentDescription="@string/your_accessibility_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
# Kotlin
val itemView: View = layout.find(R.id.someView)
itemView.contentDescription = "Your accessibility Text"

If a view is not of interest for an accessibility user, think of little icons, you can ignore the view by using:

<ImageView
android:id="@+id/some_unimportant_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:importantForAccessibility="no"/>

To alleviate the problem of generating a fitting accessibility text for both Android and iOS clients we fetch our accessibility text straight from our backend.

[
{
"id": "1533565019306",
"title": "Twee doden en tientallen gewonden",
"accessibilityText": "Buitenland, Twee doden en tientallen gewonden bij de explosie van een tankwagen in Bologna, aangepast ${time}, dit artikel bevat video"
}
]
    "accessibilityText": "Buitenland, Twee doden en tientallen gewonden bij de explosie van een tankwagen in Bologna, aangepast ${time}, dit artikel bevat video"
}
]

The only computing that needs to be done by the client is replacing the ${time} with the correct time according to some business logic and place it on the itemView.

To make sure you don’t forget this we have a base layout interface which enforces you to have an accessibility text.
You could even make a default interface, but we rather wanted it to be explicit about it.

Grouping of views

When you are composing views together it makes sense to have but one content description for one block instead of each individual item.
The reason behind this is because screen readers like Talkback will otherwise read every little view separately. Grouping views together combines the accessibility text.

In the screenshot below we grouped all views in a list item as one accessibility group with a content description

The way Google recommends you to do this is by placing an android:focusable on to your parent ViewGroup however that breaks tab navigation as explained in this Github issue.

We choose to place android:importantForAccessibility="no" on each view that should be ignored by the screen reader and instead only provide a content description for the parent view.

This will also ensure that the gesture for going to the previous/next item (swipe left/right) is properly implemented

If you want more fine-grained control over what view should be selected next you can take a look at:

android:nextFocusLeft="@id/view_selected_when_swipe_left"    
android:nextFocusRight="@id/view_selected_when_swipe_right"

Text Scaling

In a previous section, we talked about how a user can enlarge text displayed on the screen. The only downside to this is that you should declare your font sizes in SP rather than in DP’s

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp" />

Even better would be to look at the auto sizing TextView it allows for an automatically scaling TextView widget that will fill all available space.
Thanks to Jetpack it is backported all the way back to Android 14.

State & Correct Intent

As a user is it important to know which page or which item is currently active.

Again by leveraging default views this behavior is done for you, but in situations where that is not the case, don’t forget to include it.

Default behavior of a TabLayout will tell you which tab is currently active

Custom Views

You might have custom views in your project fetching periodical results and showing new items in a colorful manner.

Consider notifying your visually impaired end user by using:

view.announceForAccessibility("New items were being fetched")

This will interrupt the screen reader and will broadcast the defined string.

Maybe your custom view is difficult to use or it has a dense set of buttons which would be annoying for people with dexterity impairments.
You could take a look at AccessibilityDelegateCompat this class allows you to define a custom view only for Accessibility users.

Detect Accessibility On

In some situation we are even changing the behavior of the app depending on when accessibility is enabled or not.
Think about running expensive beautiful animations.
Why would you want those if you can detect a user is using a screen reader.

We use a little utility class for this.

Conclusion

If you have come this far I hope that you were inspired to make your apps more accessible. As you can tell it is a rather low effort to fulfil and yet it means a lot to millions of users.

Got any questions? Leave them below.

Special thanks to AnySurfer and Marc Walraven.

Follow @https://twitter.com/googleaccess