Service Layer medium complexity Shared Component mobile
0
Dependencies
5
Dependents
1
Entities
0
Integrations

Description

Detects whether a screen reader (VoiceOver or TalkBack) is active on the device and exposes this state as a reactive stream throughout the app. Other services and widgets subscribe to this stream to conditionally adjust behaviour, such as triggering the sensitive field warning only when a screen reader is running.

Feature: Screen Reader Support

screen-reader-detection-service

Summaries

The Screen Reader Detection Service is a foundational capability that enables the entire accessibility layer of the application to activate intelligently and only when needed. Rather than applying accessibility-specific flows universally — which can add friction for non-AT users — this service ensures that features such as sensitive field privacy warnings and enhanced focus management are triggered exclusively for users who rely on screen readers. This precision approach protects user privacy, reduces unnecessary UI complexity for the general population, and demonstrates thoughtful, high-quality product design. As a shared service used across multiple features, it provides consistent behaviour and avoids duplicated platform detection logic throughout the codebase.

As a shared infrastructure service consumed by multiple features, Screen Reader Detection Service sits on the critical path for all accessibility-dependent functionality including sensitive field privacy guarding and focus management. It carries no external dependencies, making it one of the safest components to deliver early and unblock downstream teams. The main delivery risk is platform API variability: VoiceOver and TalkBack expose accessibility state differently across OS versions, so testing must cover a matrix of iOS and Android versions rather than a single device. Plan for a regression test suite that runs on CI with real-device farms.

Because this service is shared, any breaking change to its stream contract will require coordinated updates across all consuming components.

Screen Reader Detection Service wraps Flutter's SemanticsBinding.instance.accessibilityFeatures and registers a listener on SemanticsBinding.instance.window.onAccessibilityFeaturesChanged to track state transitions reactively. screenReaderStream() exposes a StreamController.broadcast() stream so multiple widgets and services can subscribe without ownership conflicts. isScreenReaderActive() provides a synchronous snapshot for non-reactive callsites such as build methods. refreshState() is called on AppLifecycleState.resumed to re-evaluate because TalkBack state is not always propagated to the Flutter layer during backgrounding on Android.

getPlatformReaderName() returns 'VoiceOver' or 'TalkBack' based on Platform.isIOS for use in user-facing copy. Consumers should dispose stream subscriptions in their own lifecycle hooks to avoid leaks.

Responsibilities

  • Detect VoiceOver and TalkBack active state at app startup
  • Expose a reactive stream for screen reader active/inactive transitions
  • Provide a synchronous current-state accessor for non-reactive contexts
  • Re-evaluate state when the app returns from background

Interfaces

isScreenReaderActive()
screenReaderStream()
onScreenReaderChanged(callback)
refreshState()
getPlatformReaderName()

Related Data Entities (1)

Data entities managed by this component

API Contract

View full contract →
REST /api/v1/screen-reader-states 7 endpoints
GET /api/v1/screen-reader-states
GET /api/v1/screen-reader-states/:id
POST /api/v1/screen-reader-states
PUT /api/v1/screen-reader-states/:id
DELETE /api/v1/screen-reader-states/:id
POST /api/v1/screen-reader-states/refresh
+1 more