Accessibility (Java)

Accessibility means making sure people who use screen readers, switch devices, or have low vision can actually use your app — not as an optional extra, but as a real requirement for reaching the full range of your users. This lesson covers the handful of practical, cheap fixes that make the biggest difference for a Java Android app: content descriptions, touch target sizing, contrast, and testing tools.

1. contentDescription for Screen Readers

TalkBack, Android's built-in screen reader, reads a View's content aloud so a user who cannot see the screen still knows what's there. A plain ImageView or ImageButton, however, has no text of its own — without a description, TalkBack has nothing meaningful to say about it. android:contentDescription (introduced alongside ImageView and ImageButton in ImageView & ImageButton) fills that gap.

<!-- Missing description: TalkBack says nothing useful -->
<ImageButton
    android:id="@+id/btnFavorite"
    android:src="@drawable/ic_favorite_heart"
    android:layout_width="48dp"
    android:layout_height="48dp" />

<!-- With a description: TalkBack reads it aloud -->
<ImageButton
    android:id="@+id/btnFavorite"
    android:src="@drawable/ic_favorite_heart"
    android:contentDescription="@string/add_to_favorites"
    android:layout_width="48dp"
    android:layout_height="48dp" />

Since RecipeBox's favorite icon changes meaning depending on state, the description should update in Java to match:

// RecipeDetailActivity.java
ImageButton btnFavorite = findViewById(R.id.btnFavorite);

void updateFavoriteIcon(boolean isFavorite) {
    btnFavorite.setImageResource(isFavorite
            ? R.drawable.ic_favorite_filled
            : R.drawable.ic_favorite_heart);

    btnFavorite.setContentDescription(getString(isFavorite
            ? R.string.remove_from_favorites
            : R.string.add_to_favorites));
}
Explanation:
  • A static XML description is enough for icons that never change meaning; a stateful icon like RecipeBox's favorite heart needs its description updated in Java alongside the image itself.
  • Purely decorative images that convey no information (a background pattern, for instance) should set android:contentDescription="@null" so TalkBack skips them instead of reading something meaningless.

2. Touch Target Size

Android's accessibility guidelines recommend every tappable element be at least 48dp by 48dp — the same dp unit covered in depth in Dimensions & Density. Below that size, a target becomes genuinely hard to hit accurately, and the effect compounds for users with limited fine motor control, a shaking hand, or simply a large fingertip. This isn't a cosmetic guideline — it measurably affects whether people can complete an action at all.

<!-- Too small: visually fine, but hard to tap reliably -->
<ImageButton
    android:id="@+id/btnFavorite"
    android:contentDescription="@string/add_to_favorites"
    android:layout_width="24dp"
    android:layout_height="24dp" />

<!-- Better: 48dp touch target, icon itself can stay smaller with padding -->
<ImageButton
    android:id="@+id/btnFavorite"
    android:contentDescription="@string/add_to_favorites"
    android:padding="12dp"
    android:layout_width="48dp"
    android:layout_height="48dp" />
Explanation: the icon graphic itself can still look small and visually light — the surrounding padding pads out the actual tappable area to 48dp without changing how large the icon looks. RecipeBox's favorite heart uses exactly this pattern: a 24dp icon centered inside a 48dp touch target.

3. Color Contrast

Text needs enough contrast against its background to be readable, especially for users with low vision or color blindness. This connects directly back to Colors & Typography: when choosing text and background color pairs — including the light and dark variants from Light/Dark Theme — favor combinations with a clear brightness difference (dark text on a light background, or light text on a dark background) rather than similarly-toned colors that look fine to designers with good vision but wash out for others.

4. Testing with TalkBack and Accessibility Scanner

The most reliable way to know whether an app is actually accessible is to test it the way an affected user would. Turning on TalkBack in device Accessibility settings and navigating RecipeBox by swipe gestures alone quickly reveals which buttons have no description, or which screens are confusing without sight.

Accessibility Scanner is a free tool (available from the Play Store, or built into some Android Studio tooling) that automatically scans a running screen and flags concrete issues — missing content descriptions, touch targets under 48dp, and low contrast text — with specific, actionable suggestions. It won't catch everything a human tester would, but it's a genuinely fast way to find the most common mistakes before they reach real users.

5. Focus Order for Keyboard / Switch Access

Some users navigate entirely without touch, using a hardware keyboard, a D-pad, or switch-access hardware that steps focus between elements. By default, Android guesses a reasonable focus order based on layout position, but a custom layout can override it explicitly with attributes like android:nextFocusDown, android:nextFocusUp, android:nextFocusLeft, and android:nextFocusRight when the automatic order doesn't match the visual/logical flow.

<!-- Forcing focus to move from the title field down to ingredients -->
<EditText
    android:id="@+id/etRecipeTitle"
    android:nextFocusDown="@id/etIngredients"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

Accessibility Checklist

ConcernFixCost to implement
Screen reader can't describe an iconandroid:contentDescriptionVery low
Small tap targetsMinimum 48dp width/height, add padding around a small iconLow
Low contrast textChoose color pairs with clear brightness differenceLow
Confusing keyboard/switch navigationnextFocusDown and related attributesLow, only where needed
Accessibility isn't a "nice to have" bolted on at the end — it's what determines whether a meaningfully large group of real users can use your app at all. The fixes above are individually small and cheap: a content description here, 24dp of extra padding there. None of them require redesigning RecipeBox; they just require remembering to do them as you build each screen.
With the app understandable and usable for a wider range of users, the next lesson, SharedPreferences, moves into Data & Storage — starting with how to persist a simple setting like the dark-mode preference from earlier.