ryanheise / audio_session

MIT License
115 stars 81 forks source link

Unhandled Exception: MissingPluginException(No implementation found for method getDevices on channel com.ryanheise.android_audio_manager #61

Closed zuala69 closed 2 years ago

zuala69 commented 2 years ago

I'm getting the error

Unhandled Exception: MissingPluginException(No implementation found for method getDevices on channel com.ryanheise.android_audio_manager

and other MissingPluginException for getMode, requestAudioFocus as of now. This is happening for some specific devices i guess as there's no problem on a Redmi Note 9 pro max and many more devices but only happening on Redmi Note 10, Vivo 1820 and a few other devices. This plugin itself doesn't cause a problem but when used with the below plugins.

just_audio: ^0.9.20 just_audio_background: ^0.0.1-beta.5

I have stoppped, cleaned, pub get and even restarted both pc and mobile. I created a new project and the issue is reproducable with the following code

pubspec.yaml file codes below

name: audiotest
description: A new Flutter project. 
publish_to: 'none' 
version: 1.0.0+1
environment:
  sdk: ">=2.16.1 <3.0.0" 
dependencies:
  flutter:
    sdk: flutter 
  cupertino_icons: ^1.0.2
  just_audio: ^0.9.20
  just_audio_background: ^0.0.1-beta.5
  audio_session: ^0.1.6+1
dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^1.0.0
flutter:
  uses-material-design: true

And the activity where I use them are below


class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  final int _counter = 0;
  final _player = AudioPlayer(
    handleInterruptions: false,
    androidApplyAudioAttributes: false,
    handleAudioSessionActivation: false,
  );
  @override
  void initState() {
    _init();
    super.initState();
  }
  void _handleInterruptions(AudioSession audioSession) {
    var playInterrupted = false;
    audioSession.becomingNoisyEventStream.listen((_) {
      log('PAUSE');
      _player.pause();
    });
    _player.playingStream.listen((playing) async {
      log("play stream $playing");
      if (playing) {
        audioSession.setActive(true);
      }
    });
    audioSession.interruptionEventStream.listen((event) {
      log('interruption begin: ${event.begin}');
      log('interruption type: ${event.type}');
      if (event.begin) {
        switch (event.type) {
          case AudioInterruptionType.duck:
            if (audioSession.androidAudioAttributes!.usage ==
                AndroidAudioUsage.game) {
              _player.setVolume(_player.volume / 2);
            }
            playInterrupted = false;
            break;
          case AudioInterruptionType.pause:
          case AudioInterruptionType.unknown:
            if (_player.playing) {
              _player.pause();
              playInterrupted = true;
            }
            break;
        }
      } else {
        switch (event.type) {
          case AudioInterruptionType.duck:
            _player.setVolume(math.min(1.0, _player.volume * 2));
            playInterrupted = false;
            break;
          case AudioInterruptionType.pause:
            if (playInterrupted) _player.play();
            playInterrupted = false;
            break;
          case AudioInterruptionType.unknown:
            playInterrupted = false;
            break;
        }
      }
    });
    audioSession.getDevices().then((devices) {
      log('devices changed: $devices');
    });
    audioSession.devicesChangedEventStream.listen((event) {
      for (var device in event.devicesAdded) {
        log('Devices 1233 added of type : ${device.type} eq-' +
            (device.type == AudioDeviceType.remoteSubmix).toString());
        if (device.type == AudioDeviceType.remoteSubmix) {
          log("remote submix added ${device.type}");
          _player.setVolume(0);
        }
      }
      for (var device in event.devicesRemoved) {
        if (device.type == AudioDeviceType.remoteSubmix) {
          // volume.value = 0;
          log("remote submix removed ${device.type}");
          _player.setVolume(1);
        }
        log('Devices 1233 removed: ${event.devicesRemoved}');
      }
    });
  }
  Future<void> _init() async {
    try {
      final session = await AudioSession.instance;
      await session.configure(const AudioSessionConfiguration.music());
      session.getDevices().then((devices) {
        log('devices changed: $devices');
      });
      _handleInterruptions(session);
    } catch (e) {
      log("Error loading audio source: $e");
    }
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
    );
  }
}```
zuala69 commented 2 years ago

Project architecture was not according to the latest available and recreating the project with flutter 3.0.0 solved the problem

under3415 commented 1 year ago

Hi, I am getting this issue reported in Crashlytics from Google Play Store testing devices. Cannot replicate on my side.

just_audio: ^0.9.32

Fatal Exception: io.flutter.plugins.firebase.crashlytics.FlutterError: MissingPluginException(No implementation found for method dispose on channel com.ryanheise.just_audio.methods.90f3f701-72bd-445f-8bb4-d53bf1087c98)

Am I doing something wrong or is this an issue with the package? In stack trace there is no mention of my code...

Flutter Doctor:

[√] Flutter (Channel stable, 3.7.11, on Microsoft Windows [Version 10.0.19045.2846], locale en-US)
[√] Windows Version (Installed version of Windows is version 10 or higher)
[√] Android toolchain - develop for Android devices (Android SDK version 33.0.2)
[√] Chrome - develop for the web
[!] Visual Studio - develop for Windows (Visual Studio Community 2022 17.5.3)
    X Visual Studio is missing necessary components. Please re-run the Visual Studio installer for the "Desktop development with C++" workload, and include these components:
        MSVC v142 - VS 2019 C++ x64/x86 build tools
         - If there are multiple build tool versions available, install the latest
        C++ CMake tools for Windows
        Windows 10 SDK
[√] Android Studio (version 2022.1)
[√] VS Code (version 1.77.3)
[√] Connected device (3 available)
[√] HTTP Host Availability
ryanheise commented 1 year ago

MissingPluginException is an umbrella term with a wide range of causes. For example, it could be the specific combination of plugins you're using in your app, particularly if any of the other plugins in your app are instantiating new FlutterEngines. But this is almost certainly not an audio_session bug. Your error message doesn't mention audio_session. It mentions just_audio, but even then, it doesn't specifically point to a crash within just_audio, it only refers to the fact that the FlutterEngine's initialisation failed before it was able to load all of the plugins. It is possible that one of the other plugins in your app failed to load within the FlutterEngine and just_audio might have been an innocent bystander. In any case, audio_session would not be it.

under3415 commented 1 year ago

This is happening every time I deploy to the Play Store and on all their testing devices (Pixel 5, 6, 7...). It is the same message pointing to com.ryanheise.just_audio.methods every time. It's not a once off.

I should have shared the next line probably:

#00 pc 0x65eaab appmyapp.myapp (AudioPlayer._load [just_audio.dart:853]) (BuildId: 9344508ecbe1b7074c942982f6c118bb)

All my code that plays sounds is wrapped in try/catch blocks, but this still causes app to crash.

ryanheise commented 1 year ago

I don't think we're communicating here. It seems you either didn't read or didn't understand my last reply.

under3415 commented 1 year ago

Quite possible I didn't understand. Sorry, not very good at this... In my simple mind I expect that if wrap just_audio calls in try/catch, it should not crash with unhandled exception. But it seems that when just_audio (line 853) throws this error, it crashes the app. throw PlayerInterruptedException(e.message);

ryanheise commented 1 year ago

I'm locking this issue for reasons explained in my very first reply. I would rather not have to repeat the reason.