1

In Android while using SpeechRecognizer, I have noticed that SpeechRecognizer stopped listening automatically in few seconds.

I am working on an app that requires continuous speech input from the user. Our app needs to work without internet. For speech recognition we are using SpeechRecognizer class.

Below is the implementation: (in Kotlin)

var recognizer = SpeechRecognizer.createSpeechRecognizer(this.applicationContext)
recognizer!!.setRecognitionListener(RecognitionListener(this))

To start Listening

val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, "com.taazaa.texttospeechdemo")
recognizer!!.startListening(intent)

This is working fine until user takes a pause while speaking.

I need following implementation:

  1. SpeechRecognizer should not stop listening until user manually stop recognition.

    recognizer!!.stopListening()

  2. Everytime when recognition starts or stops device makes a beep sound which I need to stop.

  3. App should work in Offline Mode mostly.

    let me know what I am doing wrong and what need to implement to support above two points. Google Bolo is doing this so there could be a way. Google bolo: https://play.google.com/store/apps/details?id=com.google.android.apps.seekh&hl=en_IN

I tried many links and some of them are mentioned below:

Offline Speech Recognition in Android

Offline Speech Recognition In Android (JellyBean)

How to handle ERROR_RECOGNIZER_BUSY

Speech to Text on Android

Community
  • 1
  • 1
Satish Azad
  • 2,302
  • 1
  • 16
  • 35

1 Answers1

0

You could give a look at this example that uses SpeechRecognizer without internet:

*By the way, it's in japanesse.

About the continious listening... it's kind of tricky with Android's SpeechRecognizer library. I have done this before long time ago and the problem was about the device's microphones. If it is, in some way, blocked or interrupted by something, let's say the entrance is covered with something or the person is using handfree (bluetooth, that's another thing to think too), the results won't be 100% success.

I could recomend you to use the component Service. This will keep the SpeechRecognizer ongoing. But consider the states:

  • listening -> process** -> answer -> action -> listening again

**In process, the app could fail listening, you will neeed to handle that too.

And as the component Service is running on background, you will need to connect this with your activities or fragments (maybe using Binders or Broadcast, depends on your app)

class ServiceSpeech : Service(), RecognitionListener {

    val mVoiceBinder: IBinder = LocalBinder()

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return START_STICKY
    }

    inner class LocalBinder : Binder() {
        fun getService(): ServiceSpeech? {
            return this@ServiceSpeech
        }
    }

    /*
    *
    * create the methods for:
    * build speechrecognizer
    * startlistening
    * stoplistening
    * listeningAgain
    * send the results to activity/fragment
    *
    * */

    override fun onBind(p0: Intent?): IBinder? {
        return mVoiceBinder
    }

    override fun onReadyForSpeech(p0: Bundle?) {
        //important
    }

    override fun onBeginningOfSpeech() {
        //important
    }

    override fun onError(p0: Int) {
        //important, you could check SpeechRecognizer.ERROR_* to handle the errors
    }

    override fun onRmsChanged(p0: Float) {
        //handle some events, will give you the sound intensity
    }

    override fun onPartialResults(p0: Bundle?) {
        //important
    }

    override fun onResults(p0: Bundle?) {
        //important
    }

    override fun onEndOfSpeech() {
        //important
    }

    override fun onEvent(p0: Int, p1: Bundle?) {
    }

    override fun onBufferReceived(p0: ByteArray?) {
    }
}

I hope this can help you.