مشاركة الإدخال الصوتي

يكون إدخال الصوت عادةً من الميكروفون المدمج أو الميكروفون الخارجي أو واجهة الصوت المتصلة بالجهاز. ويمكن أن يكون الإدخال الصوتي أيضًا من محادثة هاتفية.

في بعض الأحيان، قد يريد تطبيقان أو أكثر "التقاط" إدخال الصوت نفسه. قد يقومون بمهام مختلفة. على سبيل المثال، قد تكون بعض التطبيقات التي تتلقى الصوت "تسجّل" مثل "مسجّل صوتي" بسيط، بينما تتحدّث تطبيقات أخرى عن "الاستماع"، مثل "مساعد Google" أو إحدى خدمات تسهيل الاستخدام التي تستجيب للأوامر الصوتية.

وفي كلتا الحالتين، تريد هذه التطبيقات تلقّي إدخال الصوت. ونستخدم مصطلح "التقاط" في هذه الصفحة بغض النظر عما إذا كان التطبيق يسجّل أو يستمع فقط.

إذا أراد تطبيقان أو أكثر تسجيل الصوت في الوقت نفسه، قد تكون هناك مشكلة في إرسال الإشارة الصوتية من المصدر نفسه إلى جميع التطبيقات. توضّح هذه الصفحة كيف يشارك نظام Android إدخال الصوت بين تطبيقات متعددة تلتقط الصوت.

سلوك مستخدمي الأجهزة التي تعمل بالإصدار 10 من نظام التشغيل Android

قبل نظام التشغيل Android 10، كان بالإمكان تسجيل البث الصوتي عبر تطبيق واحد في كل مرة. إذا كان أحد التطبيقات يسجِّل الصوت أو تستمع إليه، يمكن لتطبيقك إنشاء عنصر AudioRecord، ولكن سيظهر خطأ عند طلب الرمز AudioRecord.startRecording() وتعذّر بدء التسجيل.

وأحد الاستثناءات لهذه القاعدة هو عندما حصل تطبيق مميّز (مثل "مساعد Google" أو خدمة لتسهيل الاستخدام) على الإذن android.permission.CAPTURE_AUDIO_HOTWORD واستخدمت مصدرًا صوتيًا من النوع HOTWORD. وفي هذه الحالة، يمكن لتطبيق آخر بدء التسجيل. عندما حدث ذلك، تم إنهاء التطبيق الامتياز وحصل التطبيق الجديد على المدخلات.

تم إجراء تغيير آخر على نظام Android 9: يمكن للتطبيقات التي تعمل في المقدّمة فقط (أو خدمة تعمل في المقدّمة) تسجيل إدخال الصوت. عندما بدأ التقاط تطبيق لا يحتوي على خدمة تعمل في المقدّمة أو مكوّن واجهة مستخدم تعمل في المقدّمة، استمر التطبيق في العمل ولكنّه توقف عن رصد الصوت، حتى لو كان التطبيق الوحيد الذي يلتقط الصوت في ذلك الوقت.

سلوك نظام التشغيل Android 10

إنّ السلوك السابق لنظام Android 10 هو "أولوية الحجز أولاً". عندما يبدأ التطبيق في التقاط الصوت، لن يتمكن أي تطبيق آخر من الوصول إلى إدخال الصوت حتى يتوقف التطبيق الذي يسجِّل الصوت.

يفرض Android 10 نظام أولوية يمكنه تبديل مصدر بث الصوت بين التطبيقات أثناء تشغيلها. في معظم الحالات، إذا حصل تطبيق جديد على الإدخال الصوتي، يستمر تشغيل التطبيق الذي التقاط الصورة سابقًا، لكنه يتلقى صمتًا. في بعض الحالات، يمكن للنظام مواصلة إرسال الصوت إلى كلا التطبيقين. وقد تم توضيح سيناريوهات المشاركة المختلفة أدناه.

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

يميِّز Android نوعَين من التطبيقات لأغراض تسجيل الصوت:

  • يتم تثبيت التطبيقات "العادية" من قِبل المستخدم.
  • يتم تثبيت التطبيقات "المميزة" مسبقًا على الجهاز. ويشمل ذلك "مساعد Google" وجميع خدمات تسهيل الاستخدام.

