語音輸入

語音輸入功能可讓你打造完全不必動手操作的介面。玻璃 提供三種語音輸入功能。

主要語音指令會從 Google Home 資訊卡啟動 Glassware,情境語音 指令可在活動內執行動作以及系統的語音 辨識活動可讓您接收使用者提供的任意形式語音輸入內容。

主要語音指令

這些語音指令可透過 Google Home 資訊卡 (時鐘卡) 啟動 Glassware。當您 宣告主要語音指令,Glass 會自動建立觸控選單項目 如果使用者決定輕觸 首頁資訊卡。

如何將語音指令新增至 ok Glass 語音主選單:

  1. 為語音指令建立 XML 資源: res/xml/<my_voice_trigger>.xml (使用現有的任一語音指令) VoiceTriggers.Command。 舉例來說,以下是使用「開始跑步」的方式。

    <?xml version="1.0" encoding="utf-8"?>
    <trigger command="START_A_RUN" />

    建立語音指令,提示使用者說出額外的語音 請在開始活動或服務前輸入 input 舉例來說,假設您有 點選「發布最新動態」連結

    <?xml version="1.0" encoding="utf-8"?>
    <trigger command="POST_AN_UPDATE">
       
    <input prompt="@string/glass_voice_prompt" />
    </trigger>
  2. 使用以下程式碼註冊意圖篩選器: com.google.android.glass.action.VOICE_TRIGGER在 Android 資訊清單。意圖篩選器會啟動您的活動或服務 偵測到使用者說出您的語音指令。

    <?xml version="1.0" encoding="utf-8"?>
    <application ...>
       
    <activity | service ...>
           
    <intent-filter>
               
    <action android:name=
                       
    "com.google.android.glass.action.VOICE_TRIGGER" />
           
    </intent-filter>
           
    <meta-data android:name="com.google.android.glass.VoiceTrigger"
               
    android:resource="@xml/my_voice_trigger" />
       
    </activity | service>
        // ...
    </application>
  3. 為活動或服務宣告 android:icon 屬性, 這樣 Glass 就會在 ok, Glass 觸控選單。

    <activity |service
       
    android:icon="@drawable/my_icon" ...>
      ...
    </activity | service>
  4. 如果語音指令會使用語音提示並開始活動,請取得 帶有下列程式碼的轉錄文字 (例如 onResume()):

    ArrayList<String> voiceResults = getIntent().getExtras()
           
    .getStringArrayList(RecognizerIntent.EXTRA_RESULTS);

    如果語音指令啟動服務,意圖額外項目會列在 onStartCommand() 回呼:

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
       
    ArrayList<String> voiceResults = intent.getExtras()
               
    .getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
       
    // ...
    }

設定限制條件

如果您需要以下一或多項功能來啟動 Glassware, 請在 res/xml/<my_voice_trigger>.xml 資源中指定。 如果螢幕無法使用這些功能,Glass 會停用語音指令:

  • camera
  • network
  • microphone

    <trigger command="POST_AN_UPDATE">
       
    <constraints
           
    camera="true"
           
    network="true" />
    </trigger>

情境語音指令

情境式語音指令可讓使用者透過活動執行動作。 您可以使用標準 Android 選單 API 建構情境語音指令 使用者可以利用語音指令叫用選單項目,不需透過觸控操作。

