Engineering

Android Accessibility Basics: Contrast, Labels, and Targets

A concrete engineering guide to shipping Android apps that work for everyone using TalkBack, switch access, and high-contrast modes.

AIA Innovations Editorial · September 27, 2026
Share

Small studio apps often skip accessibility under the pressure of limited runways. The common misconception is that accessibility (a11y) is a massive project to be tackled 'at scale' or 'when we have more users.' In reality, accessibility is a core engineering requirement that is much easier to ship incrementally than to retrofit later. When we built Salah Companion, we realized that a prayer times app meant for daily use must be usable by people of all ages and visual abilities. If a user cannot read their next prayer time because the contrast is too low, or if a user relying on a screen reader cannot navigate the tracker, the app has failed its primary purpose.

Accessibility is not just for users with permanent disabilities. It serves the user trying to check a stock verdict on ShariahSignal in bright sunlight, the parent using one hand to navigate an app while holding a toddler, and the student using a screen reader because they have a temporary eye injury. By focusing on three foundational pillars—touch targets, content labeling, and color contrast—you can ensure your app meets the baseline for a professional, inclusive Android experience.

1. Touch Targets: Designing for Fingers, Not Just Pixels

Android users interact with your app through a variety of physical inputs. While a mouse cursor is precise, a human thumb is not. Google’s Material Design guidelines recommend a minimum touch target size of 48x48dp. However, developers often make the mistake of setting the visual icon size to 24dp and forgetting to pad the touchable area. Small touch targets lead to 'fat-fingering'—where a user accidentally triggers the wrong action or has to tap multiple times to get a response.

The Common Mistake

Consider a close button in a dialog. A developer might write:

ImageButton(icon = Icons.Close, size = 24.dp)

Visually, this looks fine. Functionally, it is a nightmare. The user must hit a tiny 24dp square. If they miss by a hair, the tap falls through to the background or does nothing, causing frustration.

The Fix: Padding and Touch Delegates

In Jetpack Compose, the Modifier.clickable or IconButton naturally handles some of this, but you must ensure the layout allows for the full 48dp. If your design requires a small visual icon, use internal padding to expand the hit area without changing the icon's visual scale.

FeatureMinimum SizeRecommended Size
Standard Button48 x 48 dp56 x 56 dp
Text Links48dp height48dp height
Inline Icons48 x 48 dp48 x 48 dp
List Items48dp height64dp height

If you have a tight UI where two buttons are close together, ensure they don't overlap their touch regions. If they do, the system might struggle to decide which one was tapped. Always test your targets using the 'Show layout bounds' option in Android Developer Options. If your clickable boxes look like tiny slivers, they are too small.

2. Content Descriptions: Speaking to the Screen Reader

TalkBack, the Android screen reader, converts UI elements into speech. For a Text composable, TalkBack reads the string. For an Image or IconButton, TalkBack has no way of knowing what the element does unless you provide a contentDescription.

Writing Better Labels

Many developers provide descriptions that are redundant or overly technical. For example, labeling a search icon as 'search_icon_final_v2' is useless. Labeling it as 'Search button' is better, but since TalkBack already identifies it as a button, it will announce 'Search button, button.'

Follow these rules for content descriptions:

  • Skip the type: Don't include words like 'button' or 'image.' The system handles that.
  • Focus on the action: Instead of 'Green checkmark,' use 'Mark as completed.'
  • Null for decorative elements: If an image is purely for aesthetic (like a background flourish), set contentDescription = null. This tells TalkBack to ignore the element, preventing 'ear clutter.'

Practical Example: Prayer Tracker

In a tracker, you might have a row of icons representing prayers.

Bad Label: "icon_fajr" (What does it do?) Better Label: "Fajr prayer" (Okay, but state is missing) Best Label: "Fajr prayer, marked as prayed" or "Fajr prayer, not yet prayed"

You can use string resources with arguments to dynamically update these labels based on the app state. This ensures that a blind user has the same information as a sighted user who sees a color change.

3. Contrast Ratios: Clarity Beyond Branding

Color contrast is the most frequent accessibility failure. Designers often choose light grey text on a white background or thin white text on a vibrant brand color for a 'clean' look. For many users, this text is invisible.

The Web Content Accessibility Guidelines (WCAG) 2.1 suggest a minimum contrast ratio of 4.5:1 for normal text and 3:1 for large text.

Why High Contrast Matters

It isn't just about vision impairment. Contrast helps everyone when:

  • The screen brightness is turned down to save battery.
  • The user is outside in midday sun.
  • The user has an older device with a poor-quality display.

How to Check and Fix

  1. 1.Use the Layout Inspector: Android Studio's layout inspector can now highlight accessibility issues, including low contrast.
  2. 2.Check Your Surface Colors: Ensure your onPrimary color contrasts highly with your primary color. If your brand color is a pale blue, your text should likely be black or a very dark navy, not white.
  3. 3.Test in Dark Mode: Accessibility requirements don't go away in dark mode. Often, developers use 'pure black' (#000000) backgrounds which can cause 'smearing' on OLED screens for some users, or they use grey shades that are too close to each other.

When we worked on the stock verdicts for ShariahSignal, we had to ensure that the 'Compliant' (Green) and 'Non-Compliant' (Red) indicators weren't relying on color alone. About 8% of men have some form of color blindness. We added text labels and specific icons so the information was clear even if the user couldn't distinguish red from green.

4. The Accessibility Scanner Checklist

Google provides a free tool called the Accessibility Scanner. You should run this on every core screen of your app before every release. It will flag:

  • Small touch targets.
  • Low contrast ratios.
  • Missing content descriptions.
  • Duplicate descriptions (which confuse navigation).

If you are using Jetpack Compose, you can also write UI tests that specifically check for accessibility properties. For example:

composeTestRule.onNodeWithContentDescription("Submit").assertExists()

This ensures that if a developer accidentally removes a label during a refactor, the build fails. This is a crucial part of maintaining a healthy codebase, similar to the strategies discussed in our post on making Android notifications actually reliable.

5. State and Focus Management

For users using a keyboard or a switch device, 'focus' is how they move through your app. Usually, Android handles the focus order (top-to-bottom, left-to-right) automatically. However, custom layouts can break this.

If you have a complex dashboard, the logical flow might not be what the system expects. You can manually manage focus using Modifier.focusProperties to ensure that when a user hits 'Next' on their keyboard, they land on the most important next element, rather than jumping to a footer menu.

Conclusion: Start Small, But Start Now

You don't need a dedicated accessibility team to ship a usable app. Most of these fixes take seconds to implement if you do them while you're writing the initial code. Adding a content description takes the same amount of time as writing a print statement. Choosing a high-contrast color takes no longer than choosing a low-contrast one.

Shipping these basics is an act of respect for your users. It says that you value their time and their ability to use your tools, regardless of their physical circumstances. Over time, these small habits become part of your engineering culture, leading to better products for everyone.

What to do next

  1. 1.Run the Accessibility Scanner: Download the Google Accessibility Scanner from the Play Store, open your app, and run a 'Record' session on your main flow. Fix every 'Small Touch Target' warning it generates.
  2. 2.Audit Your Primary Colors: Plug your brand's primary and background colors into a contrast checker. If they are below 4.5:1, darken or lighten your 'On' colors (text/icons) until they pass.
  3. 3.Test with TalkBack: Turn on TalkBack in your phone's settings and try to navigate your app with your eyes closed. If you get stuck or hear 'Unlabelled button,' you have found your first priority for the next sprint.
#android#accessibility#ux-design#mobile-engineering

One email per launch. No spam, unsubscribe any time.