應用程式開發

如要實作語音互動應用程式 (VIA),請完成下列步驟:

  1. 建立 VIA 骨架。
  2. (選用) 實作設定/登入流程。
  3. (選用) 實作設定畫面。
  4. 在資訊清單檔案中宣告必要權限。
  5. 實作語音板 UI。
  6. 實作語音辨識功能 (必須包含 RecognitionService API 實作)。
  7. 實作語音內容 (您也可以實作 TextToSpeech API)。
  8. 實作指令執行要求。以下列語言觀看這項內容 執行指令

以下各節說明如何完成上述各個步驟。

建立 VIA 骨架

資訊清單

在下列情況中,Google 會偵測到應用程式具有語音互動功能 資訊清單:

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myvoicecontrol">
    ...

  <application ... >
    <service android:name=".MyInteractionService"
        android:label="@string/app_name"
        android:permission="android.permission.BIND_VOICE_INTERACTION"
        android:process=":interactor">
      <meta-data
          android:name="android.voice_interaction"
          android:resource="@xml/interaction_service" />
      <intent-filter>
        <action android:name=
          "android.service.voice.VoiceInteractionService" />
      </intent-filter>
    </service>
  </application>
</manifest>

在這個例子中:

  • VIA 必須公開擴充 VoiceInteractionService 的服務,包括 動作 VoiceInteractionService.SERVICE_INTERFACE ("android.service.voice.VoiceInteractionService") 的意圖篩選器。
  • 這項服務必須具備 BIND_VOICE_INTERACTION 系統簽署權限。
  • 這項服務應包含 android.voice_interaction 中繼資料檔案 包含下列項目:

    res/xml/interaction_service.xml

    <voice-interaction-service
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:sessionService=
          "com.example.MyInteractionSessionService"
        android:recognitionService=
          "com.example.MyRecognitionService"
        android:settingsActivity=
          "com.example.MySettingsActivity"
        android:supportsAssist="true"
        android:supportsLaunchVoiceAssistFromKeyguard="true"
        android:supportsLocalInteraction="true" />
    

如要進一步瞭解每個欄位,請參閱 R.styleable#VoiceInteractionService。 由於所有 VIA 也都是語音辨識器服務,因此您還必須 請在資訊清單中加入以下內容:

AndroidManifest.xml

<manifest ...>
  <uses-permission android:name="android.permission.RECORD_AUDIO"/>
  <application ...>
    ...
    <service android:name=".RecognitionService" ...>
      <intent-filter>
        <action android:name="android.speech.RecognitionService" />
        <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
      <meta-data
        android:name="android.speech"
        android:resource="@xml/recognition_service" />
    </service>
  </application>
</manifest>

語音辨識服務也需要下列中繼資料:

res/xml/recognition_service.xml

<recognition-service
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:settingsActivity="com.example.MyRecognizerSettingsActivity" />

VoiceInteractionService、VoiceInteractionSessionService 和 VoiceInteractionSession

下圖說明每個實體的生命週期:

Lifecycles

圖 1. Lifecycles

如前所述,VoiceInteractionService 是進入點 還有一個 VIA這項服務的主要責任包括:

  • 初始化任何應持續執行的程序 這部 VIA 是有效的組合。例如啟動字詞偵測。
  • 回報支援的語音指令 (請參閱 Voice 助理的輕觸朗讀功能)。
  • 從螢幕鎖定畫面 (鍵盤鎖) 啟動語音互動工作階段。

最簡單的 VoiceInteractionService 實作方式 輸入:

public class MyVoiceInteractionService extends VoiceInteractionService {
    private static final List<String> SUPPORTED_VOICE_ACTIONS =
        Arrays.asList(
            CarVoiceInteractionSession.VOICE_ACTION_READ_NOTIFICATION,
            CarVoiceInteractionSession.VOICE_ACTION_REPLY_NOTIFICATION,
            CarVoiceInteractionSession.VOICE_ACTION_HANDLE_EXCEPTION
    );

    @Override
    public void onReady() {
        super.onReady();
        // TODO: Setup hotword detector
    }

    @NonNull
    @Override
    public Set<String> onGetSupportedVoiceActions(
            @NonNull Set<String> voiceActions) {
        Set<String> result = new HashSet<>(voiceActions);
        result.retainAll(SUPPORTED_VOICE_ACTIONS);
        return result;
    }
    ...
}

VoiceInteractionService#onGetSupportedVoiceActions() 的實作方式為 才能處理 語音助理的輕觸朗讀功能。 系統會運用 VoiceInteractionSessionService 建立和 與 VoiceInteractionSession 互動。只有一個責任 按要求啟動新的工作階段。

