Разработка приложений Android* с функциями распознавания речи

Станислав Павлов

Сама ОС Android не может распознавать речь, поэтому обычное устройство Android не в состоянии сделать это. Или все же есть способ?

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

Наше целевое устройство должно иметь, по крайней мере, одно приложение, которое может обработать намерение для распознавания речи, которое вызывается операцией RecognizerIntent.ACTION_RECOGNIZE_SPEECH.

Одним таким приложением является Google Voice Search. Это один из лучших сервисов распознавания речи для ОС Android, которое поддерживает множество языков. Для его работы требуется подключение к Интернету, так как процесс распознавания речи осуществляется на серверах Google. Данное приложение имеет очень простую операцию, которая информирует пользователей, когда они могут начать говорить. В тот момент, когда пользователь прекращает говорить, диалог закрывается, и наше приложение (вызвавшее намерение) принимает массив строк с обнаруженными элементами речи.

Пример распознавания речи

Давайте напишем небольшое приложение, демонстрирующее использование функций поиска речи в приложениях.

Нашему приложению необходимо сделать следующее:

  • Получить запрос для распознавания речи
  • Проверить доступность приложения для распознавания речи
  • Если приложение распознавания речи доступно, затем вызвать для него намерение и получить результаты
  • Если приложение распознавания речи недоступно, тогда нужно отобразить диалог для установки сервиса Google Voice Search и направления пользователя в магазин Play Google, если он решит выполнить установку

Во-первых, мы создадим класс, который реализует логику распознавания речи. Назовем этот класс SpeechRecognitionHelper, где мы объявим функцию run() (static, public), которая будет получать запрос на запуск распознавания:

/**
 * A helper class for speech recognition
 */
public class SpeechRecognitionHelper {

/**
     * Running the recognition process. Checks availability of recognition Activity,
     * If Activity is absent, send user to Google Play to install Google Voice Search.
    * If Activity is available, send Intent for running.
     *
     * @param callingActivity = Activity, that initializing recognition process
     */
    public static void run(Activity callingActivity) {
        // check if there is recognition Activity
        if (isSpeechRecognitionActivityPresented(callingActivity) == true) {
            // if yes – running recognition
            startRecognition(callingActivity);
        } else {
            // if no, then showing notification to install Voice Search
            Toast.makeText(callingActivity, "In order to activate speech recognition you must install "Google Voice Search"", Toast.LENGTH_LONG).show();
            // start installing process
            installGoogleVoiceSearch(callingActivity);
        }
    }
}

Как видите, кроме функции run() мы используем еще три функции:

  • isSpeechRecognitionActivityPresented – проверяет, если в системе приложение распознавания речи
  • installGoogleVoiceSearch – начинает процесс установки сервиса Google Voice Search
  • startRecognition – готовит соответствующее намерение и запускает процесс распознавания

Для проверки того, что на устройстве установлено приложение распознавания речи, мы можем использовать метод queryIntentActivities в классе PackageManager. Этот метод представляет список операций, которые могут обрабатывать указанное намерение. Чтобы получить экземпляр класса PackageManager, мы можем использовать getPackageManager.

Далее представлен наш код:

isSpeechRecognitionActivityPresented

/**
     * Checks availability of speech recognizing Activity
     *
     * @param callerActivity – Activity that called the checking
     * @return true – if Activity there available, false – if Activity is absent
     */
    private static boolean isSpeechRecognitionActivityPresented(Activity callerActivity) {
        try {
            // getting an instance of package manager
            PackageManager pm = callerActivity.getPackageManager();
            // a list of activities, which can process speech recognition Intent
            List activities = pm.queryIntentActivities(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);

            if (activities.size() != 0) {    // if list not empty
                return true;                // then we can recognize the speech
            }
        } catch (Exception e) {

        }

        return false; // we have no activities to recognize the speech
    }

Теперь реализуем функцию startRecognition. Эта функция сформирует соответствующее намерение для запуска операции распознавания речи. Вы можете найти подробную информацию о том, как это сделать на странице документации.

Исходный код:

   /**
     * Send an Intent with request on speech 
     * @param callerActivity  - Activity, that initiated a request
     */
    private static void startRecognitionActivity(Activity callerActivity) {

        // creating an Intent with “RecognizerIntent.ACTION_RECOGNIZE_SPEECH” action
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);

        // giving additional parameters:
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Select an application");    // user hint
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);    // setting recognition model, optimized for short phrases – search queries
        intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1);    // quantity of results we want to receive