بالإضافة إلى ذلك، يتم التعامل مع التطبيق بطريقة مختلفة إذا كان يستخدم مصدر صوت "يراعي الخصوصية": CAMCORDER أو VOICE_COMMUNICATION.

في ما يلي قواعد تحديد الأولوية لاستخدام إدخال الصوت ومشاركته:

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

سيناريوهات المشاركة

عندما يحاول تطبيقان تسجيل الصوت، قد يتمكن كلا التطبيقين من استقبال إشارة الإدخال أو قد يكون أحدهما صامتًا.

هناك أربعة سيناريوهات رئيسية:

  • "مساعد Google" + التطبيق العادي
  • خدمة تسهيل الاستخدام + تطبيق عادي
  • تطبيقان عاديان
  • المكالمة الصوتية + التطبيق العادي

"مساعد Google" + التطبيق العادي

"مساعد Google" هو تطبيق مميّز لأنّه مثبَّت مسبقًا ويتولّي دور RoleManager.ROLE_ASSISTANT. يتم التعامل مع أي تطبيق آخر مثبَّت مسبقًا تم منحه هذا الدور بالطريقة نفسها.

ويشارك Android الصوت المدخل وفقًا للقواعد التالية:

  • يمكن لخدمة "مساعد Google" تلقّي الصوت (بصرف النظر عمّا إذا كان الصوت في المقدّمة أو الخلفية) إلا إذا بدأ تطبيق آخر يستخدم مصدر صوت حسّاسًا للخصوصية.

  • يتلقّى التطبيق الصوت، ما لم يكن هناك عنصر واجهة مستخدم مرئي في أعلى الشاشة في "مساعد Google".

يُرجى العِلم بأنّ كلا التطبيقَين يتلقّى الصوت فقط عندما يكون "مساعد Google" مفعّلاً في الخلفية، في حين لا يلتقط التطبيق الآخر من مصدر صوت حسّاس للخصوصية.

خدمة تسهيل الاستخدام + تطبيق عادي

تتطلّب السمة AccessibilityService بيانًا صارمًا.

ويشارك Android الصوت المدخل وفقًا للقواعد التالية:

  • في حال وجود واجهة مستخدم الخدمة في الأعلى، يتلقى كل من الخدمة والتطبيق إدخالاً صوتيًا. ويوفر هذا السلوك وظائف مثل التحكم في مكالمة صوتية أو التقاط فيديو باستخدام الأوامر الصوتية.

  • إذا لم تكن الخدمة في المقدمة، يتم التعامل مع هذه الحالة على غرار الحالة العادية التي تخصّ التطبيقَين أدناه.

تطبيقان عاديان

عندما يتم التقاط تطبيقين في وقت واحد، يتلقى تطبيق واحد فقط الصوت والآخر يكتم الصوت.

ويشارك Android الصوت المدخل وفقًا للقواعد التالية:

  • إذا لم يكن أي من التطبيقين حساسًا للخصوصية، فإن التطبيق الذي يحتوي على واجهة مستخدم في الأعلى يتلقى الصوت. إذا لم تتوفر واجهة مستخدم في أي تطبيق، يعني هذا أنّ التطبيق الذي بدأ تسجيل الصوت مؤخرًا.
  • فإذا كان أحد التطبيقات حساسًا من حيث الخصوصية، فهو يتلقى الصوت ويتم كتم صوت التطبيق الآخر حتى ولو كان يتضمن واجهة مستخدم في الأعلى أو بدأ التقاط الصوت مؤخرًا.
  • فإذا كان كلا التطبيقين يراعيان الخصوصية، فإن التطبيق الذي بدأ في التقاط الصوت مؤخرًا يتلقى الصوت مؤخرًا والتطبيق الآخر صامت.

المكالمة الصوتية + التطبيق العادي

يتم تفعيل المكالمة الصوتية إذا كان وضع الصوت المعروض من خلال AudioManager.getMode() هو MODE_IN_CALL أو MODE_IN_COMMUNICATION.

ويشارك Android الصوت المدخل وفقًا للقواعد التالية:

سلوك نظام التشغيل Android 11

