Skip to content

TalkBack stops announcing Semantics.liveRegion updates while recording with record plugin #592

@nero-angela

Description

@nero-angela

Package version

  • 6.2.0

Environment

  • OS: Android

Describe the bug

On Android API 28 devices, the Semantics.liveRegion feature does not work when the audio source is set to AndroidAudioSource.mic.

I originally reported this issue in the Flutter repository, but I was asked to submit it to the record package instead.

To Reproduce

  1. Create a new Flutter project via terminal:

    flutter create accessibility_bug_report
    cd accessibility_bug_report
  2. Add the required dependencies:

    flutter pub add record path_provider path
  3. Configure Android Permissions:
    Open android/app/src/main/AndroidManifest.xml and add the following line inside the <manifest> tag:

    <uses-permission android:name="android.permission.RECORD_AUDIO" />
  4. Replace the content of lib/main.dart with code sample bellow

  5. Run on an Android device:

    flutter run
  6. Verify with TalkBack:

    • Enable TalkBack in Android Settings.
    • Launch the app and tap the "Start Mic" button.
    • Observe: The screen visually updates with dB values every second, but TalkBack does not announce anything while the microphone is active.
AndroidAudioSource.mic AndroidAudioSource.voiceCommunication
liveRegion is broken liveRegion works
IMG_3627.mp4
IMG_3628.mp4

I tested this on the latest version of Flutter 3.41.0 using a Samsung Galaxy S8 (Android 9 – API 28) device. When AndroidAudioSource is explicitly set to .mic in the code, or when it is omitted, the liveRegion feature does not work. However, when it is set to .voiceCommunication, liveRegion works as expected.

Source code changes
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:record/record.dart';
import 'package:path/path.dart' as p;

void main() => runApp(const MaterialApp(home: AndroidLiveRegionIssue()));

class AndroidLiveRegionIssue extends StatefulWidget {
  const AndroidLiveRegionIssue({super.key});
  @override
  State<AndroidLiveRegionIssue> createState() => _AndroidLiveRegionIssueState();
}

class _AndroidLiveRegionIssueState extends State<AndroidLiveRegionIssue> {
  final AudioRecorder _audioRecorder = AudioRecorder();
  StreamSubscription<Amplitude>? _amplitudeSubscription;
  bool _isMonitoring = false;
  double _currentDb = -160.0;

  Future<void> _startMonitoring() async {
    if (await _audioRecorder.hasPermission()) {
      final tempDir = await getTemporaryDirectory();
      final tempPath = p.join(tempDir.path, 'temp_mic.m4a');

      await _audioRecorder.start(RecordConfig(
        androidConfig: AndroidRecordConfig(
          audioSource: AndroidAudioSource.mic, // 👈 Test `mic` or `voiceCommunication`
        )
      ), path: tempPath);

      setState(() => _isMonitoring = true);

      _amplitudeSubscription = _audioRecorder
          .onAmplitudeChanged(const Duration(milliseconds: 1000))
          .listen((amp) {
            setState(() => _currentDb = amp.current);
          });
    }
  }

  @override
  void dispose() {
    _amplitudeSubscription?.cancel();
    _audioRecorder.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Android Accessibility Bug')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Semantics(
              liveRegion: true, // TalkBack ignores this once mic is active on Android
              child: Text(
                _isMonitoring ? "Volume: ${_currentDb.toStringAsFixed(0)} dB" : "Mic is OFF",
                style: const TextStyle(fontSize: 32),
              ),
            ),
            const SizedBox(height: 50),
            ElevatedButton(
              onPressed: _isMonitoring ? null : _startMonitoring,
              child: const Text("Start Mic"),
            ),
          ],
        ),
      ),
    );
  }
}
flutter doctor -v
❯ flutter doctor -v                        
[✓] Flutter (Channel stable, 3.41.0, on macOS 26.0 25A354 darwin-arm64, locale ko-KR) [1,084ms]
    • Flutter version 3.41.0 on channel stable at /Users/nell/.fvm/versions/stable
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 44a626f4f0 (2 days ago), 2026-02-10 10:16:12 -0800
    • Engine revision 3452d735bd
    • Dart version 3.11.0
    • DevTools version 2.54.1
    • Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, cli-animations,
      enable-native-assets, omit-legacy-version-file, enable-lldb-debugging, enable-uiscene-migration

[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.1) [2.1s]
    • Android SDK at /Users/nell/Library/Android/sdk
    • Emulator version 35.4.9.0 (build_id 13025442) (CL:N/A)
    • Platform android-36, build-tools 35.0.1
    • Java binary at: /Library/Java/JavaVirtualMachines/jdk-17.0.12.jdk/Contents/Home/bin/java
      This JDK is specified in your Flutter configuration.
      To change the current JDK, run: `flutter config --jdk-dir="path/to/jdk"`.
    • Java version Java(TM) SE Runtime Environment (build 17.0.12+8-LTS-286)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 26.0) [1,694ms]
    • Xcode at /Applications/Xcode-26.0.0.app/Contents/Developer
    • Build 17A324
    • CocoaPods version 1.16.2

[✓] Chrome - develop for the web [5ms]
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Connected device (5 available) [6.4s]
    • [Test Device 👉] SM G950N (mobile)                   • ce0317136a2c08f10c        • android-arm64  • Android 9 (API 28)

Expected results

On Android, TalkBack should continue to announce updates within the Semantics.liveRegion even when the microphone is active, ensuring that visually impaired users can receive real-time updates.

Actual results

An active microphone session on Android silences all liveRegion announcements.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions