Indicateur de saisie vocale dans Jetpack Compose Glimmer

Appareils XR concernés
Ces conseils vous aident à créer des expériences pour ces types d'appareils XR.
Lunettes d'affichage

Le VoiceInputIndicator est un composant Jetpack Compose Glimmer qui affiche l'activité sonore à l'utilisateur. Vous pouvez utiliser ce composant pour accepter la saisie vocale ou d'autres contenus audio, et fournir un retour visuel indiquant que votre application capture l'audio.

Ce composant est strictement un élément visuel. Il n'enregistre pas l'audio ni ne traite les données du micro par lui-même. Au lieu de cela, il répond à un level audio fourni par votre application, qui affiche une représentation visuelle de l'intensité audio.

Figure 1. Exemple de VoiceInputIndicator.

Demander des autorisations projetées

Pour capturer des données audio afin de piloter l'indicateur, votre application a besoin de l'autorisation Manifest.permission.RECORD_AUDIO.

Lorsque vous créez des expériences de réalité augmentée pour les lunettes d'affichage, assurez-vous de demander correctement les autorisations à la fois sur l'appareil et sur les lunettes. Utilisez ProjectedPermissionsResultContract et ProjectedPermissionsRequestParams pour inviter l'utilisateur.

Pour en savoir plus sur la demande d'autorisations dans les environnements projetés, consultez Demander des autorisations matérielles.

Capturer et normaliser l'audio

Le VoiceInputIndicator nécessite un Float compris entre 0.0f et 1.0f pour refléter visuellement l'intensité audio. Comme il fonctionne uniquement comme un composant visuel et ne capture pas l'audio, votre application doit surveiller activement le micro et diffuser le volume vers le paramètre level de l'indicateur.

Il existe plusieurs façons de capturer des données audio. L'une d'elles consiste à utiliser l'API SpeechRecognizer. Lorsque vous utilisez SpeechRecognizer, vous pouvez capturer les mises à jour du volume en temps réel à l'aide du RecognitionListener.onRmsChanged rappel, qui fournit le niveau audio en décibels, rmsdB.

Comme cette valeur brute se situe généralement entre 0 et 10, vous devez normaliser la sortie dans la plage requise 0.0f à 1.0f. Vous pouvez conserver ce niveau normalisé dans une variable d'état pour mettre à jour l'indicateur en continu.

Voici un exemple d'utilisation d'un RecognitionListener pour mettre à jour une variable d'état :

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

Intégrer l'indicateur de saisie vocale

Une fois votre flux audio correctement normalisé et exposé en tant qu'état, vous pouvez le transmettre directement à 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
    )
}

Paramètres de personnalisation

Le VoiceInputIndicator fournit quelques paramètres pour personnaliser son comportement et son apparence :

  • level: fonction renvoyant un Float qui représente le niveau de la saisie vocale, allant de 0.0 pour le silence à 1.0 pour le son le plus fort.
  • indicatorColor : couleur des barres de l'indicateur. Par défaut, elle utilise la couleur principale du thème Glimmer. Consultez GlimmerTheme.colors.primary.
  • modifier : Le modifier Compose standard à appliquer à l' indicateur.

Si votre interface utilisateur nécessite que l'indicateur se trouve dans un conteneur d'arrière-plan visible, utilisez ContainedVoiceInputIndicator. Cette alternative garantit que les barres de l'indicateur sont transparentes, ce qui permet au conteneur d'arrière-plan de s'afficher.