androidでTextToSpeechを使ったアプリを作った時のメモ
注意点
- utterance_idを設定しないとCallbackを受け取れない。
- 再生中にstopしたときのcallbackが異なる場合がある。
- callbackでの処理はUIスレッドで行う。
1. utterance_idを設定しないとCallbackを受け取れない。
callbackを取得するにはTextToSpeechのonInitで
textToSpeech.setOnUtteranceProgressListener(…)
をするのですが、
実際に音声を再生するメソッドのutteranceIdをセットしておかないとcallbackは受け取れません。特に4系以下ではHashMapでちゃんと設定しないといけないのでわかりにくい。
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の時にステータスを再生状態にして対処。
//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スレッドで処理しないとダメ。
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