Skip to content

Native mobile scanning

Wholisphere scans native Android apps against WCAG 2.2 the same way it scans the web: in-house evaluators produce structured findings that roll up into the same VPAT, review queue, and client portal. There is no third-party engine (no axe / pa11y) — detection runs over the platform’s own accessibility APIs.

Why a native app needs more than a DOM scan

A native app exposes a sparse accessibility tree — no heading roles, no autofill hints, no live-region markers, none of the structure a DOM gives you. So the scanner tests the app the way a person and a screen reader actually experience it: real focus traversal, real gestures, real device state — not markup parsing. Where most mobile “audits” mark a dozen-plus criteria not evaluated and hand you a manual checklist, Wholisphere returns a disposition for every A+AA criterion.

What a mobile scan evaluates

All 55 WCAG 2.2 Level A + AA criteria are dispositioned on native Android — nothing is left to a manual checklist:

  • 44 emit an automated per-screen verdict.
  • 6 are media-evaluated (the 1.2.x captions / audio-description criteria + 1.4.2), when the app ships time-based media.
  • 5 are genuinely Not Applicable to a touch-native screen (e.g. hover, bypass-blocks), each with a documented reason.

When a single scan honestly can’t be certain — a caption’s accuracy, whether a legal-flow safeguard exists, whether a foreign-language passage declares its locale — the finding is confidence-scored and routed to a one-click reviewer step, never rounded up to a false pass. The VPAT records which method judged each criterion.

Detection methods

  • Accessibility tree (deterministic) — names, roles, states, target size (≥24dp, density-aware), label-in-name, meaningful sequence, consistent navigation/identification across screens, and honest applicability gates (e.g. Text Spacing 1.4.12 is Not Applicable on native views — Android has no platform spacing override, WCAG2ICT — and routes to review only inside an embedded WebView).
  • Pixels — text and non-text contrast measured from the screenshot (Otsu-clustered), never guessed.
  • Interaction probes — drive a real device or emulator and diff the result: TAB/switch traversal (keyboard reach, focus order, traps), font-scale and rotation re-capture (resize, reflow, orientation), a press-and-drag-off gesture (pointer cancellation), a two-capture countdown read (timing adjustable), on-focus/on-input context checks, and — on an emulator — injected accelerometer motion (motion actuation).
  • Temporal capture — a short per-screen frame stack screens for flashing (2.3.x) and auto-updating motion (2.2.2), analyzed into the same shape the web temporal probe produces.
  • Vision & media judges — a vision LLM rules on use-of-color, images-of-text, sensory instructions, and heading descriptiveness against the rendered screen; a multimodal judge reads captions against the audio for the 1.2.x criteria; Unicode script analysis flags likely foreign-language passages. Measured, never assumed — with no model key, these report unverified, never a false pass.

Media resolution — supply only what a scan can’t reach

For the time-based-media criteria, the scanner resolves the source itself wherever it can: media bundled in the APK is extracted, and streamed HLS/DASH manifests are discovered from the app at runtime. The owner supplies a source only for what a scan genuinely cannot reach on its own (for example, DRM-protected streams). Captions and audio description are then judged against the actual media, not inferred.

Running a mobile scan

The mobile runner is CLI-driven against a connected device or emulator, with a short guided-flow file describing the screens to walk:

Terminal window
npx @wholisphere.ai/scanner-runner-mobile \
--flow ./flow.json \
--out ./mobile-scan-out
  • --flow — a JSON file of app package + steps (launch activity, taps) that walks the app screen by screen.
  • --probes — opt in to the interaction probes (keyboard, focus, font-scale, rotation, pointer-cancel, motion, timing). These drive the device, so they add time per screen.
  • --temporal — opt in to per-screen frame capture for flashing / auto-updating motion. The screencap loop is deliberate (~0.6 fps on the emulator, ~15–20s/screen), so it is off by default.
  • --media-manifest — an owner-declared caption/audio-description manifest for media a scan can’t reach.

Findings flow through the same pipeline as web scans — the VPAT, the review queue, the client status portal, and regression alerts can’t tell a mobile finding from a web one, so one conformance story spans every surface. Fixes arrive in the app’s own idiom (an accessible name, a 48dp target, a contrast-safe textColor) — never a client-side overlay.

Honest limits

  • Android only today; iOS is on the roadmap (the evaluator core is shared and shaped for it).
  • Motion actuation (2.5.4) is validated on an emulator (accelerometer injection); on a real device that probe is simply absent rather than guessed.
  • Same-script language changes (e.g. English ↔ French) are not machine-detectable from the tree; only a different writing script is flagged, and it routes to review.
  • Review-routed criteria are decision support, not a silent pass/fail — the VPAT states the method and confidence for each.