分享音訊輸入內容

音訊輸入通常來自內建麥克風、外接麥克風,或連接到裝置的音訊介面。音訊輸入也可以來自電話對話。

有時,兩個以上的應用程式可能會同時想要「擷取」相同的音訊輸入。他們可能正在執行不同的工作。舉例來說,某些接收音訊的應用程式可能正在「錄音」(例如簡易錄音機),而其他應用程式可能正在「聆聽」(例如 Google 助理或回應語音指令的無障礙服務)。

無論是哪種情況,這些應用程式都想接收音訊輸入。在本頁中,無論應用程式是錄音還是僅聆聽,我們都使用「擷取」一詞。

如果兩個以上的應用程式想要同時擷取音訊,將音訊訊號從相同來源傳送至所有應用程式時,可能會發生問題。本頁說明 Android 系統如何在多個擷取音訊的應用程式之間共用音訊輸入。

Android 10 以下版本的行為

在 Android 10 之前,輸入音訊串流一次只能由一個應用程式擷取。如果已有其他應用程式正在錄音或聆聽音訊,您的應用程式可以建立 AudioRecord 物件,但呼叫 AudioRecord.startRecording() 時會傳回錯誤,且不會開始錄音。

這項規則的例外狀況是,當具特殊權限的應用程式 (例如 Google 助理或無障礙服務) 具有 android.permission.CAPTURE_AUDIO_HOTWORD 權限,並使用 HOTWORD 類型的音訊來源時。在這種情況下,另一個應用程式可能會開始錄音。發生這種情況時,特權應用程式會終止,新應用程式則會擷取輸入內容。

Android 9 新增了一項異動:只有在前景執行的應用程式 (或前景服務) 才能擷取音訊輸入。如果沒有前景服務或前景 UI 元件的應用程式開始擷取音訊,該應用程式會繼續執行,但會收到靜音,即使它是當時唯一擷取音訊的應用程式也一樣。

Android 10 行為

Android 10 之前的行為是「先到先得」。應用程式開始擷取音訊後,其他應用程式就無法存取音訊輸入,直到擷取音訊的應用程式停止為止。

Android 10 採用優先順序機制,可在應用程式執行時切換輸入音訊串流。在大多數情況下,如果新應用程式取得音訊輸入,先前擷取的應用程式會繼續執行,但會收到靜音。在某些情況下,系統可以繼續向兩個應用程式傳送音訊。以下說明各種共用情境。

這個配置與音訊焦點處理多個應用程式爭用音訊輸出的方式類似。不過,音訊焦點是透過程式輔助要求來取得及釋放焦點,而這裡所述的輸入切換配置,則是根據每當新應用程式開始擷取音訊時,自動套用的優先順序政策。

為了擷取音訊,Android 將應用程式分為兩種:

  • 「一般」應用程式是由使用者安裝。
  • 「特殊權限」應用程式會預先安裝在裝置上。包括 Google 助理和所有無障礙服務。

此外,如果應用程式使用「隱私權敏感」音訊來源:CAMCORDER 或 VOICE_COMMUNICATION,則會受到不同處理。

使用及分享音訊輸入內容的優先順序規則如下:

  • 特殊權限應用程式的優先順序高於一般應用程式。
  • 前景 UI 可見的應用程式優先順序高於背景應用程式。
  • 從隱私權敏感來源擷取音訊的應用程式,優先順序高於其他應用程式。
  • 兩個一般應用程式絕不會同時擷取音訊。
  • 在某些情況下,特殊權限應用程式可以與其他應用程式共用音訊輸入。
  • 如果兩個優先順序相同的背景應用程式正在擷取音訊,則最後啟動的應用程式優先順序較高。

共用情境

當兩個應用程式嘗試擷取音訊時,兩者可能都能接收輸入信號,或其中一個應用程式可能接收到靜音。

主要有四種情境:

  • Google 助理 + 一般應用程式
  • 無障礙服務 + 一般應用程式
  • 兩個一般應用程式
  • 語音通話 + 一般應用程式

Google 助理 + 一般應用程式

Google 助理是預先安裝的特殊權限應用程式,具有 RoleManager.ROLE_ASSISTANT 角色。任何其他具有此角色的預先安裝應用程式,也會以類似方式處理。

Android 會根據下列規則分享輸入音訊:

  • 除非其他使用隱私權敏感音訊來源的應用程式已在擷取音訊,否則 Google 助理可以接收音訊 (無論是在前景或背景)。

  • 除非 Google 助理在螢幕頂端有可見的 UI 元件,否則應用程式會接收音訊。

