Android:使用Speech To Text API進行語音到文字轉換

類別: IT
標籤: android
Android有一個非常酷的特性很多開發者都還不知道。Any.DO之類應用的語音到文字轉換功能很有創意。在現在Siri的世界裡,語音指令是極其重要的。Android原生提供Speech To Text功能,為什麼不把它用在我們的程式中!

我將會展示如何在程式中使用Android的Speech To Text API,現在開始寫我們的demo程式。

Demo程式
這個程式很簡單。他有一個Mic符號按鈕。點選之後我們觸發Android的Speech To Text意圖(Intent)顯示一個對話方塊來接收語音輸入。輸入的語音然後會被轉換成文字並顯示到一個text view中。
第一步:在Eclipse中建立基本的Android專案
在Eclipse中建立一個Hello World Android專案。開啟  New > Project > Android Project,專案名填  SpeechToTextDemo,選擇Android執行時2.1或sdk7。我給定了包名: net.viralpatel.android.speechtotextdemo

做完上面的步驟,你就有了一個基本的Android Hello World程式

第二步:更改佈局
在我們的demo中佈局很簡單。只有一個影象按鈕來觸發Speech to Text API和一個TextView來顯示從語音轉換過來的文字。

開啟layout/main.xml並替換為下面的內容:

File: res/layout/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="<a href="http://my.oschina.net/asia" class="referer" target="_blank">@android</a> :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>
第三步:觸發Speech to Text API的Android Java程式碼
開啟SpeechToTextDemoActivity 類並替換為下面的程式碼:

File: SpeechToTextDemoActivity.java

package net.viralpatel.android.speechtotextdemo;
 
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");
 
                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) {
 
                ArrayListtext = data
                        .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
 
                txtText.setText(text.get(0));
            }
            break;
        }
 
        }
    }
}


Android Speech to text Android API的核心是包  android.speech和類 android.speech.RecognizerIntent。我們觸發一個意圖(android.speech.RecognizerIntent)顯示對話方塊來識別語音輸入,這個Activity轉換語音為文字並把結果傳回我們正在呼叫的Activity。當我們呼叫android.speech.RecognizerIntent意圖時,必須使用  startActivityForResult()來接聽文字結果。

注意在上面的程式碼中我們是怎樣建立並觸發意圖intent android.speech.RecognizerIntent的,同時使用.putExtra()方法新增了一個引數。呼叫RecognizerIntent時,必須提供 RecognizerIntent.EXTRA_LANGUAGE_MODE,在這裡我們設定為  en-US

由於我們的RecognizerIntent通過startActivityForResult()觸發,我們重寫了  onActivityResult(int requestCode, int resultCode, Intent data)方法來處理結果資料。RecognizerIntent會把語音轉換為文字並把結果通過鍵RecognizerIntent.EXTRA_RESULTS作為ArrayList傳回來。只有RESULT_OK返回時才會出現。我們只需要使用  txtText.setText()把從結果中拿到的文字設定到text view  texText中。

在這裡值得注意的一件事是在不支援speech to text API的裝置/Android版本中應該怎樣處理。在這種情況下,當我們檢視啟動Activity時ActivityNotFoundException異常會被丟擲。在上面的例子中,我們捕獲了這個異常並使用Toast顯示了一個提示資訊“Opps! Your device doesn’t support Speech to Text”。

Android應用程式的螢幕截圖
到這裡就結束了! 在Android模擬器或真實裝置上執行應用程式,將會看到下面的輸出。



下載原始碼

Android_SpeechToTextDemo.zip (350 KB)

Android:使用Speech To Text API進行語音到文字轉換原文請看這裡

推薦文章