تنفيذ الأوامر

توضّح هذه الصفحة كيفية تنفيذ الأوامر من خلال التفاعل الصوتي.

تنفيذ أوامر الوسائط

يمكن تقسيم الأمر المرتبط بالوسائط إلى ثلاث مجموعات مختلفة:

  • مصادر الوسائط الخارجية (مثل Spotify المثبّت في AAOS)
  • مصادر وسائط الخلفية (مثل الموسيقى التي يتم بثها من خلال VIA)
  • مصادر الوسائط المحلية (مثل راديو السيارات)

التعامل مع أوامر مصدر الوسائط الخارجية

مصادر الوسائط الخارجية هي تطبيقات Android متوافقة مع MediaSessionCompat. وMediaBrowseCompat واجهات برمجة التطبيقات (راجع إنشاء تطبيقات وسائط لـ السيارات للحصول على شرح تفصيلي حول استخدام واجهات برمجة التطبيقات هذه).

ملاحظة مهمة: لربط تطبيق المساعد MediaBrowseService من إجمالي تطبيقات الوسائط المثبّتة في ، فيجب أن:

  1. أن يتم تثبيته كتطبيق موقَّع من النظام (يُرجى الاطّلاع على إرشادات تطوير تطبيقات الوسائط) AAOS ونموذج رمز PackageValidator).
  2. تثبيت الجهاز الذي يتمتع بامتيازات النظام لـ android.permission.MEDIA_CONTENT_CONTROL (راجع منح الأذونات المميزة للنظام).

بالإضافة إلى MediaBrowserCompat وMediaControllerCompat، يوفّر نظام التشغيل Android Automotive ما يلي:

  • 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 مثال لإجراءات intent ACTION_PACKAGE_ADDED ACTION_PACKAGE_CHANGED, ACTION_PACKAGE_REPLACED، وACTION_PACKAGE_REMOVED.

الاتصال بمصدر الوسائط قيد التشغيل حاليًا

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

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;
    }

    …
}

التعامل مع أوامر مصادر الوسائط المحلية (الراديو ومشغّل CD والبلوتوث وUSB)

تعرض مصادر الوسائط المحلية وظائفها للنظام باستخدام واجهات برمجة التطبيقات MediaSession وMediaBrowse الموضحة أعلاه. لاستيعاب خصوصيات لكل نوع من الأجهزة، تستخدم خدمات MediaBrowse هذه اصطلاحات معينة لتنظيم أوامر المعلومات والوسائط.

التعامل مع الراديو

يمكن تحديد Radio MediaBrowseService بواسطة ACTION_PLAY_BROADCASTRADIO فلتر الأهداف. من المتوقع أن يتّبعوا عناصر التحكّم في التشغيل وتصفّح الوسائط. البنية الموضحة في تنفيذ الراديو. يوفر نظام التشغيل Android Automotive car-broadcastradio-support مكتبة تحتوي على ثوابت وطرق لمساعدة المصنّعين الأصليين للأجهزة في إنشاء MediaBrowseService وعمليات التنفيذ لخدمات الراديو الخاصة بهم والتي تتبع البروتوكول المحدّد، ويدعم التطبيقات التي تستهلك شجرة التصفّح (على سبيل المثال، VIA).

التعامل مع الإدخال المساعد وصوت القرص المضغوط ووسائط USB

لا يتوفّر تنفيذ تلقائي لمصادر الوسائط هذه كجزء من عملية AOSP. النهج المقترح هو:

التعامل مع البلوتوث

يتم عرض محتوى وسائط البلوتوث من خلال ملف تعريف البلوتوث بتقنية AVRCP. ضِمن لتسهيل الوصول إلى هذه الوظيفة، يشمل نظام AAOS تنفيذ MediaBrowserService وMediaSession يستخلص من تفاصيل الاتصال (يمكنك الاطّلاع على الحزم/apps/البلوتوث).

يتم تحديد بنية شجرة متصفّح الوسائط المعنيّة في BrowseTree الصف. يمكن تسليم أوامر التحكم في التشغيل بشكل مشابه لأي تطبيق آخر، من خلال تنفيذ MediaSession.

التعامل مع طلبات وسائط البث

لتنفيذ بث الوسائط من جهة الخادم، يجب أن يتم تفعيل VIA نفسها. مصدر وسائط، مع تنفيذ MediaBrowse وMediaSession API. ارجع إلى إنشاء تطبيقات الموسيقى للسيارات. ومن خلال تنفيذ واجهات برمجة التطبيقات هذه، سيتمكن تطبيق التحكم الصوتي من إجراء ما يلي: (من بين أمور أخرى):

  • المشاركة بسلاسة في اختيار مصدر الوسائط
  • سيتم استئنافها تلقائيًا بعد إعادة تشغيل السيارة.
  • توفير إمكانية التحكّم في التشغيل والتصفّح باستخدام واجهة مستخدم Media Center
  • تلقّي أحداث أزرار وسائط الجهاز العادية

ما مِن طريقة موحّدة للتفاعل مع جميع تطبيقات التنقّل. لعمليات الدمج مع "خرائط Google"، اطّلِع على 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"));
    }

    …
}

تنفيذ أوامر الاتصال

التعامل مع طلبات المراسلة

يجب أن تتعامل VIA مع الرسائل الواردة بعد "النقر للقراءة" التدفق الموصوف في المساعد الصوتي النقر للقراءة، الذي يمكنه اختياريًا معالجة إرسال الردود إلى مُرسِل الرسائل الواردة. بالإضافة إلى ذلك، يمكن لـ VIA استخدام SmsManager (جزء من android.telephony (حزمة) لإنشاء رسائل SMS وإرسالها مباشرةً من السيارة أو عبر البلوتوث.

التعامل مع طلبات المكالمات

بطريقة مماثلة، يمكن لـ VIA استخدام TelephonyManager لإجراء مكالمات هاتفية والاتصال برقم البريد الصوتي للمستخدم. في هذه الحالات، ستتفاعل VIA مع حزمة الاتصالات الهاتفية مباشرةً أو مع Car Dialer التطبيق. على أي حال، يجب أن يكون تطبيق Car Dialer هو التطبيق الذي يعرض واجهة المستخدم المتعلقة بالمكالمة الصوتية للمستخدم.

تنفيذ الطلبات الأخرى

للحصول على قائمة بنقاط التكامل المحتملة الأخرى بين VIA راجع قائمة أهداف Android المعروفة. نتائج عديدة ويمكن حل أوامر المستخدم من جانب الخادم (على سبيل المثال، قراءة رسائل البريد الإلكتروني وأحداث التقويم للمستخدمين) ولا تتطلب أي تفاعلات مع النظام بخلاف التفاعل الصوتي نفسه

الإجراءات الشاملة (عرض محتوى مرئي)

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

لتمكين التخصيص والاتساق مع باقي تصميم الوحدة الرئيسية (HU)، وينبغي أن تستخدم VIA سيارة مكونات مكتبة واجهة المستخدم لمعظم عناصر واجهة المستخدم. للحصول على التفاصيل، يمكنك مراجعة التخصيص: