flutter async function is being skipped - flutter

So I was trying to organize my code and breaking it down into smaller functions when I discovered that a function is being skipped by Dart for some reason, if somebody is versed well with async programming; an explination for why this is happening would be appreciated.
The code:
void _converse(bool first_run) async {
first_run ? _speak("how may I help you?") : _speak("need anything else?");
sleep(Duration(seconds: 3));
await _listen();// the _listen function
sleep(Duration(seconds: 10));
first_run = false;
}
_listen() code:
Future _listen() async {
String _question = '-';
if (!_isListening) {
bool available = await _speech.initialize(
onStatus: (val) => print('onStatus: $val'),
onError: (val) => print('onError: $val'),
);
if (available) {
setState(() => _isListening = true);
_speech.listen(
onResult: (val) => setState(() {
_text = val.recognizedWords;
if (val.hasConfidenceRating && val.confidence > 0) {
_confidence = val.confidence;
}
}),
);
}
} else {
setState(() => _isListening = false);
// test placeholder
process_speech(_text);
_speech.stop();
}
}
The _listen() function which is supposed to take in speech input is being ignored.

Related

flutter google_speach response stream not working

final serviceAccount = ServiceAccount.fromString(r'''{
Json private keys
}''');
final speechToText = SpeechToText.viaServiceAccount(serviceAccount);
final config = RecognitionConfig(
encoding: AudioEncoding.LINEAR16,
model: RecognitionModel.basic,
enableAutomaticPunctuation: true,
sampleRateHertz: 16000,
languageCode: 'en-US');
final streamingConfig =
StreamingRecognitionConfig(config: config, interimResults: true);
Stream<List<int>> stream =
(await MicStream.microphone(sampleRate: 16000)) as Stream<List<int>>;
final responseStream =
speechToText.streamingRecognize(streamingConfig, stream);
if (_isListining) {
setState(() {
_isListining = false;
});
} else {
setState(() {
_isListining = true;
print('hello');
try {
responseStream.listen((data) {
print(data.results.length);
setState(() {
_sendController.text = data.results
.map((e) => e.alternatives.first.transcript)
.join('/n');
});
print(content);
}, onDone: () {
setState(() {
setState(() {
_isListining = false;
});
});
}, onError: (e) {
print('errorr : ' + e);
setState(() {
_isListining = false;
});
});
print('streaming');
} catch (e) {
print('not streaming');
print(e);
}
});
}
linke to packages used
https://pub.dev/packages/google_speech
https://pub.dev/packages/mic_stream
so the problem is that microphone streaming is working fine but responseStream from google apis not printing or doing anything
after reading the docs
found this
https://cloud.google.com/speech-to-text/docs/troubleshooting#returns_an_empty_response
and i dont know if it is the problem or not

Await and then usage issues when switching states

By default The text to speech engine uses an async call, this causes the main Dart thread to go on with whatever line of code comes next, this leads up to another setstate() call after the TTS speak function which reverts the animation state from Speaking to Idle almost instantly.
is there any way to avoid this issue?
I want it to work as follows:
setstate(() => _animation = 'Speaking')
wait until the TTS is finished speaking
setstate(() => _animation = 'Idle')
If I'm misunderstanding something, could you please point it out? in case this is how Dart works then if you have any workarounds that'd be great.
Simplified code for inspection:
void _speak(String sentence) async {
updateRiveRoot(_animation = 'Speak');
setState(() => _isSpeaking = true);
if (!_isSpeaking) {
await tts.awaitSpeakCompletion(true);
tts.speak(sentence).then((result) {
if (result != null) {
print("getting here");// not being preinted out
setState(() => _isListening = false);
setState(() => _isSpeaking = false);
updateRiveRoot(_animation = 'Idle');
}
});
} else {
setState(() => _isSpeaking = true);
}
print("isSpeaking is $_isSpeaking and animation is $_animation");
}
I have scrolled through the TTS documentation but couldn't find useful information on the problem I'm currently facing.
try to use .then,
void _speak(String sentence) async {
if (!_isSpeaking) {
setState(() => _animation = 'Speak');
setState(() => _isSpeaking = true);
tts.speak(sentence).then((result) {
if (result != null) {
_isListening = false;
_isSpeaking = false;
setState((){});
}
});
}
} else {
setState(() => _isSpeaking = false);
}
}

Alert Dialog running infinitely

