Jetpack Compose Glimmer 中的語音輸入指標

適用的 XR 裝置
這份指南可協助您為這類 XR 裝置打造體驗。
顯示眼鏡

VoiceInputIndicatorJetpack Compose Glimmer 元件,可向使用者顯示聲音活動。您可以使用這個元件接受語音輸入或其他音訊,並提供視覺回饋,表示應用程式正在擷取音訊。

這個元件嚴格來說是視覺元素,不會自行錄音或處理麥克風資料。而是回應應用程式提供的音訊 level,顯示音訊強度的視覺化表示法。

圖 1. VoiceInputIndicator 的範例。

要求預計權限

如要擷取音訊資料來計算指標,應用程式必須具備 Manifest.permission.RECORD_AUDIO 權限。

為顯示型眼鏡建構擴增體驗時,請務必在裝置和眼鏡上正確要求權限。使用 ProjectedPermissionsResultContractProjectedPermissionsRequestParams 提示使用者。

如要進一步瞭解如何在投影環境中要求權限,請參閱「要求硬體權限」。

擷取及正規化音訊

VoiceInputIndicator 需要介於 0.0f1.0f 之間的 Float,才能以視覺化方式反映音訊強度。由於這項指標純粹是視覺化元件,不會擷取音訊,因此應用程式必須主動監控麥克風,並將音量串流至指標的 level 參數。

擷取音訊資料的方法有很多種,其中一種是使用 SpeechRecognizer API。使用 SpeechRecognizer 時,您可以透過 RecognitionListener.onRmsChanged 回呼擷取即時音量更新,該回呼會提供以分貝為單位的音訊音量 rmsdB

由於這個原始值通常介於 0 到 10 之間,您必須將輸出內容正規化為所需的 0.0f1.0f 範圍。您可以將這個標準化層級保留在狀態變數中,持續更新指標。

以下是使用 RecognitionListener 更新狀態變數的範例:

// Example state variable to hold the normalized level (0.0 to 1.0)
// that the VoiceInputIndicator component expects.
val audioLevel = MutableStateFlow(0f)

// Initialize the Android SpeechRecognizer
val speechRecognizer = SpeechRecognizer.createSpeechRecognizer(context)

// Listener to capture speech events and audio level changes
val listener = object : RecognitionListener {
    override fun onRmsChanged(rmsdB: Float) {
        // Normalize raw dB level to a 0.0-1.0 range.
        // Android SpeechRecognizer's rmsdB typically ranges from 0 to ~10.
        audioLevel.value = ((rmsdB - 1f) / 9f).coerceIn(0f, 1f)
    }

    // ... Implement other required RecognitionListener methods ...
    override fun onReadyForSpeech(params: Bundle?) {}
    override fun onBeginningOfSpeech() {}
    override fun onEndOfSpeech() {}
    override fun onError(error: Int) {}
    override fun onResults(results: Bundle?) {}
    override fun onPartialResults(partialResults: Bundle?) {}
    override fun onEvent(eventType: Int, params: Bundle?) {}
    override fun onBufferReceived(buffer: ByteArray?) {}
}

// Attach the listener to the recognizer
speechRecognizer.setRecognitionListener(listener)

// Create an intent to specify the recognition model and behavior
val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply {
    putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
}
// Begin listening for audio input
speechRecognizer.startListening(intent)

整合語音輸入指標

音訊串流經過適當正規化並以狀態形式公開後,即可直接傳遞至 VoiceInputIndicator

@Composable
fun VoiceInputExample(modifier: Modifier) {
    // Collect the flow as Compose State so the UI reacts to changes in real-time.
    val currentLevel by audioLevel.collectAsState()

    VoiceInputIndicator(
        // The VoiceInputIndicator component provides a visual "pulse" or indicator
        // that changes based on the 'level' lambda, which returns a Float between 0.0 and 1.0.
        level = { currentLevel },
        modifier = modifier
    )
}

自訂參數

VoiceInputIndicator 提供多項參數,可自訂其行為和外觀:

  • level:傳回 Float 的函式,代表語音輸入的音量,範圍從 0.0 (無聲) 到 1.0 (最大音量)。
  • indicatorColor:指標列的顏色。根據預設,這會使用 Glimmer 主題中的主要顏色;請參閱 GlimmerTheme.colors.primary
  • modifier:要套用至指標的標準 Compose modifier

如果 UI 需要指標位於可見的背景容器中,請使用 ContainedVoiceInputIndicator。這個替代方案可確保指標列為透明,讓背景容器顯示出來。