مؤشر الإدخال الصوتي في Jetpack Compose Glimmer

أجهزة XR المشمولة
تساعدك هذه الإرشادات في إنشاء تجارب لهذه الأنواع من أجهزة XR.
النظارات المزودة بشاشة

VoiceInputIndicator هو مكوّن Glimmer في Jetpack Compose يعرض للمستخدم نشاطًا صوتيًا. يمكنك استخدام هذا المكوّن لقبول الإدخال الصوتي أو أي محتوى صوتي آخر وتقديم ملاحظات مرئية للإشارة إلى أنّ تطبيقك يسجّل المحتوى الصوتي.

هذا المكوّن هو عنصر مرئي بحت. ولا يسجّل المحتوى الصوتي أو يعالج بيانات الميكروفون من تلقاء نفسه. بدلاً من ذلك، يستجيب لمستوى الصوت level الذي يوفّره تطبيقك، والذي يعرض تمثيلاً مرئيًا لشدة الصوت.

الشكل 1. مثال على VoiceInputIndicator

طلب الأذونات المتوقّعة

لتسجيل البيانات الصوتية التي تحرّك المؤشر، يحتاج تطبيقك إلى إذن Manifest.permission.RECORD_AUDIO.

عند إنشاء تجارب معزّزة للنظارات المزودة بشاشة، تأكَّد من طلب الأذونات بشكلٍ صحيح على كلٍّ من الجهاز والنظارات. استخدِم ProjectedPermissionsResultContract و ProjectedPermissionsRequestParams لطلب الإذن من المستخدم.

لمزيد من المعلومات حول طلب الأذونات في البيئات المتوقّعة، يُرجى الاطّلاع على طلب أذونات الأجهزة.

تسجيل المحتوى الصوتي وتعديله

يتطلّب VoiceInputIndicator قيمة Float بين 0.0f و1.0f لعرض شدة الصوت بشكلٍ مرئي. بما أنّه يعمل كمكوّن مرئي فقط ولا يسجّل المحتوى الصوتي، يجب أن يراقب تطبيقك الميكروفون بشكلٍ نشط وأن ينقل مستوى الصوت إلى مَعلمة level في المؤشر.

على الرغم من وجود طرق متعدّدة لتسجيل البيانات الصوتية، يتمثّل أحد الأساليب في استخدام واجهة برمجة التطبيقات SpeechRecognizer. عند استخدام SpeechRecognizer، يمكنك تسجيل تعديلات مستوى الصوت في الوقت الفعلي باستخدام معاودة الاتصال RecognitionListener.onRmsChanged، التي توفّر مستوى الصوت بالديسيبل، rmsdB.

بما أنّ هذه القيمة الأولية تتراوح عادةً بين 0 و10، عليك تعديل الناتج ليناسب النطاق المطلوب من 0.0f إلى 1.0f. يمكنك الاحتفاظ بهذا المستوى المعدَّل في متغيّر حالة لتعديل المؤشر باستمرار.

إليك مثال على استخدام RecognitionListener لتعديل متغيّر حالة:

// Example state variables to hold the normalized level
val audioLevel = MutableStateFlow(0f)
val speechRecognizer = SpeechRecognizer.createSpeechRecognizer(context)

val listener = object : RecognitionListener {
    override fun onRmsChanged(rmsdB: Float) {
        // Normalize raw dB (~0–10) to 0.0-1.0 for the indicator
        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 and start recognizing speech
speechRecognizer.setRecognitionListener(listener)

val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply {
    putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
}
speechRecognizer.startListening(intent)

دمج مؤشر الإدخال الصوتي

بعد تعديل بثك الصوتي بشكلٍ صحيح وعرضه كحالة، يمكنك تمريره مباشرةً إلى VoiceInputIndicator.

@Composable
fun VoiceInputExample() {
    // Collect the flow as Compose State so the UI reacts to changes
    val currentLevel by audioLevel.collectAsState()

    VoiceInputIndicator(
        // The component responds to the level provided, showing a visual representation of the audio intensity
        level = { currentLevel },
        modifier = Modifier.size(64.dp)
    )
}

مَعلمات التخصيص

يوفّر VoiceInputIndicator بعض المَعلمات لتخصيص سلوكه ومظهره:

  • level: دالة تعرض قيمة Float تمثّل مستوى الإدخال الصوتي، وتتراوح بين 0.0 للصمت و1.0 لأعلى صوت.
  • indicatorColor: لون أشرطة المؤشر. يستخدم هذا الخيار تلقائيًا اللون الأساسي من مظهر Glimmer، يُرجى الاطّلاع على GlimmerTheme.colors.primary.
  • modifier: أداة التعديل القياسية في Compose modifier التي سيتم تطبيقها على المؤشر.

إذا كانت واجهة المستخدم تتطلّب وضع المؤشر داخل حاوية خلفية مرئية، استخدِم ContainedVoiceInputIndicator. يضمن هذا البديل أنّ أشرطة المؤشر شفافة، ما يسمح بظهور الحاوية الخلفية.