التوجيه الصوتي

في Android 10، يحلّ الرمز car_audio_configuration.xml محلّ car_volumes_groups.xml وIAudioControl.getBusForContext. في ملف الإعدادات الجديد، يتم تحديد قائمة بالمناطق. تحتوي كل منطقة على مجموعة واحدة أو أكثر من مجلدات مع الأجهزة المرتبطة بها، ويحتوي كل جهاز على السياقات التي يجب توجيهها داخل تلك المنطقة. يجب تمثيل جميع السياقات داخل كل منطقة.

ضبط توجيه الصوت

تمثّل ملفات سياسة الصوت، التي تقع عادةً في قسم المورّد، إعدادات الأجهزة الصوتية للوحة. يجب تحديد جميع الأجهزة المُشار إليها في car_audio_configuration.xml ضمن audio_policy_configuration.xml.

تفعيل توجيه AAOS

لاستخدام التوجيه المستنِد إلى AAOS، يجب ضبط علامة audioUseDynamicRouting على true:

<resources>
    <bool name="audioUseDynamicRouting">true</bool>
</resources>

عند إيقاف false، سيتم إيقاف التوجيه ومعظم CarAudioService، وسيعود نظام التشغيل إلى السلوك التلقائي للAudioService.

المنطقة الأساسية

سيتم توجيه كل المحتوى الصوتي تلقائيًا إلى المنطقة الأساسية. يمكن أن يكون هناك منطقة أساسية واحدة فقط، ويتم الإشارة إليها في الإعدادات من خلال السمة isPrimary="true".

مثال على الضبط

على سبيل المثال، يمكن أن تحتوي المركبة على منطقتَين: منطقة أساسية ونظام ترفيهي في المقعد الخلفي. وبناءً على ذلك، سيتم تعريف car_audio_configuration.xml المحتمَل على النحو التالي:

<audioZoneConfiguration version="2.0">
       <zone name="primary zone" isPrimary="true">
           <volumeGroups>
               <group>
                   <device address="bus0_media_out">
                       <context context="music"/>
                       <context context="announcement"/>
                   </device>
                   <device address="bus3_call_ring_out">
                       <context context="call_ring"/>
                   </device>
                   <device address="bus6_notification_out">
                       <context context="notification"/>
                   </device>
                   <device address="bus7_system_sound_out">
                       <context context="system_sound"/>
                       <context context="emergency"/>
                       <context context="safety"/>
                       <context context="vehicle_status"/>
                   </device>
               </group>
               <group>
                   <device address="bus1_navigation_out">
                       <context context="navigation"/>
                   </device>
                   <device address="bus2_voice_command_out">
                       <context context="voice_command"/>
                   </device>
               </group>
               <group>
                   <device address="bus4_call_out">
                       <context context="call"/>
                   </device>
               </group>
               <group>
                   <device address="bus5_alarm_out">
                       <context context="alarm"/>
                   </device>
               </group>
           </volumeGroups>
       </zone>
        <zone name="rear seat zone" audioZoneId="1">
           <volumeGroups>
               <group>
                   <device address="bus100_rear_seat">
                       <context context="music"/>
                       <context context="navigation"/>
                       <context context="voice_command"/>
                       <context context="call_ring"/>
                       <context context="call"/>
                       <context context="alarm"/>
                       <context context="notification"/>
                       <context context="system_sound"/>
                       <context context="emergency"/>
                       <context context="safety"/>
                       <context context="vehicle_status"/>
                       <context context="announcement"/>
                   </device>
               </group>
           </volumeGroups>
    </zones>
</audioZoneConfiguration>

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

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

ضبط الصوت في منطقة الركاب

في الإصدار 11 من Android، تم توسيع نطاق car_audio_configuration.xml لإضافةaudioZoneId وoccupantZoneId. يمكن استخدام الرمز الأول، audioZoneId، للتحكّم بشكل أفضل في إدارة المناطق. من ناحية أخرى، يمكن استخدام occupantZoneId لضبط توجيه استنادًا إلى رقم تعريف المستخدم.

