This code below works. But it sits in the MainActivity.kt, the spoken words are retrieved under the resultLauncher code.
fun askSpeechInput(context: Context, viewModel: SettingsViewModel) {
if (!SpeechRecognizer.isRecognitionAvailable(context)) {
Toast.makeText(context, "Speech not Available", Toast.LENGTH_SHORT).show()
} else {
val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
intent.putExtra(
RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH
)
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault())
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Talk")
intent.putExtra()
resultLauncher.launch(intent).let {
viewModel.reactToSpeech(speechInput.value.toString().lowercase())
}
}
}
private var resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult())
{ result ->
if(result.resultCode == Activity.RESULT_OK){
val data: Intent? = result.data
val result = data?.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS)
speechInput.value = result?.get(0).toString()
}
}
I am trying to do them same with this code below, but, this does not respond. Is it possible to achieve the same functionality from within a ViewModel class? If yes, how can I run the Intent.
@HiltViewModel
class SettingsViewModel @Inject constructor(
private val settingsRepository: SettingsRepository
) : ViewModel(), RecognitionListener
{
data class SpeechState(
val spokenText: String = "",
val error: String = ""
)
private val _settings = MutableStateFlow(value = Settings())
val settings: StateFlow<HomeSettings> = _settings.asStateFlow()
private val speechState = MutableStateFlow(value = SpeechState())
private val speechRecognizer: SpeechRecognizer = createSpeechRecognizer(application.applicationContext).apply {
setRecognitionListener(this@SettingsViewModel)
}
private fun updateResults(speechBundle: Bundle?) {
val userSaid = speechBundle?.getStringArrayList(RESULTS_RECOGNITION)
speechState.value = speechState.value.copy(spokenText = userSaid?.get(0) ?: "")
reactToSpeech(speechState.value.spokenText)
}
override fun onEndOfSpeech() = speechRecognizer.stopListening()
override fun onResults(results: Bundle?) = updateResults(speechBundle = results)
override fun onPartialResults(results: Bundle?) = updateResults(speechBundle = results)
override fun onError(errorCode: Int) {}
private val recognizerIntent: Intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply {
putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, application.packageName)
putExtra(
RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH
)
putExtra(RecognizerIntent.EXTRA_PROMPT, "Talk")
//putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true)
}
init {}
fun startListening(){
speechRecognizer.startListening(recognizerIntent)
}
private fun reactToSpeech(speech: String){
when(speech){
"run" -> Log.w("App", "Running!")
"stop" -> Log.w("App", "Stopped!")
else -> {}
}
}
override fun onReadyForSpeech(p0: Bundle?) {}
override fun onBeginningOfSpeech() {}
override fun onRmsChanged(p0: Float) {}
override fun onBufferReceived(p0: ByteArray?) {}
override fun onEvent(p0: Int, p1: Bundle?) {}
}
from Run Intent from within @HiltViewModel and get results
No comments:
Post a Comment