توضّح هذه الصفحة كيفية تنفيذ الأوامر من خلال التفاعل الصوتي.
تنفيذ أوامر الوسائط
يمكن تقسيم الأوامر المتعلّقة بالوسائط إلى ثلاث مجموعات مختلفة:
- مصادر الوسائط الخارجية (مثل Spotify المثبَّت في نظام التشغيل AAOS)
- مصادر الوسائط في الخلفية (مثل الموسيقى التي يتم بثها من خلال VIA)
- مصادر الوسائط المحلية (مثل راديو السيارة)
معالجة أوامر مصدر الوسائط الخارجية
يتم تعريف مصادر الوسائط الخارجية على أنّها تطبيقات Android متوافقة مع واجهات برمجة التطبيقات MediaSessionCompat
وMediaBrowseCompat
(يُرجى الرجوع إلى مقالة إنشاء تطبيقات وسائط ل
السيارات للحصول على شرح مفصّل عن استخدام واجهات برمجة التطبيقات هذه).
ملاحظة مهمة: لكي يتمكّن تطبيق مساعد من الربط بواجهة برمجة التطبيقات
MediaBrowseService
لجميع تطبيقات الوسائط المثبَّتة في
النظام، يجب استيفاء الشروط التالية:
- أن يتم تثبيته كتطبيق موقَّع من النظام (راجِع إرشادات تطوير تطبيقات الوسائط لنظام التشغيل
AAOS ونموذج رمز
PackageValidator
) - الحصول على إذن
android.permission.MEDIA_CONTENT_CONTROL
الممنوح بموجب امتيازات النظام (راجِع منح أذونات بموجب امتيازات النظام)
بالإضافة إلى MediaBrowserCompat
وMediaControllerCompat
،
يقدّم AAOS ما يلي:
CarMediaService
يعرض معلومات مركزية حول مصدر الوسائط المحدّد حاليًا. ويُستخدَم هذا الإجراء أيضًا لاستئناف مصدر وسائط كان يتم تشغيله سابقًا بعد إيقاف السيارة وإعادة تشغيلها.- يوفّر
car-media-common
طرقًا ملائمة لعرض التطبيقات المشغّلة للوسائط والربط بها والتفاعل معها.
في ما يلي إرشادات خاصة بتنفيذ تعليمات التفاعل الصوتي الشائعة.
الحصول على قائمة بمصادر الوسائط المثبّتة
يمكن رصد مصادر الوسائط باستخدام PackageManager
،
والفلترة للخدمات التي تتطابق مع MediaBrowserService.SERVICE_INTERFACE
.
في بعض السيارات، قد تكون هناك بعض عمليات تنفيذ خدمة متصفّح الوسائط الخاصة،
التي يجب استبعادها. في ما يلي مثال على هذا المنطق:
private Map<String, MediaSource> getAvailableMediaSources() { List<String> customMediaServices = Arrays.asList(mContext.getResources() .getStringArray(R.array.custom_media_packages)); List<ResolveInfo> mediaServices = mPackageManager.queryIntentServices( new Intent(MediaBrowserService.SERVICE_INTERFACE), PackageManager.GET_RESOLVED_FILTER); Map<String, MediaSource> result = new HashMap<>(); for (ResolveInfo info : mediaServices) { String packageName = info.serviceInfo.packageName; if (customMediaServices.contains(packageName)) { // Custom media sources should be ignored, as they might have a // specialized handling (e.g., radio). continue; } String className = info.serviceInfo.name; ComponentName componentName = new ComponentName(packageName, className); MediaSource source = MediaSource.create(mContext, componentName); result.put(source.getDisplayName().toString().toLowerCase(), source); } return result; }
يُرجى العِلم أنّه يمكن تثبيت مصادر الوسائط أو إلغاء تثبيتها في أي وقت. للحفاظ على دقة القائمة، ننصحك بتنفيذ مثيل BroadcastReceiver
لإجراءات الأهداف ACTION_PACKAGE_ADDED
،
ACTION_PACKAGE_CHANGED
،
ACTION_PACKAGE_REPLACED
،
وACTION_PACKAGE_REMOVED
.
الربط بمصدر الوسائط الذي يتم تشغيله حاليًا
CarMediaService
يوفّر طرقًا للحصول على مصدر الوسائط المحدّد حاليًا، وعند تغيُّر مصدر الوسائط
هذا. يمكن أن تحدث هذه التغييرات بسبب تفاعل المستخدم مع
واجهة المستخدم مباشرةً أو بسبب استخدام الأزرار في السيارة. من ناحية أخرى، تقدّم مكتبة
car-media-common طرقًا ملائمة للاتصال بمصدر إعلام معين. في ما يلي مقتطف مبسط عن كيفية الربط بتطبيق الوسائط المحدّد حاليًا:
public class MediaActuator implements MediaBrowserConnector.onConnectedBrowserChanged { private final Car mCar; private CarMediaManager mCarMediaManager; private MediaBrowserConnector mBrowserConnector; … public void initialize(Context context) { mCar = Car.createCar(context); mBrowserConnector = new MediaBrowserConnector(context, this); mCarMediaManager = (CarMediaManager) mCar.getCarManager(Car.CAR_MEDIA_SERVICE); mBrowserConnector.connectTo(mCarMediaManager.getMediaSource()); … } @Override public void onConnectedBrowserChanged( @Nullable MediaBrowserCompat browser) { // TODO: Handle connected/disconnected browser } … }
التحكّم في تشغيل مصدر الوسائط الذي يتم تشغيله حاليًا
باستخدام MediaBrowserCompat
المرتبط، من السهل إرسال أوامر التحكّم في
النقل إلى التطبيق المستهدَف. في ما يلي مثال سهل للتوضيح:
public class MediaActuator … { … private MediaControllerCompat mMediaController; @Override public void onConnectedBrowserChanged( @Nullable MediaBrowserCompat browser) { if (browser != null && browser.isConnected()) { mMediaController = new MediaControllerCompat(mContext, browser.getSessionToken()); } else { mMediaController = null; } } private boolean playSongOnCurrentSource(String song) { if (mMediaController == null) { // No source selected. return false; } MediaControllerCompat.TransportControls controls = mMediaController.getTransportControls(); PlaybackStateCompat state = controller.getPlaybackState(); if (state == null || ((state.getActions() & PlaybackStateCompat.ACTION_PLAY_FROM_SEARCH) == 0)) { // Source can't play from search return false; } controls.playFromSearch(query, null); return true; } … }
معالجة أوامر مصادر الوسائط المحلية (الراديو ومشغل الأقراص المدمجة والبلوتوث وUSB)
توفّر مصادر الوسائط المحلية وظائفها للنظام باستخدام واجهتَي برمجة التطبيقات MediaSession وMediaBrowse نفسيهما الموضّحتَين أعلاه. لتلبية خصوصيات كل نوع من الأجهزة، تستخدم خدمات MediaBrowse هذه اصطلاحات محدّدة لتنظيم معلوماتها وأوامر الوسائط.
التعامل مع الراديو
يمكن التعرّف على Radio MediaBrowseService من خلال فلتر الغرض ACTION_PLAY_BROADCASTRADIO
. من المتوقّع أن يتّبع المطوّرون عناصر التحكّم في التشغيل وبنية تصفّح الوسائط описанة في مقالة تنفيذ البثّ الصوتي. يوفّر نظام التشغيل AAOS مكتبة car-broadcastradio-support
التي تحتوي على ثوابت وطُرق لمساعدة المصنّعين الأصليّين للأجهزة في إنشاء عمليات تنفيذ MediaBrowseService
لخدمات الراديو الخاصة بهم التي تتّبع البروتوكول المحدّد،
وتوفّر الدعم للتطبيقات التي تستخدِم شجرة التصفّح (مثل واجهات برمجة التطبيقات لتطبيقات الفيديو).
التعامل مع الإدخال الإضافي وصوت الأقراص المدمجة ووسائط USB
لا تتوفّر طريقة تلقائية لتنفيذ مصادر الوسائط هذه كجزء من AOSP. في ما يلي الخطوات المقترَحة:
- أن تطلب من المصنّعين الأصليّين للأجهزة تنفيذ خدمات الوسائط لكلّ جهاز لمعرفة التفاصيل، يُرجى الاطّلاع على مقالة إنشاء تطبيقات وسائط للسيارات.
- سيتم تحديد عمليات تنفيذ MediaBrowseService هذه والاستجابة لها في Intent actions المحدّدة في Intents العامة للتشغيل.
- ستعرض هذه الخدمات شجرة تصفّح وفقًا للإرشادات الموضّحة في أنواع المصادر الأخرى.
التعامل مع البلوتوث
يتم عرض محتوى الوسائط عبر البلوتوث من خلال ملف تعريف البلوتوث AVRCP. لأجل تسهيل الوصول إلى هذه الوظيفة، يتضمّن AAOS تنفيذًا لتطبيق MediaBrowserService وMediaSession يلخّص تفاصيل الاتّصال (راجِع packages/apps/Bluetooth).
يتم تحديد بنية شجرة متصفّح الوسائط ذات الصلة في فئة BrowseTree. يمكن إرسال أوامر التحكّم في التشغيل بالطريقة نفسها المتّبعة في أي تطبيق آخر، باستخدام عملية تنفيذ MediaSession.
معالجة أوامر بث الوسائط
لتنفيذ بث الوسائط من جهة الخادم، يجب أن يصبح VIA هو نفسه مصدر وسائط، من خلال تنفيذ MediaBrowse وMediaSession API. يُرجى الاطّلاع على مقالة إنشاء تطبيقات وسائط مناسبة للسيارات. من خلال تنفيذ واجهات برمجة التطبيقات هذه، سيتمكّن تطبيق التحكّم الصوتي من (من بين أمور أخرى):
- المشاركة بسلاسة في اختيار مصدر الوسائط
- استئناف البث تلقائيًا بعد إعادة تشغيل السيارة
- توفير عناصر تحكّم في التشغيل والتصفّح باستخدام واجهة مستخدم Media Center
- تلقّي أحداث زر تشغيل/إيقاف الوسائط العادية
تنفيذ أوامر التنقّل
لا تتوفّر طريقة موحّدة للتفاعل مع جميع تطبيقات التنقّل. بالنسبة إلى عمليات الدمج مع "خرائط Google"، اطّلِع على Google خرائط لطلبات Android Automotive. بالنسبة إلى عمليات الدمج مع التطبيقات الأخرى، يُرجى التواصل مع مطوّري التطبيقات مباشرةً. قبل بدء تنفيذ نية في أي تطبيق (بما في ذلك "خرائط Google")، تأكَّد من أنّه يمكن حلّ النية (راجِع طلبات النية). يتيح لك ذلك إعلام المستخدم في حال عدم توفّر التطبيق المستهدف.
تنفيذ أوامر المركبات
يتم توفير إمكانية الوصول إلى سمات المركبات للقراءة والكتابة من خلال
CarPropertyManager.
يتم شرح أنواع سمات المركبات وتنفيذها وتفاصيل أخرى
في إعدادات
السمات. للحصول على وصف دقيق للمواقع التي يتوافق معها Android، من الأفضل الرجوع مباشرةً إلى hardware/interfaces/automotive/vehicle/2.0/types.hal
.
يحتوي التعداد VehicleProperty
المحدّد هناك على كل من السمات العادية والسمات الخاصة بالمورّد، وأنواع
البيانات، ووضع التغيير، والوحدات، وتعريف الوصول للقراءة/الكتابة.
للوصول إلى هذه الثوابت نفسها من Java، يمكنك استخدام VehiclePropertyIds والفئات المصاحبة لها. تمتلك المواقع المختلفة أذونات Android مختلفة تتحكّم في إمكانية الوصول إليها. يتمّ الإعلان عن هذه الأذونات في ملف بيان CarService، كما يتمّ وصف عملية الربط بين السمات والأذونات في VehiclePropertyIds Javadoc ويتمّ فرضها في PropertyHalServiceIds.
قراءة سمة مركبة
في ما يلي مثال يوضّح كيفية قراءة سرعة المركبة:
public class CarActuator ... { private final Car mCar; private final CarPropertyManager mCarPropertyManager; private final TextToSpeech mTTS; /** Global VHAL area id */ public static final int GLOBAL_AREA_ID = 0; public CarActuator(Context context, TextToSpeech tts) { mCar = Car.createCar(context); mCarPropertyManager = (CarPropertyManager) mCar.getCarManager(Car.PROPERTY_SERVICE); mTTS = tts; ... } @Nullable private void getSpeedInMetersPerSecond() { if (!mCarPropertyManager.isPropertyAvailable(VehiclePropertyIds.PERF_VEHICLE_SPEED, GLOBAL_AREA_ID)) { mTTS.speak("I'm sorry, but I can't read the speed of this vehicle"); return; } // Data type and unit can be found in // automotive/vehicle/2.0/types.hal float speedInMps = mCarPropertyManager.getFloatProperty( VehiclePropertyIds.PERF_VEHICLE_SPEED, GLOBAL_AREA_ID); int speedInMph = (int)(speedInMetersPerSecond * 2.23694f); mTTS.speak(String.format("Sure. Your current speed is %d miles " + "per hour", speedInUserUnit); } ... }
ضبط سمة مركبة
في ما يلي مثال يوضّح كيفية تشغيل مكيّف الهواء الأمامي وإيقافه.
public class CarActuator … { … private void changeFrontAC(boolean turnOn) { List<CarPropertyConfig> configs = mCarPropertyManager .getPropertyList(new ArraySet<>(Arrays.asList( VehiclePropertyIds.HVAC_AC_ON))); if (configs == null || configs.size() != 1) { mTTS.speak("I'm sorry, but I can't control the AC of your vehicle"); return; } // Find the front area Ids for the AC property. int[] areaIds = configs.get(0).getAreaIds(); List<Integer> areasToChange = new ArrayList<>(); for (int areaId : areaIds) { if ((areaId & (VehicleAreaSeat.SEAT_ROW_1_CENTER | VehicleAreaSeat.SEAT_ROW_1_LEFT | VehicleAreaSeat.SEAT_ROW_1_RIGHT)) == 0) { continue; } boolean isACInAreaAlreadyOn = mCarPropertyManager .getBooleanProperty(VehiclePropertyIds.HVAC_AC_ON, areaId); if ((!isACInAreaAlreadyOn && turnOn) || (isACInAreaAlreadyOn && !turnOn)) { areasToChange.add(areaId); } } if (areasToChange.isEmpty()) { mTTS.speak(String.format("The AC is already %s", turnOn ? "on" : "off")); return; } for (int areaId : areasToChange) { mCarPropertyManager.setBooleanProperty( VehiclePropertyIds.HVAC_AC_ON, areaId, turnOn); } mTTS.speak(String.format("Okay, I'm turning your front AC %s", turnOn ? "on" : "off")); } … }
تنفيذ أوامر التواصل
معالجة أوامر المراسلة
يجب أن تعالج واجهات برمجة التطبيقات للرسائل الواردة عملية "النقر للقراءة" الموضّحة
في مساعد Google
النقر للقراءة، والتي يمكنها اختياريًا معالجة إرسال الردود إلى مُرسِل الرسالة الواردة.
بالإضافة إلى ذلك، يمكن لتطبيقات VIA استخدام SmsManager
(جزء من حزمة android.telephony
) لإنشاء رسائل SMS وإرسالها مباشرةً من السيارة أو عبر البلوتوث.
معالجة أوامر المكالمات
وبالطريقة نفسها، يمكن لتطبيقات معالجة التفاعلات مع العملاء استخدام TelephonyManager
لإجراء مكالمات هاتفية والاتصال برقم البريد الصوتي الخاص بالمستخدم. في هذه الحالات، سيتفاعل
معرّفات VIA مع حِزمة خدمات الهاتف مباشرةً أو مع تطبيق "محرّك الاتصال بالسيارة"
. وفي جميع الأحوال، يجب أن يكون تطبيق "محرّك الاتصال بالسيارة" هو الذي يعرض
واجهة المستخدم ذات الصلة بالمكالمات الصوتية للمستخدم.
تنفيذ أوامر أخرى
للحصول على قائمة بنقاط الدمج الأخرى المحتملة بين VIA و النظام، اطّلِع على قائمة أهداف Android المعروفة. يمكن حلّ العديد من طلبات المستخدِم من جهة الخادم (على سبيل المثال، قراءة الرسائل الإلكترونية للمستخدمين وأحداث التقويم) ولا تتطلّب أي تفاعلات مع النظام سوى التفاعل الصوتي نفسه.
الإجراءات الشاملة (عرض محتوى مرئي)
يمكن أن يوفّر تطبيق VIA محتوًى مرئيًا إضافيًا على شاشة السيارة عندما يُحسِّن ذلك من إجراءات المستخدم أو فهمه. للحدّ من تشتيت انتباه السائق، يجب أن يكون هذا المحتوى بسيطًا وموجزًا وقابلاً للتنفيذ. لمعرفة التفاصيل حول إرشادات واجهة المستخدم/تجربة المستخدم المتعلّقة بالإجراءات الشاملة، يُرجى الاطّلاع على مقالة المساعدون المُحمَّلون مُسبَقًا: إرشادات حول تجربة المستخدم.
لتفعيل إمكانية التخصيص والتوافق مع باقي تصميم الوحدة الرئيسية (HU)، يجب أن تستخدم واجهة المستخدم في السيارة (VIA) مكونات مكتبة واجهة المستخدم في السيارة لمعظم عناصر واجهة المستخدم. لمعرفة التفاصيل، يُرجى الاطّلاع على التخصيص.