如要實作語音互動應用程式 (VIA),請完成下列步驟:
- 建立 VIA 骨架。
- (選用) 實作設定/登入流程。
- (選用) 實作設定畫面。
- 在資訊清單檔案中宣告必要權限。
- 實作語音板 UI。
- 實作語音辨識功能 (必須包含 RecognitionService API 實作)。
- 實作語音內容 (您也可以實作 TextToSpeech API)。
- 實作指令執行要求。以下列語言觀看這項內容 執行指令。
以下各節說明如何完成上述各個步驟。
建立 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
下圖說明每個實體的生命週期:
圖 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 專案。在這種情況下:
- 針對這種情況多口頭告知使用者 (例如:「為了妥善運作, 我需要你完成幾個步驟... 」)。
- 如果使用者體驗限制引擎允許 (請參閱 UX_RESTRICTIONS_NO_SETUP),請詢問使用者是否要啟動 設定程序,然後開啟 VIA 的設定畫面。
- 否則 (例如使用者正在開車),請留下通知讓使用者前往 只要在安全的情況下點選該選項即可
建構語音互動設定畫面
設定和登入畫面應做為一般活動開發。詳情請參閱 針對使用者介面開發作業實施的使用者體驗和視覺指南 預先載入的 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 是否已取得這些資訊的存取權, 應用程式可以:
- (選用) 使用
CarAssistUtils#assistantIsNotificationListener()
。您可以在設定流程等情況下完成這項操作。 - (必要) 採取動作來處理
CarVoiceInteractionSession#onShow()
VOICE_ACTION_HANDLE_EXCEPTION
以及例外狀況EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING
如果使用者未預先授予存取權,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 環境中實作啟動字詞偵測的方法。這項功能的用途是
可以分為兩個部分
- 建立
AlwaysOnHotwordDetector
的例項。 - 註冊啟動字詞偵測音效模型。
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 準備好提供口頭回應時, 請遵循下一組準則:
- 要求音訊焦點或管理音訊輸出時,應用程式
必須使用
AudioAttributes#USAGE_ASSISTANT
和AudioAttributes#CONTENT_TYPE_SPEECH
做為音訊屬性。 - 在語音辨識期間,必須使用
AudioManage#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE
要求音訊焦點。 請注意,部分媒體應用程式可能未正確回應媒體指令 (請參閱執行媒體指令一文)。 焦點就會移除