如何針對特定活動啟用情境語音指令:

  1. 撥打 getWindow().requestFeature(WindowUtils.FEATURE_VOICE_COMMANDS) 以及啟用情境語音指令透過這項功能 啟用後,「ok Glass」選單就會出現在畫面頁尾 每當此活動獲得焦點時。

  2. 覆寫 onCreatePanelMenu() 並處理 WindowUtils.FEATURE_VOICE_COMMANDS 如果啟用這項功能,你可以在這裡設定一次性選單,例如加載 選單資源或呼叫 Menu.add() 方法建立語音選單系統。

  3. 覆寫 onMenuItemSelected() 在使用者說話時處理語音指令。使用者完成工作時 選取選單項目後,系統會自動說出 "ok, Glass" 語音指令 再次出現在螢幕頁尾部分,準備接受新語音 指令。

    以下程式碼可啟用情境語音指令,加載選單資源 並視情況處理語音指令:

    public class ContextualMenuActivity extends Activity {

       
    @Override
       
    protected void onCreate(Bundle bundle) {
           
    super.onCreate(bundle);

           
    // Requests a voice menu on this activity. As for any other
           
    // window feature, be sure to request this before
           
    // setContentView() is called
            getWindow
    ().requestFeature(WindowUtils.FEATURE_VOICE_COMMANDS);
            setContentView
    (R.layout.activity_main);
       
    }

       
    @Override
       
    public boolean onCreatePanelMenu(int featureId, Menu menu) {
           
    if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS) {
                getMenuInflater
    ().inflate(R.menu.main, menu);
               
    return true;
           
    }
           
    // Pass through to super to setup touch menu.
           
    return super.onCreatePanelMenu(featureId, menu);
       
    }

       
    @Override
       
    public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater
    ().inflate(R.menu.main, menu);
           
    return true;
       
    }

       
    @Override
       
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
           
    if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS) {
               
    switch (item.getItemId()) {
                   
    case R.id.dogs_menu_item:
                       
    // handle top-level dogs menu item
                       
    break;
                   
    case R.id.cats_menu_item:
                       
    // handle top-level cats menu item
                       
    break;
                   
    case R.id.lab_menu_item:
                       
    // handle second-level labrador menu item
                       
    break;
                   
    case R.id.golden_menu_item:
                       
    // handle second-level golden menu item
                       
    break;
                   
    case R.id.calico_menu_item:
                       
    // handle second-level calico menu item
                       
    break;
                   
    case R.id.cheshire_menu_item:
                       
    // handle second-level cheshire menu item
                       
    break;
                   
    default:
                       
    return true;
               
    }
               
    return true;
           
    }
           
    // Good practice to pass through to super if not handled
           
    return super.onMenuItemSelected(featureId, item);
       
    }
    }

    以下是先前活動使用的選單資源範例。 留意如何為階層語音建立巢狀選單項目 應用程式選單系統在以下範例中,第一個選單項目 範例:ok Glass、Show me dogs, Labrador

    <menu xmlns:android="http://schemas.android.com/apk/res/android">
       
    <!-- Use the constants defined in the ContextualMenus.Command enum-->
       
    <item
           
    android:id="@+id/dogs_menu_item"
           
    android:title="@string/show_me_dogs">
           
    <menu>
               
    <item
                   
    android:id="@+id/lab_menu_item"
                   
    android:title="@string/labrador" />
               
    <item
                   
    android:id="@+id/golden_menu_item"
                   
    android:title="@string/golden" />
           
    </menu>
       
    </item>
       
    <item
           
    android:id="@+id/cats_menu_item"
           
    android:title="@string/show_me_cats">
           
    <menu>
               
    <item
                   
    android:id="@+id/cheshire_menu_item"
                   
    android:title="@string/cheshire" />
               
    <item
                   
    android:id="@+id/calico_menu_item"
                   
    android:title="@string/calico" />
           
    </menu>
       
    </item>
    </menu>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
       
    <!-- Use the constants defined in the ContextualMenus.Command enum-->
       
    <item
           
    android:id="@+id/play_menu_item"
           
    android:title="PLAY_MUSIC" />
       
    <item
           
    android:id="@+id/pause_menu_item"
           
    android:title="PAUSE_MUSIC" />
    </menu>
  4. (選用) 覆寫 onPreparePanel()、 正在檢查 WindowUtils.FEATURE_VOICE_COMMANDS 已啟用。 啟用後,就能在這裡執行其他設定選單系統的邏輯。 例如根據某些條件新增或移除特定選單項目你可以 同時將內容語音選單切換為開啟 (返回 true) 和關閉 (傳回 false)。例如:

        private boolean mVoiceMenuEnabled;
       
    ...
       
    @Override
       
    public boolean onPreparePanel(int featureId, View view, Menu menu) {
           
    if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS) {
           
    // toggle this boolean on and off based on some criteria
               
    return mVoiceMenuEnabled;
           
    }
           
    // Good practice to call through to super for other cases
           
    return super.onPreparePanel(featureId, view, menu);
       
    }

