1

Hi I'm implementing continuous speech listening in my application, but when i destroy the speech recognizer in onPause i get not connected to the recognition service error.

I already read this question, and the relative answer, but it doesn't seem to solve the problem.

This is the code that generates the error:

// Activity code
@Override
public void onPause()
{
    assistant.dismiss();
    super.onPause();
}

@Override
public void onResume()
{
    super.onResume();
    assistant = new Assistant(this);
    Log.d(TAG,"resume");
}

Assistant code:

public class Assistant extends UtteranceProgressListener implements RecognitionListener, TextToSpeech.OnInitListener
{
private static final String TAG = "Assistant" ;

private Context context ;

private Intent intent ;
private SpeechRecognizer speechRecognizer;
private TextToSpeech textToSpeech;

private static AudioManager audioManager;

private boolean isAudioMute;

String actionAnswer ;

public Assistant ( Context context )
{
    this.context = context;

    isAudioMute = false ;

    textToSpeech = new TextToSpeech(context, this);
    textToSpeech.setOnUtteranceProgressListener(this);

    if ( SpeechRecognizer.isRecognitionAvailable(context))
    {
        intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
                context.getPackageName());

        speechRecognizer = SpeechRecognizer.createSpeechRecognizer(context);

        speechRecognizer.setRecognitionListener(this);

        audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
    }
    else
    {
        Log.e(TAG, "speech recognizer not avaiable");
    }
}

private void startListening()
{
    if ( !isAudioMute )
    {
        audioManager.setStreamMute(AudioManager.STREAM_MUSIC, true);
        isAudioMute = true ;
    }

    ((Activity)context).runOnUiThread(new Runnable()
    {
        @Override
        public void run()
        {
            speechRecognizer.startListening(intent);
            Log.d(TAG, "startlisten");
        }
    });
}

private void stopListening()
{
    speechRecognizer.stopListening();

    try
    {
        // wait for annoying sound to happens, then unmute channel.
        Thread.sleep(400);
    }
    catch (InterruptedException e)
    {
        e.printStackTrace();
    }

    Log.d(TAG, "stoplistne");

    if ( isAudioMute )
    {
        audioManager.setStreamMute(AudioManager.STREAM_MUSIC, false);
        isAudioMute = false ;
    }
}

public void dismiss()
{
    ((Activity)context).runOnUiThread(new Runnable()
    {
        @Override
        public void run()
        {
            speechRecognizer.stopListening();
            speechRecognizer.cancel();
            speechRecognizer.destroy();
            speechRecognizer = null;
        }
    });

    try
    {
        // wait for annoying sound to happens, then unmute channel.
        Thread.sleep(400);
    }
    catch (InterruptedException e)
    {
        e.printStackTrace();
    }

    Log.d(TAG, "stoplistne");

    if ( isAudioMute )
    {
        audioManager.setStreamMute(AudioManager.STREAM_MUSIC, false);
        isAudioMute = false ;
    }

    textToSpeech.stop();
    textToSpeech.shutdown();
    textToSpeech = null;
}

private void speakOut(String text)
{
    stopListening();

    if (Build.VERSION.SDK_INT >= 21 )
    {
        if (textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null, this.getClass().getName()) != TextToSpeech.SUCCESS)
            Log.e(TAG, "failed to queue text " + text);
    }
    else
    {
        if (textToSpeech.speak(text.toString(), TextToSpeech.QUEUE_FLUSH, null) != TextToSpeech.SUCCESS)
            Log.e(TAG, "failed to queue text " + text);
    }
}

// text to speech
@Override
public void onInit(int status)
{
    if (status == TextToSpeech.SUCCESS)
    {
        int result = textToSpeech.setLanguage(Locale.US);

        if (result == TextToSpeech.LANG_MISSING_DATA
                || result == TextToSpeech.LANG_NOT_SUPPORTED)
        {
            Log.e(TAG, "This Language is not supported");
            return;
        }

        speakOut("Assistant Ready");

    }
    else
    {
        Log.e(TAG, "Initilization Failed!");
    }
}