public class MyVoiceInteractionSessionService extends VoiceInteractionSessionService {
    @Override
    public VoiceInteractionSession onNewSession(Bundle args) {
        return new MyVoiceInteractionSession(this);
    }
}

最後,VoiceInteractionSession 主要用於處理作業 關鍵在於單一工作階段例項可重複使用,以完成多個 使用者互動狀況AAOS 中已經有 CarVoiceInteractionSession 輔助程式, 協助導入部分汽車特有功能

public class MyVoiceInteractionSession extends CarVoiceInteractionSession {

    public InteractionSession(Context context) {
        super(context);
    }

    @Override
    protected void onShow(String action, Bundle args, int showFlags) {
        closeSystemDialogs();
        // TODO: Unhide UI and update UI state
        // TODO: Start processing audio input
    }
    ...
}

VoiceInteractionSession 的回呼方法不多, 。請參閱 VoiceInteractionSession 的說明文件

實作設定/登入流程

可能發生設定和登入事件:

  • 裝置新手上路期間 (設定精靈)。
  • 在語音互動服務替換期間 (「設定」)。
  • 於使用者選取應用程式時初次啟動。

如要進一步瞭解建議的使用者體驗和圖像指引,請參閱 預先載入的 Google 助理:使用者體驗指南

在語音服務替換期間設定

使用者可以自行選取未正確使用的 VIA 專案。可能原因如下:

  • 使用者完全略過設定精靈或使用者略過語音提示 互動設定步驟
  • 使用者選取的 VIA 與裝置期間所設定的設定不同 新手上路

在任何情況下,VoiceInteractionService 都可透過多種方式鼓勵使用者 以完成設定:

  • 通知提醒。
  • 在使用者嘗試使用自動語音回覆時。

注意:強烈建議不要提供 VIA 設定流程 未明確取得使用者明確要求這表示 VIA 應避免 裝置啟動時,或因使用者切換或執行其他動作而於 HU 顯示內容 解除鎖定。

通知提醒

通知提醒是一種不會造成乾擾的方式 表明需要設定 並提供預設用途,讓使用者能自行選擇是否使用 Google 助理 流程

通知提醒

圖 2. 通知提醒

以下是此流程的運作方式:

通知提醒流程

圖 3. 通知提醒流程

語音回覆

這是最簡單的實作流程, VoiceInteractionSession#onShow() 回呼,向使用者說明 ,然後詢問對方 (如果將使用者體驗限制狀態設為允許) 用於啟動設定流程如果無法進行設定,請說明 情況也隨之增加

首次使用時設定

使用者隨時可以觸發未正確執行的 VIA 專案。在這種情況下:

  1. 針對這種情況多口頭告知使用者 (例如:「為了妥善運作, 我需要你完成幾個步驟... 」)。
  2. 如果使用者體驗限制引擎允許 (請參閱 UX_RESTRICTIONS_NO_SETUP),請詢問使用者是否要啟動 設定程序,然後開啟 VIA 的設定畫面。
  3. 否則 (例如使用者正在開車),請留下通知讓使用者前往 只要在安全的情況下點選該選項即可

建構語音互動設定畫面

設定和登入畫面應做為一般活動開發。詳情請參閱 針對使用者介面開發作業實施的使用者體驗和視覺指南 預先載入的 Google 助理:使用者體驗指南

一般指南:

  • VIA 應讓使用者隨時中斷設定並繼續設定。
  • 如果 UX_RESTRICTIONS_NO_SETUP 限制生效,就無法設定。詳情請參閱 駕駛人分心等級規範
  • 設定畫面應符合每輛車的設計系統。一般畫面 版面配置、圖示、顏色和其他元素應與 UI 的其餘部分一致。詳情請見 自訂

實作設定畫面

設定整合

圖 4. 設定整合

設定畫面是一般的 Android 活動。如果已實作這些項目,其進入點 作為 VIA 的一部分,必須在 res/xml/interaction_service.xml 中宣告。 資訊清單 (請參閱 「資訊清單」)。 「設定」部分,可以繼續設定及登入 (如果使用者未完成操作) ),或者視需要提供登出切換使用者的選項。與設定類似 上述畫面應符合以下條件:

  • 提供在畫面堆疊中退出返回上一個畫面的選項 (例如前往「汽車設定」)。
  • 開車時禁止使用。詳情請參閱駕駛人分心等級規範
  • 請將各個車輛設計系統配對。詳情請參閱 自訂

