Text to Speech API 未调用 setOnUtteranceCompletedListener

Text to Speech API not calling setOnUtteranceCompletedListener

我想要的:
我想在 TextToSpeech 程序完成朗读时收到通知,并且我想在它完成朗读任务时执行一些 GUI 任务。

我知道的:

setOnUtteranceCompletedListener 可以用作回调,它应该通知我它已经发现 speaking.It 在 API 级别 15 中贬值,但它仍然应该工作。

setOnUtteranceProgressListener 是另一种更好的接收回调以启动完成和错误通知的方法。实现此接口至少需要 API 级别 15。我将我的最低 sdk 版本更改为 15 并尝试了这种方法,但它对我也不起作用。

这是我的代码

    public class SpeakingNotepad extends AppCompatActivity  implements TextToSpeech.OnUtteranceCompletedListener{

    Button btnSpeak;
    EditText etText;
    TextToSpeech speaker;
    SpeechRecognizer voiceRecognizer;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_speaking_notepad);
        init();
    }

    private void init() {
        speaker = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                speaker.setLanguage(Locale.ENGLISH);
            }
        });
        speaker.setOnUtteranceCompletedListener(this);
        btnSpeak = (Button) findViewById(R.id.btnSpeak);
        btnSpeak.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(etText.getText().length()>0)
                   speaker.speak(etText.getText().toString(),TextToSpeech.QUEUE_FLUSH,null);
            }
        });
        etText = (EditText) findViewById(R.id.etText);

    }

    @Override
    public void onUtteranceCompleted(String utteranceId) {
        Log.d("textToSpeech","completed");
        Toast.makeText(this,"completed",Toast.LENGTH_LONG).show();
        btnSpeak.setBackgroundColor(Color.BLACK);
    }
}

EDIT :使用 Handler 而不是 runOnUiThread() 方法。


我推荐你 OnUtteranceProgressListener 因为这个 API 有更多的方法来监听 TextToSpeech 的状态正在改变。

但是,如果您想使用 OnUtteranceCompleted Listener,请按如下方式编辑:

 public class SpeakingNotepad extends AppCompatActivity  implements TextToSpeech.OnUtteranceCompletedListener{
    private final String UTTER_ID = "utterance";
    private final int TTS_DONE = 99;

    Button btnSpeak;
    EditText etText;
    TextToSpeech speaker;
    SpeechRecognizer voiceRecognizer;

    HashMap<String, String> ttsOptions;
    MainViewHandler g_hnd;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        g_hnd = new MainViewHandler(SpeakingNotepad.this);
        init();
    }

    private void init() {
        speaker = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                ttsOptions = new HashMap<String, String>();
                ttsOptions.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, UTTER_ID);

                speaker.setLanguage(Locale.ENGLISH);
            }
        });
        speaker.setOnUtteranceCompletedListener(this);
        btnSpeak = (Button) findViewById(R.id.btnSpeak);
        btnSpeak.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(etText.getText().length()>0)
//                    speaker.speak(etText.getText().toString(),TextToSpeech.QUEUE_FLUSH,null);
                    speaker.speak(etText.getText().toString(),TextToSpeech.QUEUE_FLUSH,ttsOptions);
            }
        });
        etText = (EditText) findViewById(R.id.etText);
    }

    @Override
    public void onUtteranceCompleted(String utteranceId) {
        if (utteranceId.equals(UTTER_ID)) {
            Log.d("textToSpeech", "completed");
            /*
            // for more common usage, use `Handler` instead of `runOnUiThread()`.
            // block
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(SpeakingNotepad.this, "completed", Toast.LENGTH_LONG).show();
                    btnSpeak.setBackgroundColor(Color.BLACK);
                }
            });
            */

            // then, you just call `sendMessage()`.
            g_hnd.sendMessage(TTS_DONE);
        }
    }

    private static class MainViewHandler extends Handler {
        private final WeakReference<SpeakingNotepad> mAct;

        MainViewHandler(SpeakingNotepad act) {
            mAct = new WeakReference<SpeakingNotepad>(act);
        }

        public void handleMessage(Message msg) {
            SpeakingNotepad act = mAct.get();
            if (act != null) {
                act.handleMessage(msg)
            }
        }
    }

    private void handleMessage(Message msg) {
        switch(msg.what) {
            case TTS_DONE:
                Toast.makeText(SpeakingNotepad.this, "completed", Toast.LENGTH_LONG).show();
                btnSpeak.setBackgroundColor(Color.BLACK);
                break;
        }
    }
}