同時支援語音和觸控選單

內容語音指令會使用現有的 Android 選單 API 您可以重複使用許多現有的程式碼和資源 並同時支援這兩種選單

你只需檢查 Window.FEATURE_OPTIONS_PANEL 功能即可 除了您已提供的 WindowUtils.FEATURE_VOICE_COMMANDS 功能 檢查幾種方法,然後加入邏輯來開啟 有些使用者動作 (例如輕觸) 上的選單

舉例來說,您可以變更先前的活動 範例:新增這類觸控選單 (變更內容會留下評論):

// 1. Check for Window.FEATURE_OPTIONS_PANEL
// to inflate the same menu resource for touch menus.
@Override
public boolean onCreatePanelMenu(int featureId, Menu menu) {
   
if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS ||
            featureId
== Window.FEATURE_OPTIONS_PANEL) {
   
...
}

// 2. Check for Window.FEATURE_OPTIONS_PANEL
// to handle touch menu item selections.
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
   
if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS ||
            featureId
== Window.FEATURE_OPTIONS_PANEL) {
   
...
}

完成這些變更後,你可以輕觸或說出「Ok Glass」以顯示螢幕 您的選單。

使用不公開的語音指令進行開發

當您想要分發 Glassware 時,必須使用經核准的主應用程式 使用語音指令 VoiceTriggers.Command敬上 和經過核准的語境語音指令 ContextualMenus.Command

如果您想使用 GDK 中沒有的語音指令, 您可以在 AndroidManifest.xml 檔案中要求 Android 權限:

<uses-permission
     
android:name="com.google.android.glass.permission.DEVELOPMENT" />

使用未列出的主要語音指令

  1. res/values/strings.xml 中宣告定義的字串值 語音觸發條件的名稱可選擇宣告語音提示 ,在啟動 Glassware 前顯示語音辨識 Glassware。

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
       
    <string name="glass_voice_trigger">read me a story</string>
       
    <string name="glass_voice_prompt">what story?</string>
    </resources>
  2. 為語音觸發條件建立 XML 資源: res/xml/<my_voice_trigger>.xml。如果不是不公開的語音指令,則應使用 keyword 屬性,而不是用於核准的 command 屬性 語音指令。keyword 屬性應為對字串的參照 定義語音指令的資源語音觸發的簡易語音觸發程序 請直接指定 trigger 元素:

    <?xml version="1.0" encoding="utf-8"?>
    <trigger keyword="@string/glass_voice_trigger" />

    建立語音觸發條件,提示使用者說出其他語音 詞組,再開始活動或服務,請加入輸入元素 其他情況:

    <?xml version="1.0" encoding="utf-8"?>
    <trigger keyword="@string/glass_voice_trigger">
       
    <input prompt="@string/glass_voice_prompt" />
    </trigger>

使用在不公開的情境下語音指令

建立選單項目時,請使用任何文字做為選單項目的標題。 例如:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
   
<!-- Use the constants defined in the ContextualMenus.Command enum-->
   
<item
       
android:id="@+id/pizza_menu_item"
       
android:title="@string/find_pizza" />
</menu>

啟動語音辨識


語音辨識 Glassware 會等待使用者說話,然後傳回 並在完成後轉錄的文字如何開始活動:

  1. 呼叫 startActivityForResult() ACTION_RECOGNIZE_SPEECH 意圖。 啟動活動時,系統支援下列意圖額外項目:
  2. 覆寫 onActivityResult()敬上 回呼,以便接收來自 EXTRA_RESULTS 意圖額外項目使用者說完後,系統就會呼叫此回呼。

    private static final int SPEECH_REQUEST = 0;

    private void displaySpeechRecognizer() {
       
    Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        startActivityForResult
    (intent, SPEECH_REQUEST);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode,
           
    Intent data) {
       
    if (requestCode == SPEECH_REQUEST && resultCode == RESULT_OK) {
           
    List<String> results = data.getStringArrayListExtra(
                   
    RecognizerIntent.EXTRA_RESULTS);
           
    String spokenText = results.get(0);
           
    // Do something with spokenText.
       
    }
       
    super.onActivityResult(requestCode, resultCode, data);
    }