Search code examples
androidtext-to-speech

UtteranceProgressListener is not getting called in api level above 21


I want to know why my UtteranceProgressListener is not getting called. Here is how i am trying to do this

 private UtteranceProgressListener progressListener=new UtteranceProgressListener() {
    @Override
    public void onStart(String utteranceId) {
        Log.d("modroid", "speech started");

    }

    @Override
    public void onDone(String utteranceId) {
        Log.d("modroid", "done");
    }

    @Override
    public void onError(String utteranceId) {
        Log.d("modroid", "error");

    }
};

  private void prepareTxtToSpeech() {
    textToSpeech = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
        @Override
        public void onInit(int status) {
            if (status == TextToSpeech.SUCCESS) {
                if (textToSpeech.isLanguageAvailable(Locale.US) == TextToSpeech.LANG_AVAILABLE) {
                    textToSpeech.setLanguage(Locale.ENGLISH);
                    textToSpeech.setSpeechRate(0.8f);
                    textToSpeech.setOnUtteranceProgressListener(progressListener);
                }
            } else if (status == TextToSpeech.ERROR) {
                Toast.makeText(context, context.getString(R.string.txttospeech_error), Toast.LENGTH_LONG).show();
            }
        }
    });
}

here is how i am calling speaking method

   public void speak(String text) {
    if (textToSpeech != null) {

        Log.d("modroid", "speaking: ");
        textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null, "some id");
    }
}

I know this type of questions has been asked before but nothing helped me. Please let me know where i am doing mistake.


Solution

  • You have to be careful how you 'validate' if a language is available and also if it sets correctly:

        switch (textToSpeech.isLanguageAvailable(Locale.US)){
    
            case TextToSpeech.LANG_AVAILABLE:
                break;
            case TextToSpeech.LANG_COUNTRY_AVAILABLE:
                break;
            case TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE:
                break;
            case TextToSpeech.LANG_MISSING_DATA:
                break;
            case TextToSpeech.LANG_NOT_SUPPORTED:
                break;
        }
    

    You should also check the response of textToSpeech.setLanguage(Locale.ENGLISH) in the same way.

    One of the top three would probably be acceptable to you. Otherwise, you would need to handle the problem.

    setLanguage()

    isLanguageAvailable()