Статьи

Android SDK: использование механизма преобразования текста в речь

Этот учебник научит вас озвучивать ваши приложения с помощью Android SDK text to voice engine!

Механизм преобразования текста в речь в Android по-прежнему кажется недостаточно используемым ресурсом в приложениях для Android. Однако реализовать его в своих собственных приложениях просто. Есть несколько потенциальных проблем и вариантов, которые вы должны рассмотреть, но для большинства целей этот процесс не является сложным. В этом уроке мы немного разберемся в одном Android Activity, но не волнуйтесь, полный код приведен в конце. Цель состоит в том, чтобы дать вам четкое представление о том, что происходит на каждом этапе обработки, чтобы вы могли успешно использовать функцию в любом приложении.


Если у вас уже есть приложение, с которым вы хотите реализовать Text To Speech, откройте его в вашей IDE. В противном случае создайте новый проект Android. Вы можете использовать код в этом руководстве с любым классом Activity. Для демонстрации мы сначала создадим несколько элементов пользовательского интерфейса. Опять же, если у вас уже есть свой собственный пользовательский интерфейс, вы можете использовать его вместо.


Добавьте некоторые элементы пользовательского интерфейса в ваше приложение, позволяя пользователю вводить текст и запускать воспроизведение речи с помощью кнопки. В файле макета XML для вашей деятельности, который будет «main.xml», если вы создали новый проект, добавьте следующую разметку:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
<TextView android:id=»@+id/intro»
    android:layout_width=»fill_parent»
    android:layout_height=»wrap_content»
    android:text=»Enter some text:»
/>
<EditText android:id=»@+id/enter»
    android:layout_width=»fill_parent»
    android:layout_height=»wrap_content»
/>
<Button android:id=»@+id/speak»
    android:layout_width=»wrap_content»
    android:layout_height=»wrap_content»
    android:text=»Speak»
/>

Ваши XML-файлы макета должны находиться в каталоге res / layout в пакете приложения. Этот код добавляет три элемента пользовательского интерфейса: метку с небольшим текстом инструкции, редактируемое текстовое поле и кнопку. Пользователь сможет ввести текст в поле, а затем нажать кнопку, чтобы услышать его произнесение. Если вы используете существующий проект, вы, конечно, можете использовать элементы интерфейса, которые у вас уже есть. Если вы используете эти новые элементы, вы можете изменить их в соответствии с дизайном вашего собственного приложения.

Пользовательский интерфейс приложения Speech

Откройте файл Java для действия, в котором вы хотите реализовать TTS. Если вы создали новое приложение, откройте файл основного класса. В Eclipse ваша активность должна автоматически содержать метод onCreate и расширять «активность» как часть ее объявления. Вверху файла класса добавьте следующие операторы импорта, чтобы ваше приложение могло прослушивать нажатия кнопок:

1
2
3
import android.view.View.OnClickListener;
import android.widget.Button;
import android.view.View;

Измените объявление класса, чтобы реализовать интерфейс «OnClickListener», как показано в следующем примере строки кода:

1
public class SpeakingAndroid extends Activity implements OnClickListener

Измените имя класса в соответствии с вашими данными приложения. Ваша IDE может отображать предупреждения, потому что ваш класс еще не реализовал «OnClickListener» правильно — просто проигнорируйте их сейчас. В методе «onCreate» добавьте следующий код:

1
2
Button speakButton = (Button)findViewById(R.id.speak);
speakButton.setOnClickListener(this);

Если вы не добавили кнопку, используя «речь» в качестве ее идентификатора в файле макета XML, измените этот код, чтобы он отображал правильное значение идентификатора. Это устанавливает ваш класс Activity для обработки нажатий пользовательских кнопок. Добавьте следующую схему метода в ваш класс:

1
2
3
public void onClick(View v) {
//handle user clicks here
}

Внутри этого метода вы начнете функциональность Text To Speech.


Когда пользователь нажимает кнопку, ваше приложение должно получить любой введенный текст, чтобы вы могли передать его методу TTS. Добавьте следующий оператор импорта вверху объявления класса, чтобы ваш код мог ссылаться на редактируемое текстовое поле:

1
import android.widget.EditText;

