Индикатор голосового ввода в Jetpack Compose Glimmer

Поддерживаемые XR-устройства
Это руководство поможет вам создавать продукты для таких XR-устройств.
Видеоочки

VoiceInputIndicator – это компонент Jetpack Compose Glimmer, который показывает пользователю звуковую активность. Вы можете использовать этот компонент, чтобы принимать голосовой ввод или другие аудиоданные и предоставлять визуальную обратную связь, показывающую, что ваше приложение записывает звук.

Этот компонент является исключительно визуальным элементом. Оно не записывает аудио и не обрабатывает данные микрофона самостоятельно. Вместо этого он реагирует на аудио level, предоставленное вашим приложением, которое показывает визуальное представление интенсивности звука.

Рисунок 1. Пример VoiceInputIndicator.

Запрос разрешений для трансляции

Чтобы записывать аудиоданные для индикатора, приложению требуется разрешение Manifest.permission.RECORD_AUDIO.

При создании дополненной реальности для видеоочков убедитесь, что вы правильно запрашиваете разрешения как на устройстве, так и на очках. Используйте ProjectedActivityCompat.requestPermissions, чтобы показать пользователю запрос.

Подробнее о том, как запрашивать разрешения на доступ к оборудованию…

Запись и нормализация аудио

Для визуального отражения интенсивности звука в VoiceInputIndicator требуется Float в диапазоне от 0.0f до 1.0f. Поскольку он работает исключительно как визуальный компонент и не записывает звук, ваше приложение должно активно отслеживать микрофон и передавать громкость в параметр level индикатора.

Записывать аудиоданные можно разными способами, например с помощью SpeechRecognizer API. При использовании SpeechRecognizer вы можете получать обновления громкости в реальном времени с помощью обратного вызова RecognitionListener.onRmsChanged, который предоставляет уровень звука в децибелах (rmsdB).

Поскольку это необработанное значение обычно находится в диапазоне от 0 до 10, вам необходимо нормализовать выходные данные до требуемого диапазона от 0.0f до 1.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 – стандартный modifier Compose, который будет применен к индикатору.

Если в вашем интерфейсе индикатор должен находиться в видимом фоновом контейнере, используйте ContainedVoiceInputIndicator. В этом случае полосы индикатора будут прозрачными, и сквозь них будет виден фон контейнера.