前段时间,我发现playEarcon()
never produces onUtteranceCompleted()
。
当时我刚刚解释说“当话语被合成时称呼”的文档,因为onUtteranceCompleted()
不适用于耳塞因为,一个earcon实际上并不是一个结果TTS合成。
但再看看Android的源代码,我根本找不到能够证明我解释的解释。
关于my test jig的一些事实:
onUtteranceCompleted()
总是到达earcon之前的话语ID。那句话是一种普通的TTS话语,而不是一种耳语。onUtteranceCompleted()
显示的是从不。这是非常一致和可重复的行为。深入研究TtsService源代码,似乎只有2种方法可能会影响onUtteranceCompleted()
的到达(或缺席):
如果您检查该代码,您将看到第3个候选人TtsService.getSoundResource()被排除(因为我的earcon缺乏onUtteranceComplete),因为上面的事实#2:earcon总是玩,因此getSoundResource()
不可能返回null。
使用相同的逻辑,第一个候选者TtsService.processSpeechQueue()也可以被排除,因为相同的事实#2:earcon总是在播放,因此总是执行以下两个关键语句:
1108 mPlayer.setOnCompletionListener(this);
...
1111 mPlayer.start();
所以,我们只剩下第二位候选人TtsService.onCompletion(),作为playEarcon()
never produces onUtteranceCompleted()
:
public void onCompletion(MediaPlayer arg0) {
// mCurrentSpeechItem may become null if it is stopped at the same
// time it completes.
SpeechItem currentSpeechItemCopy = mCurrentSpeechItem;
if (currentSpeechItemCopy != null) {
String callingApp = currentSpeechItemCopy.mCallingApp;
ArrayList<String> params = currentSpeechItemCopy.mParams;
String utteranceId = "";
if (params != null) {
for (int i = 0; i < params.size() - 1; i = i + 2) {
String param = params.get(i);
if (param.equals(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID)) {
utteranceId = params.get(i + 1);
}
}
}
if (utteranceId.length() > 0) {
dispatchUtteranceCompletedCallback(utteranceId, callingApp);
}
}
processSpeechQueue();
}
在那里,只有两个条件无法产生dispatchUtteranceCompletedCallback():
但我肯定知道条件#2可以排除,因为我记录所有的话语和耳塞肯定在那里。
另外,检查整个系统日志:
Log.v(SERVICE_TAG, "TTS callback: dispatch started");
丢失的onUtteranceCompleted()
可能是dispatchUtteranceCompletedCallback()未被调用的结果,但也可能是mCallbacksMap.get(packageName)
返回null的结果。
所以,我们又有两种可能性,这两种可能性对我来说都没有多大意义:
mCurrentSpeechItem
为空。但为什么? 解决这个谜团的任何建议或其他解释?
答案 0 :(得分:1)
在第android.speech.tts.TextToSpeech#playEarcon()行查看807。传递给文本到语音服务绑定器的params参数为null,这意味着服务永远不会收到您的话语ID。
public int playEarcon(String earcon, int queueMode,
HashMap<String,String> params) {
synchronized (mStartLock) {
...
result = mITts.playEarcon(mPackageName, earcon, queueMode, null);
}
...
}