Внутри вашего метода onClick добавьте следующий код:

1
2
EditText enteredText = (EditText)findViewById(R.id.enter);
String words = enteredText.getText().toString();

Этот код сначала получает ссылку на текстовое поле, используя его значение идентификатора, поэтому измените его, если вы использовали другое значение в XML макета. Затем код получает текст из поля и сохраняет его как строковую переменную. Если пользователь не ввел текст, он будет пустым. В зависимости от логики в вашем приложении вы можете добавить условный тест, проверяющий, что строка не равна нулю или не равна нулю, но это обычно не требуется.

Ввод текста

Чтобы ваши классы Android были хорошо организованы, рекомендуется создавать специальные методы для процессов, которые вы можете использовать более одного раза. Добавьте следующую схему метода в свою активность:

1
2
3
private void speakWords(String speech) {
//implement TTS here
}

Это где ваша обработка TTS будет идти. Вернувшись в метод слушателя «onClick», вызовите этот новый метод, передав ему строковую переменную, скопированную вашим кодом из текстового поля:

1
speakWords(words);

Использование метода для процесса TTS означает, что ваш код может вызвать его в другом месте, если это необходимо.


Чтобы использовать средство TTS, вам нужно внести еще несколько изменений в объявление вашего класса. Добавьте следующие операторы импорта для классов TTS вверху файла:

1
2
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;

Вам также необходимо реализовать еще один интерфейс, поэтому измените схему объявления класса, добавив OnInitListener, как в следующем примере:

1
public class SpeakingAndroid extends Activity implements OnClickListener, OnInitListener

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


Ваше приложение должно проверить, что у пользователя есть данные, необходимые для функции TTS, прежде чем вызывать ее методы. Объявите и создайте экземпляр следующей переменной экземпляра в верхней части объявления класса Activity перед методом «onCreate»:

1
private int MY_DATA_CHECK_CODE = 0;

Добавьте следующий оператор импорта вверху класса:

1
import android.content.Intent;

В методе «onCreate» добавьте следующее:

1
2
3
Intent checkTTSIntent = new Intent();
checkTTSIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkTTSIntent, MY_DATA_CHECK_CODE);

Этот код создает новое намерение исключительно для проверки пользовательских данных. Когда процесс проверки завершится, код вызовет метод «onActivityResult».

Объявите переменную экземпляра для вашего объекта TTS в начале объявления класса, также перед методом «onCreate»:

1
private TextToSpeech myTTS;

Добавьте «onActivityResult» в ваш класс следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == MY_DATA_CHECK_CODE) {
        if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
            myTTS = new TextToSpeech(this, this);
        }
        else {
            Intent installTTSIntent = new Intent();
            installTTSIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
            startActivity(installTTSIntent);
        }
        }
}

Когда Intent проверки данных завершается, приложение вызывает этот метод, передавая ему переменную «MY_DATA_CHECK_CODE», указывающую, установлены ли у пользователя данные TTS. Если данные присутствуют, код продолжается и создает экземпляр класса TTS. Если данные отсутствуют, приложение предложит пользователю установить его.


Ваше объявление класса реализует OnInitListener, поэтому вы должны предоставить метод onInit. В этом методе вы можете выполнить любые необходимые проверки окончательной настройки, а также выбрать параметры для своего экземпляра TTS, такие как язык и параметры локали. Добавьте следующий оператор импорта в начало вашего класса:

1
import java.util.Locale;

Добавьте метод onInit к классу следующим образом:

1
2
3
4
5
public void onInit(int initStatus) {
    if (initStatus == TextToSpeech.SUCCESS) {
        myTTS.setLanguage(Locale.US);
    }
}

Этот код проверяет, успешно ли создан экземпляр ресурса TTS, а затем устанавливает языковой стандарт США для речи. Вы можете при желании вывести сообщение об ошибке для пользователей, если TTS не был успешно создан, добавив следующее после блока «if»:

1
2
3
else if (initStatus == TextToSpeech.ERROR) {
    Toast.makeText(this, «Sorry! Text To Speech failed…», Toast.LENGTH_LONG).show();
}

Если вы используете этот код, вам также нужно будет импортировать класс Toast, добавив следующий оператор в верхней части вашего файла:

