Что в TtsService может объяснить отсутствие onUtteranceCompleted()для playEarcon()?

Некоторое время назад я обнаружил, чтоplayEarcon()никогда не производитonUtteranceCompleted().

В то время я просто интерпретировал документацию, в которой говорилось: «Вызывается, когда высказывание было синтезировано » как onUtteranceCompleted(), неприменимое для Earcons, потому что Earcon на самом деле не является результатом синтеза TTS.

Но просматривая исходный код Android, я просто не могу найти объяснение, которое оправдывало бы мою интерпретацию.

Несколько фактов о моем тестовом стенде:

  1. onUtteranceCompleted()всегда приходит для идентификатора высказывания, предшествующего Earcon. Это высказывание является обычным высказыванием TTS, а не слуховым аппаратом.
  2. Earcon после этого действительно воспроизводится (т.е. точно так, как задумано ).
  3. onUtteranceCompleted()ибо этот слуховой аппарат никогда не появляется. Это очень последовательное и воспроизводимое поведение.

Углубляясь в исходный код TtsService, кажется, что есть только 2 метода, которые могут повлиять на появление (или отсутствие )onUtteranceCompleted():

  1. TtsService.processSpeechQueue()
  2. TtsService.onCompletion()

Если вы изучите этот код, вы увидите, что третий кандидат, TtsService.getSoundResource()исключается (как ответственный за отсутствие onUtteranceComplete для моего наушника )из-за факта #2 выше :Earcon всегда воспроизводится, поэтому getSoundResource()не может возвращать значение null.

Используя ту же логику, первый кандидат, TtsService.processSpeechQueue(), также можно исключить, по тому же факту #2 :Earcon всегда играет, поэтому всегда выполняются следующие 2 критических утверждения:

1108   mPlayer.setOnCompletionListener(this);
...
1111   mPlayer.start();

Итак, у нас остался только второй кандидат, TtsService.onCompletion(), как возможное объяснение того, почемуplayEarcon()никогда не производит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 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();
}

Там есть только 2 условия, которые не могут привести к dispatchUtteranceCompletedCallback():

  1. currentSpeechItemCopy == ноль
  2. utteranceId.length ()== 0

Но я точно знаю, что условие #2 можно исключить, потому что я логирую все utteranceId и earcon'ы точно есть.

Кроме того, просмотр всего системного журнала:

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

Отсутствующий onUtteranceCompleted()может быть результатом dispatchUtteranceCompletedCallback()не вызывается, но это также может быть результатом того, что mCallbacksMap.get(packageName)возвращает null.

Итак, у нас снова осталось 2 возможности,и то, и другое не имеет для меня особого смысла:

  1. К тому времени, когда слуховой аппарат onCompletion()вызывается, Earcon's mCurrentSpeechItemимеет значение null. Но почему?
  2. mCallbacksMap пуст. Что это такое и когда оно заселено?

Любые предложения или другие объяснения для решения этой тайны?

34
задан Community 23 May 2017 в 12:26
поделиться