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 con pantalla

VoiceInputIndicator es un componente de Glimmer de Jetpack Compose que muestra la actividad de sonido al usuario. Puedes usar este componente para aceptar entradas de voz o de otro tipo de 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í sola. 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: Ejemplo de VoiceInputIndicator.

Cómo solicitar permisos proyectados

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

Cuando crees experiencias aumentadas para lentes con pantalla, asegúrate de solicitar los permisos correctamente tanto en el dispositivo como en los lentes. Usa ProjectedActivityCompat.requestPermissions para solicitarle al usuario que lo haga.

Para obtener más información sobre cómo solicitar permisos en entornos proyectados, consulta Cómo solicitar permisos de hardware.

Captura y normaliza audio

El VoiceInputIndicator requiere un Float entre 0.0f y 1.0f para reflejar visualmente la intensidad del audio. Como funciona únicamente 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 hay varias formas de capturar datos de audio, un enfoque es usar la API de SpeechRecognizer. 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 decibeles, rmsdB.

Debido a 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 el indicador de forma continua.

Este es un ejemplo en el que se usa un 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)

Cómo integrar el indicador de entrada de voz

Una vez que tu transmisión de audio se normalice y exponga correctamente como estado, puedes pasarla 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

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

  • level: Es una función que devuelve un Float que representa el nivel de la entrada de voz, que varía 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, se usa el color principal 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 ubique dentro de un contenedor de fondo visible, usa ContainedVoiceInputIndicator. Esta alternativa garantiza que las barras de indicadores sean transparentes, lo que permite que se vea el contenedor de fondo.