請注意,只有在 Google 助理處於背景,且其他應用程式未從隱私權敏感音訊來源擷取音訊時,兩個應用程式才會接收音訊。

無障礙服務 + 一般應用程式

AccessibilityService 需要嚴格的宣告。

Android 會根據下列規則分享輸入音訊:

  • 如果服務的 UI 位於頂端,服務和應用程式都會收到音訊輸入。這項行為可提供控制語音通話或使用語音指令擷取影片等功能。

  • 如果服務不在頂端,系統會將這種情況視為下方的一般雙應用程式情況。

兩個一般應用程式

當兩個應用程式同時擷取音訊時,只有一個應用程式會收到音訊,另一個則會收到靜音。

Android 會根據下列規則分享輸入音訊:

  • 如果兩個應用程式都不涉及隱私權,則 UI 位於頂端的應用程式會接收音訊。如果兩個應用程式都沒有 UI,則由最近開始擷取的應用程式接收音訊。
  • 如果其中一個應用程式涉及隱私權,則該應用程式會接收音訊,而另一個應用程式則會靜音,即使該應用程式在頂端有 UI 或最近開始擷取也一樣。
  • 如果兩個應用程式都涉及隱私,則最近開始擷取的應用程式會收到音訊,另一個應用程式則會收到靜音。

語音通話 + 一般應用程式

如果 AudioManager.getMode() 傳回的音訊模式為 MODE_IN_CALL 或 MODE_IN_COMMUNICATION,表示語音通話正在進行中。

Android 會根據下列規則分享輸入音訊:

Android 11 行為

Android 11 (API 級別 30) 遵循上述 Android 10 優先順序配置。此外,無論選取何種用途,AudioRecord、MediaRecorder 和 AAudioStream 中的新方法都能啟用及停用同時擷取音訊的功能。

新方法如下:

當 setPrivacySensitive() 為 true 時,擷取用途為私人,即使是具備特殊權限的助理也無法同時擷取。這項設定會覆寫取決於音訊來源的預設行為。舉例來說,VOICE_COMMUNICATION 預設為不公開,但 UNPROCESSED 則否。

設定變更

當多個應用程式同時擷取音訊時,只有一或兩個應用程式處於「活躍」狀態 (接收音訊),其他應用程式則會靜音 (接收靜音)。當使用中的應用程式變更時,音訊架構可能會根據下列規則重新設定音訊路徑:

  • 每個執行中應用程式的音訊輸入裝置可能會變更 (例如從內建麥克風變更為外接藍牙頭戴式耳機)。
  • 系統會啟用與最高優先順序活動應用程式相關聯的預先處理功能。系統會忽略所有其他預先處理作業。

由於優先順序較高的應用程式啟用時,可能會將使用中的應用程式設為靜音,因此您可以在 AudioRecord 或 MediaRecorder 物件上註冊 AudioManager.AudioRecordingCallback,以便在設定變更時收到通知。可能出現的變化包括:

  • 擷取靜音或非靜音
  • 裝置已變更
  • 預先處理已變更
  • 串流屬性已變更 (取樣率、聲道遮罩、取樣格式)

您必須在開始擷取前呼叫 AudioRecord.registerAudioRecordingCallback()。只有在應用程式接收音訊且發生變更時,才會執行回呼。

onRecordingConfigChanged() 方法會傳回包含目前音訊擷取狀態的 AudioRecordingConfiguration。請透過下列方法瞭解異動:

isClientSilenced()
如果因擷取政策而導致傳回用戶端的音訊目前靜音,則傳回 true。
getAudioDevice()
傳回使用中的音訊裝置。
getEffects()
傳回有效的預先處理效果。請注意,如果用戶端不是優先順序最高的有效應用程式,則有效效果可能與 getClientEffects() 傳回的效果不同。
getFormat()
傳回串流屬性。請注意,用戶端實際收到的音訊資料一律會遵循 getClientFormat() 傳回的必要格式。架構會自動執行必要的重新取樣、聲道和格式轉換,將硬體介面使用的格式轉換為用戶端指定的格式。
AudioRecord.getActiveRecordingConfiguration()
傳回有效的錄製設定。

您可以呼叫 AudioManager.getActiveRecordingConfigurations(),查看裝置上所有進行中錄音的一般檢視畫面。