LoginSignup
6
7

More than 5 years have passed since last update.

Androidのテキスト読み上げ機能TextToSpeechからCallbackを取得するときの注意点

Last updated at Posted at 2017-03-31

androidでTextToSpeechを使ったアプリを作った時のメモ

注意点

  1. utterance_idを設定しないとCallbackを受け取れない。
  2. 再生中にstopしたときのcallbackが異なる場合がある。
  3. callbackでの処理はUIスレッドで行う。

1. utterance_idを設定しないとCallbackを受け取れない。

callbackを取得するにはTextToSpeechのonInitで
textToSpeech.setOnUtteranceProgressListener(…)
をするのですが、
実際に音声を再生するメソッドのutteranceIdをセットしておかないとcallbackは受け取れません。特に4系以下ではHashMapでちゃんと設定しないといけないのでわかりにくい。

tts.java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
          //lollipop以上
                String id = String.valueOf(orderNo);
                textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null, utteranceId);
            } else {
          //kitkat以下
                HashMap<String, String> params = new HashMap<String, String>();
                String id = String.valueOf(orderNo);
                params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, id);
                textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, params);
            }

2. 再生中にstopしたときのcallbackが異なる場合がある。

再生が終わった時に呼ばれるonDoneの挙動に手持ちの端末で違いがあってかなりはまりました。
4系のGalaxyと5系のNexusではstopした時にonDoneが呼ばれるのですが、
6系のXperiaではstopした時にonDoneが呼ばれない。。。
自分の場合は停止ボタンで再生を停止する場合と、
再生が終わった時に次のTextをセットして再生を開始する制御に困った。

自分の対処法としてはTextToSpeechのステータスをenumで持っておいて、
stopボタンを押した時は停止状態のステータスにし、
onDoneの時に、ステータスを見て停止状態なら次の再生をセット
onStartのcallbackの時にステータスを再生状態にして対処。

tts.java
//stopボタンのsetOnClickListener時点で
//ttsStatus = TTSStatusEnum.STOP;にする

textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
                @Override
                public void onStart(String utteranceId) {
                  ttsStatus = TTSStatusEnum.PLAY;
                }

                @Override
                public void onDone(String utteranceId) {
                  if (ttsStatus == TTSStatusEnum.STOP) {
                    //既にstop
                    return;
                  }
                  ttsStatus = TTSStatusEnum.STOP;
                  //次の再生の処理…
                }
...

3. callbackでの処理はUIスレッドで行う。

 callbackで再生している文言の色を変えたい的なUIの処理は
明示的にUIスレッドで処理しないとダメ。

tts.java
textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
                @Override
                public void onStart(String utteranceId) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                           //textの色を赤にする処理
                        }
                    });
                }

                @Override
                public void onDone(String utteranceId) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                       //textの色を戻す処理
                       }
                    });
                }
...

参考:Android TTS onUtteranceCompleted callback isn't getting called

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7