package com.stt import android.content.Intent import android.os.Bundle import android.speech.RecognitionListener import android.speech.RecognizerIntent import android.speech.SpeechRecognizer import com.facebook.react.bridge.* import com.facebook.react.modules.core.DeviceEventManagerModule class STTModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext), RecognitionListener { private var speechRecognizer: SpeechRecognizer? = null override fun getName(): String = "SpeechToText" @ReactMethod fun startListening(language: String?) { val lang = language ?: "en-US" val mainHandler = android.os.Handler(android.os.Looper.getMainLooper()) mainHandler.post { if (speechRecognizer == null) { speechRecognizer = SpeechRecognizer.createSpeechRecognizer(reactApplicationContext) speechRecognizer?.setRecognitionListener(this) } val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply { putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM) putExtra(RecognizerIntent.EXTRA_LANGUAGE, lang) } speechRecognizer?.startListening(intent) } } @ReactMethod fun stopListening() { val mainHandler = android.os.Handler(android.os.Looper.getMainLooper()) mainHandler.post { speechRecognizer?.stopListening() } } private fun sendEvent(eventName: String, data: String) { reactApplicationContext .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) .emit(eventName, data) } // RecognitionListener methods override fun onResults(results: Bundle?) { val matches: ArrayList? = results?.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION) if (!matches.isNullOrEmpty()) { sendEvent("onSpeechResults", matches[0]) } } override fun onError(error: Int) { sendEvent("onSpeechError", "Speech recognition error code: $error") } override fun onReadyForSpeech(params: Bundle?) {} override fun onBeginningOfSpeech() {} override fun onRmsChanged(rmsdB: Float) {} override fun onBufferReceived(buffer: ByteArray?) {} override fun onEndOfSpeech() {} override fun onPartialResults(partialResults: Bundle?) {} override fun onEvent(eventType: Int, params: Bundle?) {} }