Advanced result listener not called even after passing hashmap parameter

Here is my code, I have a series of questions to be asked by TTS and after each question the speech recognizer will be called. My statement listener is never called.

   @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_speech_recognizer);
            tts = new TextToSpeech(this /* context */, this /* listener */);
}

//This is called after first time user clicks a button

    private void processEnquiry() {
            // TODO Auto-generated method stub
            for(int i=0;i<EnquiryList.size();i++)
            {
                speak(EnquiryList.get(i).toString());

            }
        }

        @Override
        public void onInit(int status) {
            if (status == TextToSpeech.SUCCESS) {
                initialized = true;
                tts.setLanguage(Locale.ENGLISH);
                if (queuedText != null) {
                    speak(queuedText);
                }
            }
        }

        public void speak(String text) {
            // If not yet initialized, queue up the text.
            if (!initialized) {
                queuedText = text;
                return;
            }
            queuedText = null;
            // Before speaking the current text, stop any ongoing speech.
            //tts.stop();
            // Speak the text.
            setTtsListener();
            HashMap<String, String> map = new HashMap<String, String>();
            map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,"MessageId");
            tts.speak(text, TextToSpeech.QUEUE_ADD, map);
        }
    private void setTtsListener()
        {
        final SpeechRecognizer callWithResult = this;

        int listenerResult = tts.setOnUtteranceProgressListener(new UtteranceProgressListener()
        {
        @Override
        public void onDone(String utteranceId)
        {
        callWithResult.onDone(utteranceId);
        }
        @Override
        public void onError(String utteranceId)
        {
        callWithResult.onError(utteranceId);
        }
        @Override
        public void onStart(String utteranceId)
        {
        callWithResult.onStart(utteranceId);
        }
        });
        if (listenerResult != TextToSpeech.SUCCESS)
        {
        Log.e(TAG, "failed to add utterance progress listener");
        }


        }
         public void onDone(String utteranceId)
         {
             callSpeechRecognition();
         }
         public void onError(String utteranceId)
         {
         }
         public void onStart(String utteranceId)
         {
         }

      

TextToSpeech.SUCCESS returns 0.

+3


source to share


2 answers


Here's a modified version of your script where the method is called onDone()

in a listened editor. I've eliminated many features that are not directly related to TTS playback to create a barebones sample. If this works for you, you can add other features one at a time, testing that nothing breaks along the way.



import android.app.Activity;
import android.os.Bundle;
import android.speech.SpeechRecognizer;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
import android.util.Log;
import android.view.View;

import java.util.HashMap;
import java.util.Locale;


public class MainActivity extends Activity implements TextToSpeech.OnInitListener {

    private TextToSpeech tts;
    private SpeechRecognizer sr;

    private boolean initialized;
    private String queuedText;
    private String TAG = "TTS";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_speech_recognizer);
        tts = new TextToSpeech(this /* context */, this /* listener */);
        tts.setOnUtteranceProgressListener(mProgressListener);

        sr = SpeechRecognizer.createSpeechRecognizer(this); // added
    }

    // Modified for testing purposes

    //This is called after first time user clicks a button
    /*
    private void processEnquiry() {
        for (int i = 0; i < EnquiryList.size(); i++) {
            speak(EnquiryList.get(i).toString());
        }

    }
    */

    public void processEnquiry(View v) {
        speak("Process enquiry");
    }
    // End of modification

    @Override
    public void onInit(int status) {
        if (status == TextToSpeech.SUCCESS) {
            initialized = true;
            tts.setLanguage(Locale.ENGLISH);

            if (queuedText != null) {
                speak(queuedText);
            }
        }
    }

    public void speak(String text) {
        // If not yet initialized, queue up the text.
        if (!initialized) {
            queuedText = text;
            return;
        }
        queuedText = null;
        // Before speaking the current text, stop any ongoing speech.
        //tts.stop();
        // Speak the text.
        setTtsListener(); // no longer creates a new UtteranceProgressListener each time
        HashMap<String, String> map = new HashMap<String, String>();
        map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "MessageId");
        tts.speak(text, TextToSpeech.QUEUE_ADD, map);
    }

    private void setTtsListener() {
        // Method radically simplified; callWithResult is retained but not used here
        final SpeechRecognizer callWithResult = sr; // was `this`
    }

    private UtteranceProgressListener mProgressListener = new UtteranceProgressListener() {
        @Override
        public void onStart(String utteranceId) {
        } // Do nothing

        @Override
        public void onError(String utteranceId) {
        } // Do nothing.

        @Override
        public void onDone(String utteranceId) {
            callSpeechRecognition();
        }
    };

    private void callSpeechRecognition() {
        Log.d(TAG, "callSpeechRecognition() called");
    } 
}

      

+2


source


I'm not sure exactly and not sure if this answer will help you, but I think you shouldn't set the UtteranceProgressListener every time you ask for TTS so you can speak, instead you should set the onInit () listener once. Note that empty text will not be spoken, so the caller will not be called.

Although basically setting the listener after TTS initialization works great for me and works without issue on my Nexus5 and GalaxyS4, even if you set the listener every time I ask TTS to speak, so there might be some device specific issues or some kind of TTS engine specific problems.



Unfortunately I forgot to mention that the UtteranceProgressListener is available at API level 15 and above, so the listener will not be called at API level 14 and below.

+1


source







All Articles