Статьи

Android-приложение для распознавания голоса

Возможно, вы слышали о « проекте Google Now», в котором вы предоставляете голосовую команду и результаты поиска Android для вас. Он распознает ваш голос и преобразует его в текст или выполняет соответствующие действия. Вы когда-нибудь думали, как это делается? Если ваш ответ API распознавания голоса, то вы абсолютно правы. Недавно, играя с API распознавания голоса Android, я нашел несколько интересных вещей. API действительно просты в использовании с приложением. Ниже приведен небольшой учебник по API распознавания голоса / речи. Окончательная заявка будет выглядеть аналогично заявке ниже. Приложение может не работать на эмуляторе Android, поскольку оно не поддерживает распознавание голоса. Но то же самое может работать на телефоне.

Информация о проекте: метаданные о проекте.

Версия платформы: Android API Level 15.
IDE: Eclipse Helios Service Release 2
Эмулятор: Android 4.1 (API 16)

Предварительное условие: предварительное знание инфраструктуры приложений Android и Intent.

Функция распознавания голоса может быть достигнута RecognizerIntent. Создайте Intent типа RecognizerIntent, передайте дополнительные параметры и запустите действие для результата. Он в основном запускает запрос распознавателя, настроенный вашими дополнительными параметрами Внутреннее распознавание голоса связывается с сервером и получает результаты. Таким образом, вы должны предоставить разрешение на доступ в Интернет для приложения. Android Jelly Bean (уровень API 16) не требует подключения к Интернету для распознавания голоса. Как только распознавание голоса выполнено, распознаватель возвращает значение в параметрах метода onActivityResult ().

Сначала создайте проект с помощью Eclipse> Файл> Новый проект> Проект приложения Android . Появится следующее диалоговое окно. Заполните обязательные поля, т.е. Имя приложения, Имя проекта и Пакет. Теперь нажмите следующую кнопку.

Когда появится диалоговое окно, выберите BlankActivity и нажмите кнопку « Далее» .

Заполните Имя файла деятельности и Имя файла макета в диалоговое окно, показанное ниже, и нажмите кнопку Готово.

Этот процесс настроит основные файлы проекта. Теперь мы собираемся добавить четыре кнопки в файле activity_voice_recognition.xml . Вы можете изменить файл макета, используя графический редактор макетов или XML-редактор. Содержание файла показано ниже. Как вы можете заметить, мы добавили метод speak () с кнопкой в ​​теге onClick . При нажатии кнопки будет запущен метод speak (). Определим выступление () в основной деятельности.

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
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
 
    <EditText
        android:id="@+id/etTextHint"
        android:gravity="top"
        android:inputType="textMultiLine"
        android:lines="1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/etSearchHint"/>
 
    <Button
        android:id="@+id/btSpeak"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="speak"
        android:padding="@dimen/padding_medium"
        android:text="@string/btSpeak"
        tools:context=".VoiceRecognitionActivity" />
 
    <Spinner
        android:id="@+id/sNoOfMatches"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:entries="@array/saNoOfMatches"
        android:prompt="@string/sNoOfMatches"/>
 
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/tvTextMatches"
        android:textStyle="bold" />
 
    <ListView
        android:id="@+id/lvTextMatches"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
 
</LinearLayout>

Возможно, вы заметили, что строковые константы доступны из ресурса. Теперь добавьте строковые константы в string.xml . Этот файл должен выглядеть аналогично показанному ниже.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<resources>
    <string name="app_name">VoiceRecognitionExample</string>
    <string name="btSpeak">Speak</string>
    <string name="menu_settings">Settings</string>
    <string name="title_activity_voice_recognition">Voice Recognition</string>
    <string name="tvTextMatches">Text Matches</string>
    <string name="sNoOfMatches">No of Matches</string>
    <string name="etSearchHint">Speech hint here</string>
    <string-array name="saNoOfMatches">
        <item>1</item>
        <item>2</item>
        <item>3</item>
        <item>4</item>
        <item>5</item>
        <item>6</item>
        <item>7</item>
        <item>8</item>
        <item>9</item>
        <item>10</item>
    </string-array>
</resources>

Теперь давайте определим класс Activity. Этот класс активности с помощью метода checkVoiceRecognition () сначала проверяет, доступно ли распознавание голоса. Если функция распознавания голоса недоступна, добавьте сообщение и отключите кнопку. Здесь определен метод Speak (), который вызывается после нажатия кнопки разговора. В этом методе мы создаем RecognizerIntent и передаем дополнительные параметры. Код ниже имеет встроенные комментарии, которые облегчают понимание.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package com.rakesh.voicerecognitionexample;
 
import java.util.ArrayList;
import java.util.List;
 
import android.app.Activity;
import android.app.SearchManager;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.Toast;
 
public class VoiceRecognitionActivity extends Activity {
 private static final int VOICE_RECOGNITION_REQUEST_CODE = 1001;
 