// SpeechRecognizer
@Override
public void onReadyForSpeech(Bundle params)
{
    Log.d(TAG, "readyforspeech");
}

// SpeechRecognizer
@Override
public void onBeginningOfSpeech()
{
    Log.d(TAG, "beginningofspeech");
}

// SpeechRecognizer
@Override
public void onRmsChanged(float rmsdB)
{

}

// SpeechRecognizer
@Override
public void onBufferReceived(byte[] buffer)
{
    Log.d(TAG, "bufferreceived");
}

// SpeechRecognizer
@Override
public void onEndOfSpeech()
{
    Log.d(TAG, "endofspeech");
}

// SpeechRecognizer
@Override
public void onError(int error)
{
    Log.d("SPEECH", "onError: " + error);
    switch(error)
    {
        case SpeechRecognizer.ERROR_AUDIO:
            Log.d(TAG,"ERROR_AUDIO");
            break;
        case SpeechRecognizer.ERROR_CLIENT:
            Log.d(TAG,"ERROR_CLIENT");
            break;
        case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS:
            Log.d(TAG,"ERROR_INSUFFICIENT_PERMISSIONS");
            break;
        case SpeechRecognizer.ERROR_NETWORK:
            Log.d(TAG,"ERROR_NETWORK");
            break;
        case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
            Log.d(TAG,"ERROR_NETWORK_TIMEOUT");
            break;
        case SpeechRecognizer.ERROR_NO_MATCH:
            Log.d(TAG,"ERROR_NO_MATCH");
            startListening();
            break;
        case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
            Log.d(TAG,"ERROR_RECOGNIZER_BUSY");
            break;
        case SpeechRecognizer.ERROR_SERVER:
            Log.d(TAG,"ERROR_SERVER");
            break;
        case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
            Log.d(TAG,"ERROR_SPEECH_TIMEOUT");
            startListening();
            break;
        default:
            Log.d(TAG,"ERROR_UNKNOWN");
    }
}

// SpeechRecognizer
@Override
public void onResults(Bundle results)
{
    ArrayList<String> res = results. getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION) ;
    Log.i(TAG,"res: '" + res.get(0) +"'.");
    actionAnswer = res.get(0);
    speakOut(actionAnswer);
}

// SpeechRecognizer
@Override
public void onPartialResults(Bundle partialResults)
{

}

// SpeechRecognizer
@Override
public void onEvent(int eventType, Bundle params)
{

}

// Utterance progress listener
@Override
public void onStart(String utteranceId)
{
    Log.d(TAG, "onstart");
}

// Utterance progress listener
@Override
public void onDone(String utteranceId)
{
    Log.d(TAG, "ondone");
    startListening();
}

// Utterance progress listener
@Override
public void onError(String utteranceId)
{
    Log.d(TAG, "onerror");
}
}

Anyway, even if the error occurs, when i reinitialize the speech recognizer everything works fine, so i'm not sure if i have to worry about the error.

Community
  • 1
  • 1
deight
  • 331
  • 1
  • 4
  • 15
  • have you gone through this http://developer.android.com/reference/android/speech/SpeechRecognizer.html – rogerwar May 11 '15 at 09:38
  • yeah, but other than saying that i should't use it for continuous listening i didn't see any reference to how to stop it correctly. – deight May 11 '15 at 10:17
  • can you share your full activity code? – rogerwar May 11 '15 at 12:41
  • hve you read this line in doc"The implementation of this API is likely to stream audio to remote servers to perform speech recognition. As such this API is not intended to be used for continuous recognition, which would consume a significant amount of battery and bandwidth. " – rogerwar May 11 '15 at 12:52
  • Yeah, but that does't explain the error, anyway i added the code of the assistant – deight May 11 '15 at 13:00

1 Answers1

2

Don't use speechRecognizer.stopListening() and speechRecognizer.cancel(), Use speechRecognizer.destroy() instead.

Jonas Czech
  • 12,018
  • 6
  • 44
  • 65
Bina
  • 21
  • 2