在資訊清單檔案中宣告必要權限

VIA 要求的權限可分為三個類別:

  • 系統簽章權限。這些是權限 只會授予預先安裝系統簽署的 APK。使用者無法授予 這些權限,則只有原始設備製造商 (OEM) 在建構系統映像檔時才能授予權限。 如要進一步瞭解如何取得簽章權限,請參閱「授予系統權限」。
  • 危險權限。使用者必須具備這些權限 透過 PermissionsController 對話方塊授予原始設備製造商 (OEM) 可將其中部分 授予預設 VoiceInteractionService 的權限。考量到這項預設值 無論裝置為何,應用程式應可要求取得這些憑證 授予必要的權限
  • 其他權限。這些權限代表了 不必等使用者介入系統會自動授予這些權限 由系統執行

如上所述,下一節只著重在 危險權限。除非使用者處於 。

如果應用程式不具備運作所需的權限, 建議您使用語音話 向學員說明情況 ,以及向使用者發送通知,提供使用者可以用於 接著返回 VIA 設定畫面。詳情請參閱 1.通知提醒

在設定畫面中要求權限

系統會透過一般的 ActivityCompat#requestPermission() 方法 (或同等功能) 要求危險權限。如要進一步瞭解如何要求權限,請參閱 要求應用程式權限

要求權限

圖 5. 要求權限

通知事件監聽器權限

如要導入 TTR 流程,您必須將 VIA 指定為 通知接聽器。這並不代表權限,而是 讓系統將通知傳送到已註冊的 Pod 接聽程式。如要確認 VIA 是否已取得這些資訊的存取權, 應用程式可以:

如果使用者未預先授予存取權,VIA 應將使用者導向 混合使用語音的「車輛設定」的「通知存取權」部分 和通知下列程式碼可用來開啟 設定 app:

private void requestNotificationListenerAccess() {
    Intent intent = new Intent(Settings
        .ACTION_NOTIFICATION_LISTENER_SETTINGS);
    intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
    startActivity(intent);
}

實作語音板 UI

VoiceInteractionSession 收到 onShow() 回呼時, 可顯示語音板的 UI如需語音固定板的視覺和使用者體驗指南,請參閱 預先載入的 Google 助理:使用者體驗指南

顯示語音板

圖 6. 顯示語音板

實作此 UI 的方法有兩種:

  • 覆寫 VoiceInteractionSession#onCreateContentView()
  • 使用 VoiceInteractionSession#startAssistantActivity() 啟動活動

使用 onCreateContentView()

這是顯示語音板的預設方式。VoiceInteractionSession 基礎類別會建立視窗,並以語音形式管理其生命週期 都會有狀態應用程式必須覆寫 VoiceInteractionSession#onCreateContentView() 並傳回附加至該視窗的檢視畫面 已建立。此檢視畫面一開始應處於隱藏狀態。有語音互動開始時 這個檢視表應在 VoiceInteractionSession#onShow() 上顯示 然後在 VoiceInteractionSession#onHide() 再次隱藏。

public class MyVoiceInteractionSession extends CarVoiceInteractionSession {
    private View mVoicePlate;
    …

    @Override
    public View onCreateContentView() {
        mVoicePlate = inflater.inflate(R.layout.voice_plate, null);
        …
   }

    @Override
    protected void onShow(String action, Bundle args, int showFlags) {
        // TODO: Update UI state to "listening"
        mVoicePlate.setVisibility(View.VISIBLE);
    }

    @Override
    public void onHide() {
        mVoicePlate.setVisibility(View.GONE);
    }
    …
}

使用這個方法時,建議調整 VoiceInteractionSession#onComputeInsets() 以免 UI 遭到遮蓋的區域

使用 startAssistantActivity()

在這種情況下,VoiceInteractionSession 會委派語音處理作業 並排顯示一般活動使用這個選項時,VoiceInteractionSession 實作項目必須停止在 onPrepareShow() 上建立預設內容視窗 (請參閱「使用 onCreateContentView()」一節) 回呼。在 VoiceInteractionSession#onShow(),工作階段將啟動語音 使用 VoiceInteractionSession#startAssistantActivity() 進行車牌活動。這個 方法會使用適當的視窗設定和活動標記來啟動使用者介面。

public class MyVoiceInteractionSession extends CarVoiceInteractionSession {
    …

    @Override
    public void onPrepareShow(Bundle args, int showFlags) {
        super.onPrepareShow(args, showFlags);
        setUiEnabled(false);
    }

