دستورات را انجام دهید

این صفحه نحوه انجام دستورات با تعامل صوتی را شرح می دهد.

دستورات رسانه را انجام دهید

دستورات مربوط به رسانه را می توان به سه گروه مختلف تقسیم کرد:

  • منابع رسانه ای خارجی (مانند Spotify نصب شده در AAOS).
  • منابع رسانه پشتیبان (مانند موسیقی پخش شده از طریق VIA).
  • منابع رسانه ای محلی (مانند رادیو ماشین).

کنترل دستورات منبع رسانه خارجی

منابع رسانه خارجی به عنوان برنامه‌های اندرویدی تعریف می‌شوند که از MediaSessionCompat و MediaBrowseCompat APIها پشتیبانی می‌کنند (برای توضیح دقیق در مورد استفاده از این APIها به ساخت برنامه‌های رسانه برای اتومبیل‌ها مراجعه کنید).

مهم: برای اینکه یک برنامه دستیار به MediaBrowseService همه برنامه های رسانه نصب شده در سیستم متصل شود، باید:

  1. به صورت امضا شده توسط سیستم نصب شود (به دستورالعمل های توسعه برنامه رسانه برای AAOS و کد نمونه PackageValidator مراجعه کنید).
  2. 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 APIهای ذکر شده در بالا در معرض سیستم قرار می دهند. برای تطبیق ویژگی‌های هر نوع سخت‌افزار، این سرویس‌های MediaBrowse از قراردادهای خاصی برای سازماندهی اطلاعات و دستورات رسانه‌ای خود استفاده می‌کنند.

دسته رادیو

Radio MediaBrowseService را می توان با فیلتر هدف ACTION_PLAY_BROADCASTRADIO شناسایی کرد. انتظار می رود که آنها از کنترل های پخش و ساختار مرور رسانه ای که در رادیو پیاده سازی توضیح داده شده است پیروی کنند. AAOS کتابخانه car-broadcastradio-support شامل ثابت‌ها و روش‌هایی برای کمک به OEMها برای ایجاد پیاده‌سازی MediaBrowseService برای سرویس‌های رادیویی خود که از پروتکل تعریف‌شده پیروی می‌کنند، ارائه می‌دهد و برای برنامه‌هایی که درخت مرور آن‌ها را مصرف می‌کنند (به عنوان مثال، VIA) پشتیبانی می‌کند.

ورودی کمکی، صدای CD و رسانه USB را کنترل کنید

هیچ پیاده سازی پیش فرضی از این منابع رسانه ای به عنوان بخشی از AOSP وجود ندارد. رویکرد پیشنهادی این است که:

بلوتوث را کنترل کنید

محتوای رسانه بلوتوث از طریق نمایه بلوتوث AVRCP در معرض دید قرار می گیرد. به منظور تسهیل دسترسی به این قابلیت، AAOS شامل MediaBrowserService و اجرای MediaSession است که جزئیات ارتباط را خلاصه می کند (به بسته ها/برنامه ها/بلوتوث مراجعه کنید).

ساختار درختی مرورگر رسانه مربوطه در کلاس BrowseTree تعریف شده است. با استفاده از اجرای MediaSession، دستورات کنترل پخش را می توان به طور مشابه به هر برنامه دیگری تحویل داد.

کنترل دستورات رسانه جریان

برای اجرای جریان رسانه سمت سرور، VIA باید خود به یک منبع رسانه تبدیل شود و MediaBrowse و MediaSession API را پیاده سازی کند. به ساخت برنامه های رسانه ای برای اتومبیل ها مراجعه کنید. با پیاده‌سازی این APIها، یک برنامه کنترل صدا می‌تواند (از جمله موارد زیر):

  • یکپارچه در انتخاب منبع رسانه شرکت کنید
  • پس از راه اندازی مجدد خودرو به طور خودکار از سر گرفته شود
  • با استفاده از Media Center UI کنترل پخش و مرور را ارائه دهید
  • رویدادهای دکمه رسانه سخت افزاری استاندارد را دریافت کنید

