即使传递了哈希映射参数,语音进度监听器仍未被调用

3

这是我的代码,我有一系列问题需要通过TTS提问,在每个问题之后会调用语音识别器。但我的话语监听器从未被调用。

   @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 返回值为0。


1
我曾经遇到过类似的问题。最终我在onInit()方法中使用了已弃用的setOnUtteranceCompletedListener()。 - Aditya Gupta
2个回答

3
这是您脚本的修改版本,在语音合成监听器中调用了onDone()方法。为了创建一个简单的示例,我已经删除了许多与TTS播放没有直接关联的功能。如果这对您有用,那么您可以逐个添加其他功能,并在此过程中进行测试以确保不会出现任何故障。
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");
    } 
}

1
我不确定确切的情况,也不确定这个答案是否能帮到你,但我认为你不应每次请求TTS发音时都设置UtteranceProgressListener,而应该在onInit()中设置一次监听器。请注意,空文本将不会被朗读,因此也不会调用回调函数。
虽然对我来说,在TTS初始化后设置监听器看起来很好,并且在我的Nexus5和GalaxyS4上无问题运行,即使每次请求TTS发音时都设置监听器,所以可能存在某些设备特定问题或某些TTS引擎特定问题。
哎呀,我忘了提到UtteranceProgressListener仅适用于API级别15及以上,因此在API级别14及以下,监听器将不会被调用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接