    @Override
    protected void onShow(String action, Bundle args, int showFlags) {
        closeSystemDialogs();
        Intent intent = new Intent(getContext(), VoicePlateActivity.class);
        intent.putExtra(VoicePlateActivity.EXTRA_ACTION, action);
        intent.putExtra(VoicePlateActivity.EXTRA_ARGS, args);
        startAssistantActivity(intent);
    }

    …
}

維持這個活動與 VoiceInteractionSession,一組內部意圖或服務繫結可能位於 這通常代表交易 不會十分要求關聯語意舉例來說,叫用 VoiceInteractionSession#onHide() 時, 工作階段都必須能傳送這項要求給活動。

重要事項:在 Automotive 中,只需特別加註 使用者體驗「許可清單」所列的活動或活動可在 。這適用於開頭為 VoiceInteractionSession#startAssistantActivity()。記得要 使用 <meta-data android:name="distractionOptimized" android:value="true"/> 為活動加上註解,或是加入 /packages/services/Car/service/res/values/config.xml systemActivityWhitelist 鍵中的活動 檔案。如需更多資訊,請參閱驅動程式 分心處理規範

實作語音辨識

本節將說明如何透過偵測實作語音辨識功能 和啟動字詞的辨識「啟動字詞」是用來開始新查詢的觸發字詞 透過語音或語音執行操作例如「Ok Google」或「Ok Google」啟動字詞

需求端平台啟動字詞偵測

Android 可讓您在 DSP 層級存取持續待機啟動字詞偵測工具,方法是: AlwaysOnHotwordDetector 的意義。 在低 CPU 環境中實作啟動字詞偵測的方法。這項功能的用途是 可以分為兩個部分

VoiceInteractionService 實作可以建立啟動字詞偵測工具, VoiceInteractionService#createAlwaysOnHotwordDetector(), 傳遞要用於偵測的關鍵字語句和語言代碼。因此, 應用程式收到 onAvailabilityChanged() 回呼值為下列其中一個可能的值:

  • STATE_HARDWARE_UNAVAILABLE。DSP 功能不適用於 裝置。在本例中,使用軟體啟動字詞偵測功能。
  • STATE_HARDWARE_UNSUPPORTED。需求端平台支援服務通常並未開放使用,但 DSP 不支援指定的鍵盤詞組和語言代碼組合。應用程式可選擇使用 軟體啟動字詞偵測
  • STATE_HARDWARE_ENROLLED。熱門字詞偵測功能已就緒,你可以透過下列方式啟動熱門字詞偵測功能: 呼叫 startRecognition() 方法
  • STATE_HARDWARE_UNENROLLED。所要求關鍵字詞組的音效模型未 但還是可以註冊

您可以使用 IVoiceInteractionManagerService#updateKeyphraseSoundModel() 註冊啟動字詞偵測聲響模型。 系統一次只能在系統中登錄多個模型,但只能註冊一個模型 模型與 AlwaysOnHotwordDetector 相關聯。 並非所有裝置都能使用需求端平台啟動字詞偵測功能。VIA 開發人員 應使用 getDspModuleProperties() 檢查硬體功能 方法。用於顯示 請參閱 VoiceEnrollment/src/com/android/test/voiceenrollment/EnrollmentUtil.java,瞭解如何註冊聲響模型。 相關資訊請參閱「同時擷取」相關說明 並行啟動字詞辨識。

軟體啟動字詞偵測

如上所述,並非所有平台都能使用需求端平台啟動字詞偵測功能 裝置 (例如 Android 模擬器不提供 DSP 模擬)。在本例中 是唯一的替代工具為了避免干擾 應用程式可能需要存取麥克風,VIA 必須使用以下方式存取音訊輸入裝置:

這兩個常數都是 @hide,僅適用於套件的應用程式。

管理音訊輸入和語音辨識

音訊輸入是使用 MediaRecorder 類別實作。 如要進一步瞭解如何使用此 API,請參閱 MediaRecorder 總覽。預計將採用語音互動服務RecognitionService 類別實作。系統中所有需要語音辨識的應用程式都會使用 存取這項功能如要進行語音辨識及存取麥克風,VIA 必須包含 android.permission.RECORD_AUDIO。 存取 RecognitionService 的應用程式 實作項目也應保留這項權限。

在 Android 10 之前,應用程式的麥克風存取權僅限於一個應用程式 時間 (請參閱上文),但啟動字詞偵測除外。自 Android 10 起, 麥克風存取權可以分享詳情請參閱「分享 音訊輸入

存取音訊輸出

當 VIA 準備好提供口頭回應時, 請遵循下一組準則: