什么TtsService可以解释playEarcon()缺少onUtteranceCompleted()?

时间:2012-07-13 12:23:43

标签: android text-to-speech android-mediaplayer onutterancecompleted

前段时间,我发现playEarcon() never produces onUtteranceCompleted()

当时我刚刚解释说“当话语被合成时称呼”的文档,因为onUtteranceCompleted()不适用于耳塞因为,一个earcon实际上并不是一个结果TTS合成。

但再看看Android的源代码,我根本找不到能够证明我解释的解释。

关于my test jig的一些事实:

  1. onUtteranceCompleted()总是到达earcon之前的话语ID。那句话是一种普通的TTS话语,而不是一种耳语。
  2. 之后的earcon 播出(即完全符合预期)。
  3. onUtteranceCompleted()显示的是从不。这是非常一致和可重复的行为。
  4. 深入研究TtsService源代码,似乎只有2种方法可能会影响onUtteranceCompleted()的到达(或缺席):

    1. TtsService.processSpeechQueue()
    2. TtsService.onCompletion()
    3. 如果您检查该代码,您将看到第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()

      1. currentSpeechItemCopy == null
      2. utteranceId.length()== 0
      3. 但我肯定知道条件#2可以排除,因为我记录所有的话语和耳塞肯定在那里。

        另外,检查整个系统日志:

        Log.v(SERVICE_TAG, "TTS callback: dispatch started");
        

        丢失的onUtteranceCompleted()可能是dispatchUtteranceCompletedCallback()未被调用的结果,但也可能是mCallbacksMap.get(packageName)返回null的结果。

        所以,我们又有两种可能性,这两种可能性对我来说都没有多大意义:

        1. 当调用earcon onCompletion()时,earcon的mCurrentSpeechItem为空。但为什么?
        2. mCallbacksMap为空。它是什么以及何时填充?
        3. 解决这个谜团的任何建议或其他解释?

1 个答案:

答案 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);
     }
     ...
 }