//choosing only 1st -  the most relevant 

        // start Activity ant waiting the result
        ownerActivity.startActivityForResult(intent, SystemData.VOICE_RECOGNITION_REQUEST_CODE);
    }

И, наконец, мы используем функцию installGoogleVoiceSearch. Эта функция отобразит диалог с вопросом для пользователя, если он хочет установить сервис Google Voice Search, и направить его для этого в магазин Google Play.

/**
     * Asking the permission for installing Google Voice Search. 
     * If permission granted – sent user to Google Play
     * @param callerActivity – Activity, that initialized installing
     */
    private static void installGoogleVoiceSearch(final Activity ownerActivity) {

        // creating a dialog asking user if he want
        // to install the Voice Search
        Dialog dialog = new AlertDialog.Builder(ownerActivity)
            .setMessage("For recognition it’s necessary to install "Google Voice Search"")    // dialog message
            .setTitle("Install Voice Search from Google Play?")    // dialog header
            .setPositiveButton("Install", new DialogInterface.OnClickListener() {    // confirm button

                // Install Button click handler
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    try {
                        // creating an Intent for opening applications page in Google Play
                        // Voice Search package name: com.google.android.voicesearch
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.voicesearch"));
                        // setting flags to avoid going in application history (Activity call stack)
                        intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
                        // sending an Intent
                        ownerActivity.startActivity(intent);
                     } catch (Exception ex) {
                         // if something going wrong
                         // doing nothing
                     }
                }})

            .setNegativeButton("Cancel", null)    // cancel button
            .create();

        dialog.show();    // showing dialog
    }

Вот и все. Теперь мы запускаем операцию для распознавания речи. Затем запрашиваем разрешение пользователя для установки Voice Search и направляем его в магазин Google Play. Еще одно, что нужно сделать – это получить результаты процесса распознавания речи.

Мы отправляем запрос с помощью функции startActivityForResult для сбора результатов запущенной операции. Нам также необходимо повторно использовать метод OnActivityResult в нашей операции намерения. Это можно сделать следующим образом:

// Activity Results handler
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        // if it’s speech recognition results
        // and process finished ok
        if (requestCode == SystemData.VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) {

            // receiving a result in string array
            // there can be some strings because sometimes speech recognizing inaccurate
            // more relevant results in the beginning of the list
            ArrayList matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

            // in “matches” array we holding a results... let’s show the most relevant
            if (matches.size() > 0) Toast.makeText(this, matches.get(0), Toast.LENGTH_LONG).show();
        }

        super.onActivityResult(requestCode, resultCode, data);
    }

Теперь все готово

Созданный класс SpeechRecognitionHelper позволяет нам выполнять запрос распознавания речи посредством вызова только одной функции run().

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

Для получения дополнительной информации можно посетить веб-сайт для разработчиков Android. Здесь вы найдете прекрасные примеры использования функций распознавания речи и то, как получить список доступных языков. Этот список потребуется, если вам будет необходимо выполнить распознавание на языке, отличном от языка, выбранного пользователем по умолчанию.

Для быстрой интеграции функций голосового ввода в ваше приложение можно скачать и использовать этот код для класса SpeechRecognitionHelper.

Об авторах

Станислав работает в группе программ и услуг (Software & Service Group) корпорации Intel. Он имеет 10-летний опыт разработки программного обеспечения. Главным приоритетом в его работе является оптимизация производительности, энергопотребление и параллельное программирование. В настоящее время Станислав исполняет роль инженера по программным приложениям и оказывает техническую поддержку для устройств на базе платформ Intel, а также постоянно сотрудничает разработчиками ПО и архитекторами SoC, помогая им добиваться максимально возможной производительности платформ Intel. Станислав имеет степень магистра в области математической экономики национального исследовательского университета высшей школы экономики.

Михаил является соавтором этого блога и стажером факультета информатики Университета имени Лобачевского. Он любит занятия математикой и стремится овладевать навыками программирования в среде Android.

 

Intel и логотип Intel являются товарными знаками корпорации Intel в США и/или других странах.
© Корпорация Intel, 2013 г. Все права защищены.
*Другие наименования и товарные знаки являются собственностью своих законных владельцев.

Для получения подробной информации о возможностях оптимизации компилятора обратитесь к нашему Уведомлению об оптимизации.