@ -66,8 +66,9 @@ import 'package:flutter/material.dart';
import ' package:flutter_tts/flutter_tts.dart ' ;
import ' package:permission_handler/permission_handler.dart ' ;
import ' package:provider/provider.dart ' ;
/ / import ' package:speech_to_text/speech_recognition_error.dart ' ;
/ / import ' package:speech_to_text/speech_to_text.dart ' as stt ;
import ' package:speech_to_text/speech_recognition_error.dart ' ;
import ' package:speech_to_text/speech_to_text.dart ' as stt ;
import ' package:speech_to_text/speech_to_text.dart ' ;
import ' package:url_launcher/url_launcher.dart ' ;
class FloatingSearchButton extends StatefulWidget {
@ -83,7 +84,8 @@ class _FloatingSearchButton extends State<FloatingSearchButton> with TickerProvi
RobotProvider eventProvider = RobotProvider ( ) ;
bool isLoading = false ;
bool isError = false ;
/ / stt . SpeechToText speech = stt . SpeechToText ( ) ;
stt . SpeechToText speech = stt . SpeechToText ( ) ;
FlutterTts tts = FlutterTts ( ) ;
String error = ' ' ;
String _currentLocaleId = " " ;
String lastError ;
@ -92,7 +94,6 @@ class _FloatingSearchButton extends State<FloatingSearchButton> with TickerProvi
double minSoundLevel = 50000 ;
double maxSoundLevel = - 50000 ;
String reconizedWord = ' ' ;
FlutterTts flutterTts = FlutterTts ( ) ;
var selectedLang ;
bool isSearching = false ;
Map results = { } ;
@ -113,7 +114,7 @@ class _FloatingSearchButton extends State<FloatingSearchButton> with TickerProvi
void initState ( ) {
controller = AnimationController ( vsync: this , duration: Duration ( seconds: 1 ) ) ;
offset = Tween < Offset > ( begin: Offset ( 0.0 , 1.0 ) , end: Offset ( 0.0 , 0.0 ) ) . animate ( controller ) ;
startIosTts ( ) ;
if ( IS_VOICE_COMMAND_CLOSED = = true ) {
controller . reverse ( from: - 1 ) ;
} else {
@ -192,20 +193,20 @@ class _FloatingSearchButton extends State<FloatingSearchButton> with TickerProvi
: Image . asset ( ' assets/images/gif/robot-idle.gif ' ) ,
) ,
onTap: ( ) async {
/ / if ( Platform . isAndroid ) {
/ / if ( await PermissionService . isMicrophonePermissionEnabled ( ) ) {
/ / new RoboSearch ( context: context ) . showAlertDialog ( context ) ;
/ / initSpeechState ( ) . then ( ( value ) = > { startVoiceSearch ( ) } ) ;
/ / } else {
/ / Utils . showPermissionConsentDialog ( context , TranslationBase . of ( context ) . recordAudioPermission , ( ) {
/ / new RoboSearch ( context: context ) . showAlertDialog ( context ) ;
/ / initSpeechState ( ) . then ( ( value ) = > { startVoiceSearch ( ) } ) ;
/ / } ) ;
/ / }
/ / } else {
/ / new RoboSearch ( context: context ) . showAlertDialog ( context ) ;
/ / initSpeechState ( ) . then ( ( value ) = > { startVoiceSearch ( ) } ) ;
/ / }
if ( Platform . isAndroid ) {
if ( await PermissionService . isMicrophonePermissionEnabled ( ) ) {
new RoboSearch ( context: context ) . showAlertDialog ( context ) ;
initSpeechState ( ) . then ( ( value ) = > { startVoiceSearch ( ) } ) ;
} else {
Utils . showPermissionConsentDialog ( context , TranslationBase . of ( context ) . recordAudioPermission , ( ) {
new RoboSearch ( context: context ) . showAlertDialog ( context ) ;
initSpeechState ( ) . then ( ( value ) = > { startVoiceSearch ( ) } ) ;
} ) ;
}
} else {
new RoboSearch ( context: context ) . showAlertDialog ( context ) ;
initSpeechState ( ) . then ( ( value ) = > { startVoiceSearch ( ) } ) ;
}
} ,
) ,
Positioned (
@ -234,44 +235,60 @@ class _FloatingSearchButton extends State<FloatingSearchButton> with TickerProvi
] ) ) ;
}
/ / startVoiceSearch ( ) async {
/ / bool available = await speech . initialize ( onStatus: statusListener , onError: errorListener ) ;
/ / _currentLocaleId = await sharedPref . getStringWithDefaultValue ( APP_LANGUAGE , ' ar ' ) ;
/ /
/ / if ( available ) {
/ / speech . listen (
/ / onResult: resultListener ,
/ / / / listenMode: ListenMode . confirmation ,
/ / localeId: _currentLocaleId = = ' en ' ? ' en_US ' : ' ar_SA ' ,
/ / ) ;
/ / } else {
/ / print ( " The user has denied the use of speech recognition. " ) ;
/ / }
/ / / / some time later . . .
/ / / / speech . stop ( ) ;
/ / / / speech . listen (
/ / / / onResult: resultListener ,
/ / / / listenFor: Duration ( seconds: 10 ) ,
/ / / / localeId: _currentLocaleId = = ' en ' ? ' en-US ' : ' ar-SA ' ,
/ / / / onSoundLevelChange: soundLevelListener ,
/ / / / cancelOnError: true ,
/ / / / partialResults: true ,
/ / / / onDevice: true ,
/ / / / listenMode: ListenMode . deviceDefault ) ;
/ / }
startIosTts ( ) async {
await tts . setSharedInstance ( true ) ;
await tts . setLanguage ( " en-US " ) ;
tts . setIosAudioCategory (
IosTextToSpeechAudioCategory . playback ,
[ IosTextToSpeechAudioCategoryOptions . mixWithOthers ] ,
IosTextToSpeechAudioMode . voicePrompt ) ;
}
startVoiceSearch ( ) async {
bool available = await speech . initialize ( ) ;
_currentLocaleId = await sharedPref . getStringWithDefaultValue ( APP_LANGUAGE , ' ar ' ) ;
/ /
/ / if ( available ) {
/ / speech . listen (
/ / onResult: resultListener ,
/ / / / listenMode: ListenMode . confirmation ,
/ / localeId: _currentLocaleId = = ' en ' ? ' en_US ' : ' ar_SA ' ,
/ / ) ;
/ / } else {
/ / print ( " The user has denied the use of speech recognition. " ) ;
/ / }
/ / some time later . . .
if ( available ) {
speech . stop ( ) ;
speech . listen (
onResult: resultListener ,
listenFor: Duration ( seconds: 10 ) ,
localeId: _currentLocaleId = = ' en ' ? ' en-US ' : ' ar-SA ' ,
onSoundLevelChange: soundLevelListener ,
cancelOnError: true ,
partialResults: true ,
onDevice: true ,
listenMode: ListenMode . deviceDefault ) ;
}
}
void resultListener ( result ) {
_stopListening ( ) ;
reconizedWord = result . recognizedWords ;
event . setValue ( { " searchText " : reconizedWord } ) ;
if ( result . finalResult = = true ) {
Future . delayed ( const Duration ( seconds: 1 ) , ( ) {
_speak ( reconizedWord ) ;
RoboSearch . closeAlertDialog ( context ) ;
RoboSearch . closeAlertDialog ( context ) ;
/ / Navigator . of ( context ) . pop ( ) ;
} ) ;
}
}
void _stopListening ( ) async {
await speech . stop ( ) ;
/ / setState ( ( ) { } ) ;
}
Future _speak ( reconizedWord ) async {
getPages ( reconizedWord ) ;
}
@ -315,10 +332,10 @@ class _FloatingSearchButton extends State<FloatingSearchButton> with TickerProvi
/ / } ) ;
}
/ / void errorListener ( SpeechRecognitionError error ) {
/ / event . setValue ( { " searchText " : ' null ' } ) ;
/ / RoboSearch . closeAlertDialog ( context ) ;
/ / }
void errorListener ( SpeechRecognitionError error ) {
event . setValue ( { " searchText " : ' null ' } ) ;
RoboSearch . closeAlertDialog ( context ) ;
}
void statusListener ( String status ) {
/ / setState ( ( ) {
@ -807,7 +824,7 @@ class _FloatingSearchButton extends State<FloatingSearchButton> with TickerProvi
) ;
}
speak ( { isInit } ) async {
speak ( { isInit = false } ) async {
/ / if ( mounted ) {
setState ( ( ) {
this . networkImage = results [ ' AnimationURL ' ] ;
@ -817,12 +834,18 @@ class _FloatingSearchButton extends State<FloatingSearchButton> with TickerProvi
if ( isInit = = true ) {
event . setValue ( { " animationEnable " : ' true ' } ) ;
}
/ / var voice = await tts . getVoice ( ) ;
/ / print ( voice ) ;
if ( isArabic = = false & & results [ ' ReturnMessage ' ] ! = null & & isInit = = false ) {
await flutterTts . setVoice ( { " name " : " en-au-x-aub-network " , " locale " : " en-AU " } ) ;
await flutterTts . speak ( results [ ' ReturnMessage ' ] ) ;
/ / await tts . synthesizeToFile ( " Hello World " , Platform . isAndroid ? " tts.wav " : " tts.caf " ) ;
await tts . setVoice ( { " name " : " Karen " , " locale " : " en-AU " } ) ;
/ / await tts . setVoice ( { " name " : voice [ 35 ] [ " name " ] , " locale " : voice [ 35 ] [ " locale " ] } ) ;
await tts . speak ( results [ ' ReturnMessage ' ] ) ;
} else if ( results [ ' ReturnMessage_Ar ' ] ! = null & & isInit = = false ) {
await flutterTts . setVoice ( { " name " : " ar-xa-x-ard-network " , " locale " : " ar " } ) ;
await flutterTts . speak ( results [ ' ReturnMessage_Ar ' ] ) ;
/ / await tts . setVoice ( { " name " : voice [ 0 ] [ " name " ] , " locale " : voice [ 0 ] [ " locale " ] } ) ;
await tts. speak ( results [ ' ReturnMessage_Ar ' ] ) ;
}
stopAnimation ( isInit: isInit ) ;
@ -850,7 +873,7 @@ class _FloatingSearchButton extends State<FloatingSearchButton> with TickerProvi
}
initialSpeak ( ) async {
await flutterTts . awaitSpeakCompletion ( true ) ;
/ / await flutterTts . awaitSpeakCompletion ( true ) ;
results = {
' ReturnMessage_Ar ' : " هذه الخدمة تم تصميمها لتتمكن من ربط الملفات الطبية للعائلة بملفك الطبي حتى تتمكن من إدارة سجلاتهم عن طريق تسجيل الدخول إلى ملفك الطبي. " ,
' ReturnMessage ' : " Through this service, you will be able to link your family medical files to your medical file so that you can manage their records by login to your medical file. "
@ -875,21 +898,21 @@ class _FloatingSearchButton extends State<FloatingSearchButton> with TickerProvi
} ) ;
} ) ;
} else {
flu tterT ts. setCompletionHandler ( ( ) async {
event . setValue ( { " animationEnable " : ' false ' } ) ;
setState ( ( ) {
this . networkImage = null ;
this . isAnimationEnable = false ;
} ) ;
} ) ;
/ / tts. setCompletionHandler ( ( ) async {
/ / event . setValue ( { " animationEnable " : ' false ' } ) ;
/ / setState ( ( ) {
/ / this . networkImage = null ;
/ / this . isAnimationEnable = false ;
/ / } ) ;
/ / } ) ;
}
flutterTts . setCompletionHandler ( ( ) async {
event . setValue ( { " animationEnable " : ' false ' } ) ;
setState ( ( ) {
this . networkImage = null ;
this . isAnimationEnable = false ;
} ) ;
} ) ;
/ / flutterTts . setCompletionHandler ( ( ) async {
/ / event . setValue ( { " animationEnable " : ' false ' } ) ;
/ / setState ( ( ) {
/ / this . networkImage = null ;
/ / this . isAnimationEnable = false ;
/ / } ) ;
/ / } ) ;
}
signOut ( ) async {