flutter_tts icon indicating copy to clipboard operation
flutter_tts copied to clipboard

getEngineList returns empty on Android if called right after instantiating FlutterTts

Open chimura opened this issue 3 years ago • 1 comments

🐛 Bug Report

If getEngineList is called right after instantiating FlutterTts, it returns empty.

I was able to make it work by waiting around 350~500ms before calling getEngineList.

After debugging the source code, I realized it happens because getEngineList is returning before TextToSpeech is properly initialized.

Expected behavior

getEngineList should be able to wait for Android's TextToSpeech object to proper initialize and then return with value.

Or FlutterTts plugin could expose "isTtsInitialized" property so that flutter applications could decide weather or not to call certain methods.

Reproduction steps

flutterTts = FlutterTts(); // without Future.delayed, getEngines returns empty Future.delayed(Duration(milliseconds: 350), () { engineList = await flutterTts.getEngines; }

Additional thoughts

After debugging FlutterTtsPlugin.java I kept asking myself two things that might be helpful to solve this issue:

  1. It appears to me that onMethodCall's logic to "suspend the method call until TTS engine is ready" is not doing its job properly. pendingMethodCalls do indeed get called after initialization, but FlutterTts' methods get no response from those calls;

  2. setEngine method instantiate a new "TextToSpeech(context, onInitListener, engine)", but it does not set isTtsInitialized = false. Therefore, whenever a flutter application calls flutterTts.setEngine, it will get empty responses from getEngineList and getVoices right after.

Configuration

[√] Flutter (Channel stable, 3.0.5, on Microsoft Windows [Version 10.0.19044.1826], locale en-US) [√] Android toolchain - develop for Android devices (Android SDK version 33.0.0-rc2) [√] Chrome - develop for the web [√] Visual Studio - develop for Windows (Visual Studio Build Tools 2019 16.9.3) [√] Android Studio (version 2021.2) [√] VS Code (version 1.69.2) [√] Connected device (3 available) [√] HTTP Host Availability Version: 3.5.0

Platform:

  • [ ] :iphone: iOS
  • [x] :robot: Android

chimura avatar Jul 22 '22 15:07 chimura

Taking a deeper dive on this issue, maybe the best solution would be exposing TextToSpeech.onInit callback to flutter's level, since onMethodCall's result object must be called from the main thread and could not wait for the engine to properly start (would keep the ui hanging);

https://github.com/flutter/flutter/issues/22024#issuecomment-465289341

I'm not sure if this logic ever worked properly for Android devices, but it seems to me that it's the same root-cause of issue #333

chimura avatar Jul 23 '22 16:07 chimura

@chimura can you test with the latest version? thank you

dlutton avatar Nov 06 '22 06:11 dlutton

Yes, it worked fine with this latest version. Thank you!

chimura avatar Nov 25 '22 20:11 chimura