Text to Speech API不调用setOnUtteranceCompletedListener

时间:2016-01-28 09:41:37

标签: android text-to-speech

我想要的是什么:
我想在TextToSpeech程序完成说话时收到通知,我想在完成说话任务时执行一些GUI任务。

我所知道的:

setOnUtteranceCompletedListener 可以用作回叫,它应该通知我它已经发现了说话。它已经在API等级15中被摧毁但仍然可以工作。

setOnUtteranceProgressListener 是另一种接收回叫以启动finsishing和错误通知的更好方法。实现此接口需要最低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);
    }
}

1 个答案:

答案 0 :(得分:2)

编辑:使用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;
        }
    }
}