Hello I am trying to run following code, I want to run a specific asynchronous code and show alert dialog until it's running. But the code is not being executed after await showAlertDialog(); this line.
void appendAndRunPythonCode() async {
await showAlertDialog();
await runPythonScript(final_code);
_alertDialogUtils.dismissAlertDialog(context);
}
This is how my showAlertDialog() function is implemented:
Future<void> showAlertDialog() async {
if (!_alertDialogUtils.isShowing) {
await _alertDialogUtils.showAlertDialog(context);
}
}
runPythonCode():
Future<void> runPythonScript(String code) async {
if (inputImg == null) {
ToastUtils.showToastMessage(text: ConstUtils.input_image_empty_notice);
return;
}
if (code.isEmpty) {
ToastUtils.showToastMessage(text: ConstUtils.code_empty);
return;
}
List<String> lines = code.split('\n');
String lastLine = lines.elementAt(lines.length - 4);
if (lastLine.split(' ').elementAt(0).compareTo('outputImage') != 0) {
ToastUtils.showToastMessage(text: ConstUtils.cv_error_line2);
return;
}
data.putIfAbsent("code", () => code);
data.putIfAbsent("inputImg", () => inputImg);
_alertDialogUtils.showAlertDialog(context);
final result = await _channel.invokeMethod("runPythonCVScript", data);
// Add Artifical Delay of 3 seconds..
await Future.delayed(
Duration(seconds: 3),
);
_alertDialogUtils.dismissAlertDialog(context);
setState(
() {
_scrollController.animateTo(
_scrollController.position.maxScrollExtent,
curve: Curves.easeOut,
duration: const Duration(milliseconds: 300),
);
output = result['textOutput'] ??= "";
error = result['error'] ??= "";
outputImg = (result['graphOutput']);
data.clear();
},
);
}
You shouldn't await the showAlertDialog because runPythonScript won't be executed until the dialog is dismissed.
Remove the await.
Like so:
void appendAndRunPythonCode() async {
showAlertDialog();
await runPythonScript(final_code);
_alertDialogUtils.dismissAlertDialog(context);
}

Wait for callback to complete in Dart / Flutter

Currently writing a flutter app using the flutter_tts library.
I have a list of sentences to read out, but currently having trouble waiting for the setCompletionHandler() to complete.
How can I wait for the setCompletionHandler() callback to complete before moving on to the next string? Currently, the TTS.speak() function finishes immediately with the while loop incrementing right away so it only reads out the last sentence in the list.
// code shortened for brevity
FlutterTts TTS;
TtsState ttsState = TtsState.stopped;
get isPlaying => ttsState == TtsState.playing;
get isStopped => ttsState == TtsState.stopped;
List<String> sentences = ['Hello, World', 'How are you?', 'The quick brown fox jumps over the lazy dog'];
#override
void initState() {
super.initState();
TTS = FlutterTts();
}
void readOutSentences(sentences) async {
int i = 0;
bool readCompleted = false;
while (i < sentences.length) {
readCompleted = await runSpeak(sentences[i].toString());
if (readCompleted)
i++;
}
}
Future<bool> runSpeak(String currentSentence) async {
TTS.setStartHandler(() {
setState(() {
ttsState = TtsState.playing;
});
});
TTS.setCompletionHandler(() {
setState(() {
ttsState = TtsState.stopped;
});
});
await TTS.speak(currentSentence);
return true;
}
readOutSentences(sentences);
Forgive about the setCompletionHandler)
You can use such async functions:
Future<void> _speak(String _text) async {
if (_text != null && _text.isNotEmpty) {
await flutterTts.awaitSpeakCompletion(true);
await flutterTts.speak(_text);
}
}
readAllSentencesList(List<String> allSentences) async {
for (int i=0; i<allSentences.length; i++){
await _speak(allSentences[i]);
}
}
Don't forget to use last flutter_tts library!
Set setCompletionHandler like following to speak all sentences of the list one by one.
List<String> sentences = ['Hello, World', 'How are you?', 'The quick brown fox jumps over the lazy dog']
int i = 0;
FlutterTts flutterTts = FlutterTts();
await flutterTts.speak(sentences[i]);
flutterTts.setCompletionHandler(() async {
if (i < sentences.length - 1) {
i++;
await flutterTts.speak(sentences[i]);
}
});
To wait for the callback use the await keyword:
await TTS.setCompletionHandler(() {
setState(() {
ttsState = TtsState.stopped;
});
});

