24

When I call the startListening method of a SpeechRecognizer object, the speech recognizer starts listening for speech. I would like to create a service that is waiting for speech of a specific keyword: when the user says this keyword and the speech recognizer detects this keyword, then the service becomes ready to receive user voice commands.

To this end, after a new SpeechRecognizer instantiated, I should call its startListening method: can I keep the speech recognizer listening indefinitely?

enzom83
  • 8,080
  • 10
  • 68
  • 114
  • 2
    sounds like you're making an android wiretap -- I Like!! – Kristian Apr 16 '12 at 23:02
  • 2
    The objective is to be able to control one or more applications using the voice. – enzom83 Apr 16 '12 at 23:08
  • 3
    Look at the app called Vlingo. They accomplish this by keeping the application running in the background waiting for the buzzword "Hey Vlingo..." This sounds like what you're looking for. I would try and sift through the many questions around here about keeping a service running in the background. This sounds like a good place to start for you. – gobernador Apr 16 '12 at 23:08
  • 1
    Did you figure it out? What did you do? I have been trying to figure this out for a month now! – Ruchir Baronia Jan 28 '16 at 01:02
  • Please note that no expert parameter tuning can overcome inherent bugs like this: https://issuetracker.google.com/issues/36955956 – WebViewer Nov 29 '22 at 10:11

2 Answers2

16

The Android Speech recognizer can be customized through the intent extra data. See the android documentation.

public static final String EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS

The amount of time that it should take after we stop hearing speech to consider the input complete. [...]

public static final String EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS Since: API Level 8

The minimum length of an utterance. We will not stop recording before this amount of time. [...]

public static final String EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS

The amount of time that it should take after we stop hearing speech to consider the input possibly complete. [...]

Set the EXTRA_LANGUAGE_MODEL to websearch to capture only relevant words.

rockeye
  • 2,765
  • 2
  • 30
  • 44
  • 3
    _Depending on the recognizer implementation, these values may have no effect_, so we may assume that these values ​​can not be changed. In this case, when the speech recognizer stops automatically because it has not detected any voice by the user, I should restart it again by calling the `startListening` method: however, this would create a time interval during which the speech recognizer is not listening, because the restart of listening may not be instantaneous. How to overcome this obstacle? – enzom83 Apr 17 '12 at 10:55
  • You can implement your own service instead of using the Google's one. But have you really tested to parametrize the Intent? I think it worth a try. I haven't done it on my own but I guess (blindly) that the original voice recognition service provided by Google has an implementation that uses these parameters, otherwise, they would not have been added so soon (API 8). The problem with a customize service might be the possible conflicts between yours and the original one. – rockeye Apr 17 '12 at 12:28
  • 6
    I noticed that the default value of `EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS` is around 10 seconds, because if I do not speak, the speech recognizer automatically stops listening after about 10 seconds. So I set `EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS` to 100000 milliseconds: in this way the speech recognizer should not stop recording before this amount of time (100 seconds), but it always stops after about 10 seconds. – enzom83 Apr 17 '12 at 12:41
  • Alternatively, I could use two `SpeechRecognizer` objects, so I could start the first one at the time _t0_ and the second one at the time _t0 + 5 seconds_. After about _t0 + 10 seconds_ the first speech recognizer will stop, but the second one is still listening... etc.. In this way, I keep the service listening indefinitely. Or I could use a single speech recognizer and I could restart it every time you stop: I could see a message such as "waiting ...", in the time interval during which the speech recognizer is not listening. – enzom83 Apr 21 '12 at 15:30
  • 1
    ok, this would work, but what if the user speaks between t0+8 and t0+12 ? One part of the word will be captured by the 1st recognizer, which won't recognize anything. Same for the 2nd... And the probability of this situation is rather high. Ok, this might "work" and used as a proof of concept, but if you plan to build a real product, I think you will have to build your own service. IMHO, this is the only proper way to achieve this. – rockeye Apr 23 '12 at 08:01
1

You can implement onError of RecognitionListener interface like this. It is continuously listening in your activity.

@Override
public void onError(int error) {
    String errorMessage = getErrorText(error);
    Log.i(Constants.TAG, "FAILED " + errorMessage);
    speech.destroy();
    speech = null;
    StartListening();
}

private void StartListening() {
    speech = SpeechRecognizer.createSpeechRecognizer(this);
    speech.setRecognitionListener(this);
    recognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "en");
    recognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
    recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
    recognizerIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 3);

    //if setting.SpeechEnable
    speech.startListening(recognizerIntent);
}
pushkin
  • 9,575
  • 15
  • 51
  • 95