Поиск по этому блогу

пятница, 30 ноября 2012 г.

Speech to Text в Android

Android очень крутая штука в плане API, некоторые разработчики не знают что в нем есть такая функция как «речь в текст», это когда вы говорите в микрофон на телефоне, а он после окончания вашей речи переводит весь сказанный вами диалог в текст. Собственно реализация не сильно сложная, все что вам нужно это создать Intent который будет передавать сказанный вами текст телефону, а он соответственно будет переводить его в текст на экране. Для того что бы вы не искали в интернете и не мучились, я создам вам как бы маленькую шпаргалку для того что бы когда вам нужно было создать приложение с таким функционалом, вы могли открыть страницу в моем блоге и посмотреть как такое реализовывается.

Для начала вам нужно открыть main.xml в котором нужно будет добавить кнопку на которую будем жмакать для записи разговора и текствью в который будем выводить текст. И так создаем:

main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_above="@+id/textView1"
    android:layout_toLeftOf="@+id/textView1"
    android:gravity="center"
    android:orientation="vertical" >
 
    <ImageButton
        android:id="@+id/btnSpeak"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="10dp"
        android:contentDescription="@string/speak"
        android:src="@android:drawable/ic_btn_speak_now" />
 
    <TextView
        android:id="@+id/txtText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="10dp"
        android:textAppearance="?android:attr/textAppearanceLarge" />
 </LinearLayout>


Как видно из листинга тут все придельно просто, есть одна кнопка и есть один текствью, думаю дальше пояснять не нужно, если что-то не понятно то спрашивайте в комментариях ну или пишите мне в скайп.

Далее нам нужно создать активность которая будет обрабатывать наше нажатие на кнопку, нашу обработку сказанного нами же, и отправку полученного текста в текствью. Для этого открываем наш MainActivity.java и пишем вот такое вот:

MainActivity.java
import java.util.ArrayList;
 import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.view.Menu;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
 public class MainActivity extends Activity {
 
    protected static final int RESULT_SPEECH = 1;
 
    private ImageButton btnSpeak; //создаем объект кнопки
    private TextView txtText; //создаем объект нашего текствью
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        txtText = (TextView) findViewById(R.id.txtText); //определяем их
 
        btnSpeak = (ImageButton) findViewById(R.id.btnSpeak); // -//-
 
        btnSpeak.setOnClickListener(new View.OnClickListener() { //создаем листенера для определения  
                                                                 //нажатия кнопки
 
            @Override
            public void onClick(View v) {
 
                Intent intent = new Intent(
                        RecognizerIntent.ACTION_RECOGNIZE_SPEECH);    //и вот тут собственно запускаем наш 
                                                                      //интент с параметрами "голос в текст"
 
                intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, "en-US");   //задаем язык, если  
                                                                                   //русский значит ru-RU
 
                try {
                    startActivityForResult(intent, RESULT_SPEECH); //запускаем наш интент
                    txtText.setText(""); //обнуляем то что находится в текствью.
                } catch (ActivityNotFoundException a) {
                    Toast t = Toast.makeText(getApplicationContext(),
                            "Opps! Your device doesn't support Speech to Text",
                            Toast.LENGTH_SHORT);
                    t.show();
                }
            }
        });
 
    }
 
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
 
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
 
        switch (requestCode) {
        case RESULT_SPEECH: {
            if (resultCode == RESULT_OK && null != data) {
 
                ArrayList<String> text = data
                        .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); //получаем что нам вернул интент
 
                txtText.setText(text.get(0)); и записываем в текствью
            }
            break;
        }
 
        }
    }
}


Я надеюсь из комментарием все стало понятно, если не понятно то давайте я еще раз расскажу что происходит в этом коде.

Для начала мы переопределяем все наши переменные, задаем им настройки, далее определяем нашу кнопку для нажатий и в ней запускаем интент который запускает голос в текст и передает наши данные в массив из которого мы дальше считываем наши данные и передаем в текствью. Вот так вот все просто, а может и сложно. В конце пути у нас получится вот такое вот окошко с одной кнопкой