type 'future<dynamic>' is not a subtype of type 'function'

when i run my app in debug mode it shows me the error "type 'future' is not a subtype of type 'function'" all over the screen and also in the debug console. Can someone help me? I imagine it's a problem with async functions "reset","rateoGet" and "rateoSave" but i can't find any solution.
P.S. I've deleted part of the code because it was useless for this question.
int plus;
int min;
int per;
int div;
double val;
int gameswon =0;
int moves;
static int mosse=15;
String win = "gioca";
int games=0;
double rateo=1;
String mode;
int flag;
var timer=30;
#override
void initState() {
super.initState();
reset();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body:
MyButton(text: "$per" ,color: Colors.deepPurpleAccent, onTap: (){
setState(() {
val*=per;
});
if(widget.mode=="timermode" && flag==0){
timerceckresults();
}else if(widget.mode=="movesmode"){
checkResult();
}
},
MyBottomButton(text: "Reset",color: Colors.indigo,width:160, onTap: reset()),
),
}
checkResult() {
if(val == 101) {
print("hai vinto");
win="Hai Vinto";
setState(() {});
gameswon++;
Timer(Duration(seconds: 2), () {
reset();
});
} else {
print("ci sei quasi");
moves++;
mosse--;
win="$mosse moves left";
setState(() {});
if(moves>14){
print("hai perso coglione");
win="Hai Perso Coglione";
setState(() {});
Timer(Duration(seconds: 2), () {
reset();
});
}
}
}
timerceckresults(){
flag=1;
timer = 30;
Timer.periodic(Duration(seconds: 1), (t){
timer--;
setState(() {
win = "${timer.toString()}seconds left";
});
if(val==101){
timer=0;
}
if(timer == 0) {
t.cancel();
if(val == 101) {
win="Hai Vinto";
setState(() {});
gameswon++;
Timer(Duration(seconds: 2), () {
reset();
});
} else {
win="Hai Perso Coglione";
setState(() {});
Timer(Duration(seconds: 2), () {
reset();
});
}
}
});
static int randNum(x,y) {
var rng = new Random();
return rng.nextInt(y-x)+x;
}
reset() async{
timer=1;
plus = randNum(4, 9);
min = randNum(5, 19);
per = randNum(3, 9);
div = randNum(2, 5);
val = randNum(2, 11).toDouble();
moves = 0;
mosse=15;
if(widget.mode=="timermode"){
win="start playing";
}else{
win="$mosse moves left";
}
await rateoSave();
await rateoGet();
games++;
rateo=gameswon/(games-1);
await rateoSave();
flag=0;
setState(() {});
}
rateoSave() async {
SharedPreferences prefs=await SharedPreferences.getInstance();
await prefs.setInt("games",games);
await prefs.setInt("gameswon",gameswon);
}
rateoGet() async {
SharedPreferences prefs=await SharedPreferences.getInstance();
games=(prefs.getInt("games") ?? 0);
gameswon=(prefs.getInt("gameswon") ?? 0);
https://dart.dev/codelabs/async-await read this before you check the answer will help you alot
reset() async{
timer=1;
plus = randNum(4, 9);
min = randNum(5, 19);
per = randNum(3, 9);
div = randNum(2, 5);
val = randNum(2, 11).toDouble();
moves = 0;
mosse=15;
if(widget.mode=="timermode"){
win="start playing";
}else{
win="$mosse moves left";
}
await rateoSave();
await rateoGet();
games++;
rateo=gameswon/(games-1);
await rateoSave();
flag=0;
setState(() {});
}
Future<bool> rateoSave() {
SharedPreferences prefs= SharedPreferences.getInstance();
prefs.setInt("games",games);
prefs.setInt("gameswon",gameswon);
return true;
}
Future<bool> rateoGet() async {
SharedPreferences prefs= SharedPreferences.getInstance();
await games=(prefs.getInt("games") ?? 0);
await gameswon=(prefs.getInt("gameswon") ?? 0);
return true;
}
you are trying to get a variable from a method that returns a future. you need to add await just before you make the call to that function.
can you tell us in which line this error occurs ?
The most important thing to keep in mind is that if anything in your call-chain returns a Future, everything above it must deal with futures, either by returning the future itself (if no processing must be done), or await'ing and dealing with the returned value (but you'll still be returning a future).