هیچ روش استاندارد شده ای برای تعامل با همه برنامه های ناوبری وجود ندارد. برای ادغام با Google Maps، به Google Maps for Android Automotive Intents مراجعه کنید. برای ادغام با سایر برنامه ها، مستقیماً با توسعه دهندگان برنامه تماس بگیرید. قبل از راه‌اندازی یک intent برای هر برنامه (از جمله Google Maps)، بررسی کنید که این هدف قابل حل است (به درخواست‌های Intent مراجعه کنید). این فرصت را ایجاد می کند تا در صورت در دسترس نبودن برنامه مورد نظر، کاربر را مطلع کند.

دستورات خودرو را انجام دهید

دسترسی به ویژگی های خودرو برای خواندن و نوشتن از طریق CarPropertyManager فراهم می شود. انواع ویژگی های خودرو، پیاده سازی آن و سایر جزئیات در تنظیمات Property توضیح داده شده است. برای توصیف دقیق ویژگی های پشتیبانی شده توسط Android، بهتر است مستقیماً به hardware/interfaces/automotive/vehicle/2.0/types.hal مراجعه کنید. شماره VehicleProperty که در آنجا تعریف شده است شامل ویژگی‌های خاص استاندارد و فروشنده، انواع داده، حالت تغییر، واحدها و تعریف دسترسی خواندن/نوشتن است.

برای دسترسی به همین ثابت ها از جاوا، می توانید از 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);
    }

    ...
}

یک ویژگی وسیله نقلیه را تنظیم کنید

مثال زیر نحوه روشن و خاموش کردن AC جلو را نشان می دهد.

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ها باید پیام‌های دریافتی را به دنبال جریان «ضربه برای خواندن» شرح داده شده در دستیار صوتی Tap-to-Read کنترل کنند، که می‌تواند به صورت اختیاری پاسخ‌ها را به فرستنده پیام دریافتی ارسال کند. علاوه بر این، VIA ها می توانند از SmsManager (بخشی از بسته android.telephony ) برای نوشتن و ارسال پیام های SMS به طور مستقیم از ماشین یا از طریق بلوتوث استفاده کنند.

کنترل دستورات تماس

به روشی مشابه، VIA ها می توانند از TelephonyManager برای برقراری تماس های تلفنی و تماس با شماره پست صوتی کاربر استفاده کنند. در این موارد، VIA ها مستقیماً با پشته تلفن یا با برنامه Car Dialer تعامل خواهند داشت. در هر صورت، برنامه Car Dialer باید رابط کاربری مربوط به تماس صوتی را به کاربر نمایش دهد.

دستورات دیگر را انجام دهید

برای لیستی از سایر نقاط ممکن ادغام بین VIA و سیستم، فهرست اهداف معروف Android را بررسی کنید. بسیاری از دستورات کاربر را می توان در سمت سرور حل کرد (به عنوان مثال، خواندن ایمیل های کاربران و رویدادهای تقویم) و به هیچ گونه تعاملی با سیستم به غیر از خود تعامل صوتی نیاز ندارند.

اقدامات فراگیر (نمایش محتوای بصری)

در جایی که اقدامات یا درک کاربر را افزایش می‌دهد، VIA می‌تواند محتوای بصری تکمیلی را روی صفحه ماشین ارائه دهد. برای به حداقل رساندن حواس پرتی راننده، چنین محتوایی را ساده، مختصر و قابل اجرا نگه دارید. برای جزئیات بیشتر درباره دستورالعمل‌های UI/UX در مورد اقدامات همهجانبه، به دستیاران از پیش بارگذاری شده: راهنمای UX مراجعه کنید.

برای فعال کردن سفارشی‌سازی و سازگاری با بقیه طراحی واحد اصلی (HU)، VIAها باید از مؤلفه‌های Car UI Library برای بیشتر عناصر UI استفاده کنند. برای جزئیات، به سفارشی سازی مراجعه کنید.