Indicador de entrada de voz en Jetpack Compose Glimmer

Dispositivos de realidad extendida correspondientes
Esta guía te ayuda a crear experiencias para estos tipos de dispositivos de realidad extendida.
Lentes de visualización

El VoiceInputIndicator es un componente Glimmer de Jetpack Compose que muestra la actividad de sonido al usuario. Puedes usar este componente para aceptar la entrada de voz o cualquier otro audio, y proporcionar comentarios visuales para mostrar que tu app está capturando audio.

Este componente es estrictamente un elemento visual. No graba audio ni procesa datos del micrófono por sí solo. En cambio, responde a un level de audio que proporciona tu app, que muestra una representación visual de la intensidad del audio.

Figura 1. Un ejemplo de VoiceInputIndicator.

Solicita permisos proyectados

Para capturar datos de audio que impulsen el indicador, tu app necesita el Manifest.permission.RECORD_AUDIO permiso.

Cuando crees experiencias aumentadas para lentes de visualización, asegúrate de solicitar los permisos correctamente en el dispositivo y en los lentes. Usa ProjectedPermissionsResultContract y ProjectedPermissionsRequestParams para solicitarle al usuario que lo haga.

Para obtener más información sobre la solicitud de permisos en entornos proyectados, consulta Solicita permisos de hardware.

Captura y normaliza el audio

El VoiceInputIndicator requiere un Float entre 0.0f y 1.0f para reflejar visualmente la intensidad del audio. Dado que funciona puramente como un componente visual y no captura audio, tu app debe supervisar activamente el micrófono y transmitir el volumen al parámetro level del indicador.

Si bien existen varias formas de capturar datos de audio, un enfoque es usar la SpeechRecognizer API. Cuando usas SpeechRecognizer, puedes capturar actualizaciones de volumen en tiempo real con la devolución de llamada RecognitionListener.onRmsChanged, que proporciona el nivel de audio en decibelios, rmsdB.

Dado que este valor sin procesar suele estar entre 0 y 10, debes normalizar el resultado al rango requerido de 0.0f a 1.0f. Puedes mantener este nivel normalizado en una variable de estado para actualizar continuamente el indicador.

A continuación, se muestra un ejemplo con el uso de RecognitionListener para actualizar una variable 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)

Integra el indicador de entrada de voz

Una vez que tu transmisión de audio esté normalizada y expuesta correctamente como estado, puedes pasar la directamente a 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 personalización

El VoiceInputIndicator proporciona algunos parámetros para personalizar su comportamiento y apariencia:

  • level: Es una función que muestra un Float que representa el nivel de la entrada de voz, que va de 0.0 para el silencio a 1.0 para el sonido más alto.
  • indicatorColor: Es el color de las barras indicadoras. De forma predeterminada, usa el color primario del tema Glimmer; consulta GlimmerTheme.colors.primary.
  • modifier: Es el modifier estándar de Compose que se aplicará al indicador.

Si tu IU requiere que el indicador se encuentre dentro de un contenedor de fondo visible, usa ContainedVoiceInputIndicator. Esta alternativa garantiza que las barras indicadoras sean transparentes, lo que permite que se muestre el contenedor de fondo.