يتّبع نظام التشغيل Android 11 (المستوى 30) نظام أولوية Android 10 الموضَّح أعلاه. وتوفّر هذه الميزة أيضًا طرقًا جديدة في AudioRecord وMediaRecorder وAAudioStream تتيح إمكانية تسجيل الصوت بشكل متزامن أو توقِفه، بغض النظر عن حالة الاستخدام المحدَّدة.

الطرق الجديدة هي:

عندما تكون قيمة setPrivacySensitive() هي true، تكون حالة استخدام الالتقاط خاصة، ولا يمكن حتى لـ "مساعد Google" المميّز الحصول على الإذن في الوقت نفسه. يلغي هذا الإعداد السلوك التلقائي الذي يعتمد على مصدر الصوت. على سبيل المثال، تكون إعدادات VOICE_COMMUNICATION خاصة بشكل تلقائي، لكنّ السمة UNPROCESSED ليست خاصة.

تغييرات الإعدادات

وعندما تلتقط العديد من التطبيقات الصوت في الوقت نفسه، يكون تطبيق واحد أو تطبيقين فقط "نشطًا" (أي يستقبل الصوت)، بينما يتم كتم صوت التطبيقات الأخرى (وتكون الميزة صامتة). وعند تغيير التطبيقات النشطة، قد يعيد إطار العمل الصوتي ضبط المسارات الصوتية وفقًا للقواعد التالية:

  • قد يتغير جهاز إدخال الصوت لكل تطبيق نشط (على سبيل المثال، من الميكروفون المدمج إلى سماعة رأس بلوتوث ملحقة).
  • تم تفعيل المعالجة المسبقة المرتبطة بالتطبيق النشط ذي الأولوية الأعلى. ويتم تجاهل جميع العمليات المسبقة الأخرى.

بما أنّه قد يتم كتم صوت تطبيق نشط عندما يصبح أحد التطبيقات ذات الأولوية الأعلى نشطًا، يمكنك تسجيل AudioManager.audioRecordingCallback في العنصر AudioRecord أو MediaRecorder ليتم إعلامك عند إجراء تغييرات على الإعدادات. يمكن أن تكون التغييرات المحتمَلة على النحو التالي:

  • التقاط صور تم كتم صوتها أو إلغاء كتمها
  • تم تغيير الجهاز.
  • تم تغيير إعدادات المعالجة المسبقة
  • تم تغيير خصائص مصدر البيانات (معدّل أخذ العيّنات وقناع القناة وتنسيق النموذج)

يجب الاتصال برقم AudioRecord.registerAudioRecordingCallback() قبل بدء الالتقاط. لا يتم تنفيذ معاودة الاتصال إلا عندما يتلقّى التطبيق صوتًا ويحدث تغيير.

تعرض الطريقة onRecordingConfigChanged() رمز AudioRecordingConfiguration يتضمّن حالة تسجيل الصوت الحالية. استخدم الطرق التالية لمعرفة المزيد عن التغيير:

isClientSilenced()
يتم عرض "صحيح" إذا كان الصوت الذي تم إرجاعه إلى العميل يتم حاليًا كتم صوته بسبب سياسة الالتقاط.
getAudioDevice()
إرجاع الجهاز السماعي النشط.
getEffects()
عرض التأثير النشط للمعالجة المسبقة. يُرجى العِلم أنّ التأثير النشط قد لا يكون مطابقًا للتأثير الذي تعرضه getClientEffects() إذا لم يكن التطبيق النشط ذو الأولوية الأعلى.
getFormat()
عرض خصائص ساحة المشاركات. يُرجى العلم أنّ البيانات الصوتية التي يتلقّاها البرنامج تلتزم دائمًا بالتنسيق المطلوب الذي يعرضه getClientFormat(). يُجري إطار العمل تلقائيًا عمليات إعادة التشكيل والقناة والتنسيق اللازمة من التنسيق المستخدَم في واجهة الجهاز إلى التنسيق الذي حدّده العميل.
AudioRecord.getActiveRecordingConfiguration().
لعرض إعدادات التسجيل النشط.

يمكنك الحصول على نظرة عامة على جميع التسجيلات النشطة على الجهاز من خلال الاتصال على الرقم AudioManager.getActiveRecordingConfigurations().