КОТЛИН — повтор TextToSpeech

#android #loops #kotlin #text-to-speech

Вопрос:

Мне было интересно, возможно ли, что, как только я включаю преобразование текста в речь, это преобразование текста в речь постоянно считывает значение

 currentItem.percent
           
 

это значение постоянно обновляется, поэтому я хочу, чтобы каждое новое значение читалось вслух

  tts = TextToSpeech(Context, TextToSpeech.OnInitListener { status ->

                    if (status != TextToSpeech.ERROR) // if no error set language
                        tts.language = Locale.UK


                    tts.speak(
                        currentItem.percent.toString(),
                        TextToSpeech.QUEUE_ADD,
                        null,
                        ""
                    );

                    tts.speak(
                        currentItem.percent.toString(),
                        TextToSpeech.QUEUE_ADD,
                        null,
                        ""
                    );
 

приведенный выше код просто считывает одно и то же значение процента дважды? есть идеи, как это исправить?

Редактировать

Я также попробовал этот цикл, но безуспешно, приложение не считывает новое значение и продолжает каждый раз повторять одно и то же значение

     for (i in 0..6) {
tts.speak(
currentItem.percent.toString(),
TextToSpeech.QUEUE_ADD,
 null,
""
);
 

Ответ №1:

Причина, по которой вы слышите повторение одного и того же значения, заключается в том, что speak метод не ждет завершения синтеза речи, прежде чем вернуться. Из документов:

Этот метод является асинхронным, т. е. метод просто добавляет запрос в очередь запросов TTS, а затем возвращает. Синтез, возможно, не был завершен (или даже начат!) в то время, когда возвращается этот метод.

(Документы разработчика Android)

Это означает, что когда вы звоните speak несколько раз подряд, вы на самом деле просто добавляете одно и то же значение в очередь несколько раз.

Вместо этого вам нужно вводить небольшую задержку при каждом звонке speak . Один из способов сделать это-использовать а Handler в своей деятельности.

 private val handler = Handler()
 

Затем создайте метод, который будет одновременно считывать текущее значение и ставить в очередь новую задачу, чтобы прочитать ее позже:

 val delayMs = 2000

fun speakCurrentValue() {
    tts.speak(
        currentItem.percent.toString(),
        TextToSpeech.QUEUE_ADD,
        null,
        ""
    )
    handler.postDelayed(Runnable { speakCurrentValue() }, delayMs)
}
 

Теперь, после вашего звонка speakCurrentValue , он будет продолжать стоять в очереди, чтобы его можно было запустить позже.

Комментарии:

1. если это находится внутри фрагмента, является ли код тем же самым?

2. Да, вместо этого вы можете создать обработчик внутри фрагмента 👍

3. я попробовал этот код еще раз, при добавлении обработчика я представил ожидаемый установщик свойств ошибок или получатель, что мне здесь делать