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

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

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

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

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

Как запросить спроецированные разрешения

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

При создании приложений с дополненной реальностью для дисплейных очков убедитесь, что вы правильно запрашиваете разрешения как на устройстве, так и на очках. Используйте ProjectedPermissionsResultContract и ProjectedPermissionsRequestParams, чтобы запросить у пользователя информацию.

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

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

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

Существует несколько способов сбора аудиоданных, но один из них – использовать API SpeechRecognizer. При использовании 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 – стандартный метод Compose modifier, который нужно применить к индикатору.

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