State Descriptions on Android

Learn what state descriptions are, why they’re important for accessibility and how you can use them on older versions of Android.

Ataul Munim
Google Developer Experts
3 min readDec 9, 2021

--

State descriptions are a relatively new addition to the accessibility toolbox on Android, having been added in Android 11 (API 30). It’s a dedicated property used to describe a UI component’s current state.

Before this API, we had to overload the content description to provide this extra information:

Image showing media controls and the text “Play/pause button — paused, double tap to play”. “Play/pause button — paused” is highlighted as content description and “play” in “double tap to play” is highlighted as the click label

Now, we can keep the state description separate:

Image showing media controls and the text “Paused, play/pause button, double tap to play”. “Paused” is highlighted as the state description and “play/pause button” is highlighted as the content description and “play” in “double tap to play” is highlighted as the click label

In this post, we’ll look at the state description property and how we can use it in both Jetpack Compose UIs as well as traditional View-based systems.

When do I need a state description?

A state description is helpful when a UI component changes visually to express state.

Built-in components like CheckBox, RadioButton and Switch are all well-known to accessibility services. The service can query these components and present their state to the users automatically:

Image shows two CheckBox items and the text “Not ticked, item one, tick box, double tap to toggle” next to the unchecked item, and “ticked, item two, tick box, double tap to toggle” next to the checked item. The “not ticked” and “ticked” portions are labelled as state descriptions.
A not-ticked and ticked CheckBox

RadioButton and Switch enjoy similar functionality. Google TalkBack will present these with “selected”/“not selected” and “on”/“off” as the respective state descriptions.

For custom widgets, icons or badges, there are no such instrinsic properties. Accessibility services don’t know about our custom volume indicator or microphone badge, so it used to be necessary to bake information about the state into the content description.

Left: 3 speaker icons, with a varying number of waves being emitted, and labelled to show 0%, 20% and 80% volume states. Right: two microphone icons, one with a line through it, to indicate microphone on and off states.

With the state description property, we can instead keep our content description short and focused.

State descriptions in Jetpack Compose UI

In this example, we’re using the Slider component to represent min/max price filters. If we check with TalkBack though, it’s using the default state description which isn’t very helpful; we want it to show the price.

Image shows TalkBack focused on a slider (or seekbar). The description reads “30%, min price, slider”. Image on the right shows the same but the description reads “£30, min price, slider”.
Left: without a custom state description, right: with

State descriptions can be set in Compose UI using Modifier.semantics. Here, we’re updating the default description so that it tells us what price is currently selected:

Slider(
value = sliderPosition,
onValueChange = { sliderPosition = it },
modifier = Modifier.semantics {
val money = (sliderPosition * 100).toInt()
stateDescription = "£$money"

}
)

This works with the latest version of Talkback (12.1), even on older versions of Android (I tested on Android 10, prior to the introduction of the state description API). Jetpack Compose UI works all the way back to Android 5.1 (API 21) so this is great news.

State descriptions in a View-based UI system

In a View-based system, we can use the ViewCompat API from AppCompat. It uses view tags to backport support all the way back to Android 4.4 (API 19)!

val localizedDesc = "On" // TODO: localize it..!
ViewCompat.setStateDescription(micView, localizedDesc)

This lets us set a state description on any View which accessibility services (like TalkBack) should use.

What’s next?

It’s pretty cool that this new property has been backported so far back in both View and Compose UIs. If you haven’t seen it yet, I’d recommend watching this video from Shailen Tuli about “Conveying state for Accessibility”:

⚠️ One place that hasn’t worked as expected is with Seekbar. Star this issue to get updates on this bug!

Let me know if you have comments or questions!

Thanks Jolanda and Caren for the reviews and help with filing the bug!

--

--

Ataul Munim
Google Developer Experts

Android Developer Relations Engineer, focusing on Wear OS.