1
import android.widget.Toast;

Ваше приложение может выполнять проверки на пользовательском устройстве, например на доступных языках, как в следующей расширенной версии оператора, создающего объект TTS внутри первого условного оператора:

1
if(myTTS.isLanguageAvailable(Locale.US)==TextToSpeech.LANG_AVAILABLE) myTTS.setLanguage(Locale.US);

Наконец, ваше приложение готово к работе. В методе «speakWords» добавьте следующий код:

1
myTTS.speak(speech, TextToSpeech.QUEUE_FLUSH, null);

Здесь много вариантов с точки зрения того, как ваше приложение обрабатывает речь. Этот код инструктирует приложение немедленно произносить текстовую строку. Если вы хотите добавить последовательные речевые операции, вы можете указать приложению дождаться завершения текущих речевых операций, добавив новый речевой элемент в очередь, следующим образом:

1
myTTS.speak(speech, TextToSpeech.QUEUE_ADD, null);
Говорящий текст пользователя

Как только ваш класс закончен с TTS, вы можете при желании закрыть его следующим образом:

1
myTTS.shutdown();

Не включайте эту строку, если вы хотите, чтобы пользователи могли заставить приложение говорить более одного раза.


Чтобы увидеть, как все эти элементы сочетаются друг с другом, вот полное объявление класса:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import android.app.Activity;
import android.os.Bundle;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.view.View;
import android.widget.EditText;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.content.Intent;
import java.util.Locale;
import android.widget.Toast;
 
public class SpeakingAndroid extends Activity implements OnClickListener, OnInitListener {
     
        //TTS object
    private TextToSpeech myTTS;
        //status check code
    private int MY_DATA_CHECK_CODE = 0;
     
        //create the Activity
    public void onCreate(Bundle savedInstanceState) {
     
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
             
                //get a reference to the button element listed in the XML layout
            Button speakButton = (Button)findViewById(R.id.speak);
                //listen for clicks
            speakButton.setOnClickListener(this);
 
            //check for TTS data
            Intent checkTTSIntent = new Intent();
            checkTTSIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
            startActivityForResult(checkTTSIntent, MY_DATA_CHECK_CODE);
    }
     
        //respond to button clicks
    public void onClick(View v) {
 
            //get the text entered
            EditText enteredText = (EditText)findViewById(R.id.enter);
            String words = enteredText.getText().toString();
            speakWords(words);
    }
     
        //speak the user text
    private void speakWords(String speech) {
 
            //speak straight away
            myTTS.speak(speech, TextToSpeech.QUEUE_FLUSH, null);
    }
     
        //act on result of TTS data check
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
     
        if (requestCode == MY_DATA_CHECK_CODE) {
            if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
                //the user has the necessary data — create the TTS
            myTTS = new TextToSpeech(this, this);
            }
            else {
                    //no data — install it now
                Intent installTTSIntent = new Intent();
                installTTSIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
                startActivity(installTTSIntent);
            }
        }
    }
 
        //setup TTS
    public void onInit(int initStatus) {
     
            //check for successful instantiation
        if (initStatus == TextToSpeech.SUCCESS) {
            if(myTTS.isLanguageAvailable(Locale.US)==TextToSpeech.LANG_AVAILABLE)
                myTTS.setLanguage(Locale.US);
        }
        else if (initStatus == TextToSpeech.ERROR) {
            Toast.makeText(this, «Sorry! Text To Speech failed…», Toast.LENGTH_LONG).show();
        }
    }
}

Не забудьте использовать собственное имя класса и указать свой пакет приложения в верхней части файла. Если вы используете Eclipse, вам не нужно добавлять все операторы импорта вручную, поскольку IDE вставит некоторые из них автоматически. Запустите свое приложение в эмуляторе Android и услышите его в действии.

Это базовый обзор реализации Text To Speech в ваших приложениях для Android. Ресурс TTS предоставляет широкий спектр дополнительных опций, которые вы, возможно, захотите изучить в зависимости от характера ваших приложений. Например, при вызове метода «говорить» объекта TextToSpeech вы можете передать объект HashMap, указывающий детали более сложных параметров воспроизведения.