 private EditText metTextHint;
 private ListView mlvTextMatches;
 private Spinner msTextMatches;
 private Button mbtSpeak;
 
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_voice_recognition);
  metTextHint = (EditText) findViewById(R.id.etTextHint);
  mlvTextMatches = (ListView) findViewById(R.id.lvTextMatches);
  msTextMatches = (Spinner) findViewById(R.id.sNoOfMatches);
  mbtSpeak = (Button) findViewById(R.id.btSpeak);
  checkVoiceRecognition()
 }
 
 public void checkVoiceRecognition() {
  // Check if voice recognition is present
  PackageManager pm = getPackageManager();
  List<resolveinfo> activities = pm.queryIntentActivities(new Intent(
    RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
  if (activities.size() == 0) {
   mbtSpeak.setEnabled(false);
   mbtSpeak.setText("Voice recognizer not present")
   Toast.makeText(this, "Voice recognizer not present",
     Toast.LENGTH_SHORT).show();
  }
 }
 
 public void speak(View view) {
  Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
 
  // Specify the calling package to identify your application
  intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getClass()
    .getPackage().getName());
 
  // Display an hint to the user about what he should say.
  intent.putExtra(RecognizerIntent.EXTRA_PROMPT, metTextHint.getText()
    .toString());
 
  // Given an hint to the recognizer about what the user is going to say
  //There are two form of language model available
  //1.LANGUAGE_MODEL_WEB_SEARCH : For short phrases
  //2.LANGUAGE_MODEL_FREE_FORM  : If not sure about the words or phrases and its domain.
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
    RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
 
  // If number of Matches is not selected then return show toast message
  if (msTextMatches.getSelectedItemPosition() == AdapterView.INVALID_POSITION) {
   Toast.makeText(this, "Please select No. of Matches from spinner",
     Toast.LENGTH_SHORT).show();
   return;
  }
 
  int noOfMatches = Integer.parseInt(msTextMatches.getSelectedItem()
    .toString());
  // Specify how many results you want to receive. The results will be
  // sorted where the first result is the one with higher confidence.
  intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, noOfMatches);
  //Start the Voice recognizer activity for the result.
  startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);
 }
 
 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (requestCode == VOICE_RECOGNITION_REQUEST_CODE)
 
   //If Voice recognition is successful then it returns RESULT_OK
   if(resultCode == RESULT_OK) {
 
    ArrayList<string> textMatchList = data
    .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
 
    if (!textMatchList.isEmpty()) {
     // If first Match contains the 'search' word
     // Then start web search.
     if (textMatchList.get(0).contains("search")) {
 
        String searchQuery = textMatchList.get(0);
                                           searchQuery = searchQuery.replace("search","");
        Intent search = new Intent(Intent.ACTION_WEB_SEARCH);
        search.putExtra(SearchManager.QUERY, searchQuery);
        startActivity(search);
     } else {
         // populate the Matches
         mlvTextMatches
      .setAdapter(new ArrayAdapter<string>(this,
        android.R.layout.simple_list_item_1,
        textMatchList));
     }
 
    }
   //Result code for various error.
   }else if(resultCode == RecognizerIntent.RESULT_AUDIO_ERROR){
    showToastMessage("Audio Error");
   }else if(resultCode == RecognizerIntent.RESULT_CLIENT_ERROR){
    showToastMessage("Client Error");
   }else if(resultCode == RecognizerIntent.RESULT_NETWORK_ERROR){
    showToastMessage("Network Error");
   }else if(resultCode == RecognizerIntent.RESULT_NO_MATCH){
    showToastMessage("No Match");
   }else if(resultCode == RecognizerIntent.RESULT_SERVER_ERROR){
    showToastMessage("Server Error");
   }
  super.onActivityResult(requestCode, resultCode, data);
 }
 /**
 * Helper method to show the toast message
 **/
 void showToastMessage(String message){
  Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
 }
}

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

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
    package="com.rakesh.voicerecognitionexample"
    android:versionCode="1"
    android:versionName="1.0" >
 
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />
    <!-- Permissions -->
 <uses-permission android:name="android.permission.INTERNET" />
 
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
 
        <activity
            android:name=".VoiceRecognitionActivity"
            android:label="@string/title_activity_voice_recognition" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Как только вы закончите с кодированием, подключите телефон к вашей системе и нажмите кнопку запуска в Eclipse IDE. Eclipse установит и запустит приложение. Вы увидите следующие действия на экране вашего устройства.

В следующем уроке мы узнаем, как использовать новый API распознавания голоса, представленный в Android Jelly Bean (уровень API 16), вместе с примерами.

Если вас интересует исходный код, вы можете получить его с github .

Ссылка: учебник по распознаванию голоса Android от нашего партнера по JCG Ракеша Кусата в блоге Code4Reference .