لاستخدام هذه الحقول الجديدة، يجب استخدام الإصدار 2 من car_audio_configuration.xml. عند مراجعة إعدادات الصوت أعلاه باستخدام الحقل الجديد لربط أرقام تعريف مناطق الركاب ومناطق الصوت، يمكن إعداد الإعدادات الجديدة بدون تعريفات مجموعات مستوى الصوت على النحو التالي:

<audioZoneConfiguration version="2.0">
       <zone name="primary zone" isPrimary="true" occupantZoneId="0">
         ...
       </zone>
       <zone name="rear seat zone" audioZoneId="1" occupantZoneId="1">
         ...
       </zone>
    </zones>
</audioZoneConfiguration>

يحدِّد الإعداد أعلاه تعيينًا للمنطقة الأساسية إلى منطقة الأشخاص 0، وaudioZoneId 1 إلى occupantZoneId 1. بشكل عام، يمكن ضبط أي تعيين بين منطقة الركاب ومنطقة الصوت، ولكن يجب أن يكون التعيين بين عنصرَين فقط. في ما يلي القواعد التي حدّدت الحقلَين الجديدَين:

  • تكون قيمة audioZoneId للمنطقة الأساسية دائمًا صفرًا.
  • لا يمكن تكرار الرقمَين audioZoneId وoccupantZoneId.
  • لا يمكن أن يتضمّن audioZoneId وoccupantZoneId سوى عملية تعيين واحدة لواحد

التوجيه من خلال المعرّف الفريد للتطبيق

تمّ تقديم سلسلة من واجهات برمجة التطبيقات المخفية في الإصدار 10 من CarAudioManager للسماح للتطبيقات بطلب معلومات عن مناطق الصوت والتركيز وضبطها.

int[] getAudioZoneIds();
int getZoneIdForUid(int uid);
boolean setZoneIdForUid(int zoneId, int uid);
boolean clearZoneIdForUid(int uid);

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

تغيير المناطق لأحد التطبيقات

يتم توجيه جميع الأصوات تلقائيًا إلى المنطقة الأساسية. لتعديل تطبيق لتوجيهه إلى منطقة مختلفة، استخدِم CarAudioManager#setZoneIdForUid:

// Find zone to play
int zoneId = ...

// Find application's uid
Int uid = mContext.getPackageManager()
        .getApplicationInfo(mContext.getPackageName(), 0)
        .uid;

if (mCarAudioManager.setZoneIdForUid(zoneId, info.uid)) {
    Log.d(TAG, "Zone successfully updated");
} else {
    Log.d(TAG, "Failed to change zone");
}

N ملاحظة: لا يمكن لميزة "البث" وميزة "التركيز" تبديل المناطق بشكل ديناميكي. لذلك، يجب إيقاف التشغيل وإعادة طلب التركيز لتغيير المناطق.

التوجيه باستخدام رقم تعريف المستخدِم

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

لا يزال بإمكانك استخدام التوجيه المستنِد إلى رقم تعريف فريد للتطبيقات، ولكن يجب إجراء ذلك بشكل مستقل عن توجيه رقم تعريف المستخدم. وهذا يعني أنّه في حال تحديد ربط بين منطقة الركاب ومنطقة الصوت في السيارة، سيتم إيقاف التوجيه المستنِد إلى المعرّف الفريد للجهاز، وستؤدي محاولة الاتصال بـ CarAudioManager#setZoneidForUid إلى ظهور خطأ.

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

التوجيه باستخدام setPreferredDevice

بالإضافة إلى التغييرات المذكورة أعلاه، يتضمّن Android 11 أيضًا واجهة برمجة تطبيقات جديدة لاستعلام أجهزة الإخراج المرتبطة بكل منطقة، وهي CarAudioManager#getOutputDeviceForUsage(int zoneId, int usage).

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

audioZoneId = ... ;
mediaDeviceInfo = mCarAudioManager
            .getOutputDeviceForUsage(audioZoneId, AudioAttributes.USAGE_MEDIA);
…
mPlayer.setPreferredDevice(mediaDeviceInfo);