Indicador de entrada de texto por voz no Jetpack Compose Glimmer

Dispositivos XR relevantes
Estas orientações ajudam você a criar experiências para esses tipos de dispositivos XR.
Óculos de exibição

O VoiceInputIndicator é um componente Glimmer do Jetpack Compose que mostra a atividade sonora ao usuário. Você pode usar esse componente para aceitar entrada de voz ou outro áudio e fornecer feedback visual para mostrar que o app está capturando áudio.

Esse componente é estritamente um elemento visual. Ele não grava áudio nem processa dados do microfone por conta própria. Em vez disso, ele responde a um level de áudio fornecido pelo app, que mostra uma representação visual da intensidade do áudio.

Figura 1. Um exemplo do VoiceInputIndicator.

Solicitar permissões projetadas

Para capturar dados de áudio para acionar o indicador, o app precisa da Manifest.permission.RECORD_AUDIO permissão.

Ao criar experiências aumentadas para óculos com tela virtual, peça permissões corretamente no dispositivo e nos óculos. Use ProjectedPermissionsResultContract e ProjectedPermissionsRequestParams para solicitar ao usuário.

Para mais informações sobre como solicitar permissões em ambientes projetados, consulte Solicitar permissões de hardware.

Capturar e normalizar áudio

O VoiceInputIndicator exige um Float entre 0.0f e 1.0f para refletir visualmente a intensidade do áudio. Como ele funciona puramente como um componente visual e não captura áudio, o app precisa monitorar ativamente o microfone e transmitir o volume para o parâmetro level do indicador.

Há várias maneiras de capturar dados de áudio. Uma abordagem é usar a API SpeechRecognizer. Ao usar SpeechRecognizer, você pode capturar atualizações de volume em tempo real usando o RecognitionListener.onRmsChanged callback, que fornece o nível de áudio em decibéis, rmsdB.

Como esse valor bruto normalmente fica entre 0 e 10, é necessário normalizar a saída para o intervalo necessário de 0.0f a 1.0f. Você pode manter esse nível normalizado em uma variável de estado para atualizar continuamente o indicador.

Confira um exemplo usando um RecognitionListener para atualizar uma variável de estado:

// 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)

Integrar o indicador de entrada de texto por voz

Depois que o stream de áudio for normalizado e exposto como estado, você poderá transmiti-lo diretamente para o 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
    )
}

Parâmetros de personalização

O VoiceInputIndicator oferece alguns parâmetros para personalizar o seu comportamento e a aparência:

  • level: uma função que retorna um Float que representa o nível da entrada de voz, variando de 0.0 para silêncio a 1.0 para o som mais alto.
  • indicatorColor: a cor das barras do indicador. Por padrão, ela usa a cor primária do tema Glimmer. Consulte GlimmerTheme.colors.primary.
  • modifier: o modifier padrão do Compose a ser aplicado ao indicador.

Se a interface exigir que o indicador fique dentro de um contêiner de plano de fundo visível, use o ContainedVoiceInputIndicator. Essa alternativa garante que as barras do indicador sejam transparentes, permitindo que o contêiner de plano de fundo apareça.