निर्देशों को पूरा करना

इस पेज पर, आवाज़ से इंटरैक्ट करके कमांड पूरी करने का तरीका बताया गया है.

मीडिया से जुड़े निर्देश पूरे करना

मीडिया से जुड़ी कमांड को तीन अलग-अलग ग्रुप में बांटा जा सकता है:

  • बाहरी मीडिया सोर्स, जैसे कि AAOS में इंस्टॉल किया गया Spotify.
  • बैकएंड मीडिया सोर्स (जैसे, VIA के ज़रिए स्ट्रीम किया गया संगीत).
  • लोकल मीडिया सोर्स (जैसे, कार रेडियो).

बाहरी मीडिया सोर्स के निर्देशों को हैंडल करना

बाहरी मीडिया सोर्स, Android ऐप्लिकेशन के तौर पर तय किए जाते हैं. ये ऐप्लिकेशन, MediaSessionCompat और MediaBrowseCompat एपीआई के साथ काम करते हैं. इन एपीआई के इस्तेमाल के बारे में ज़्यादा जानकारी के लिए, कारों के लिए मीडिया ऐप्लिकेशन बनाना लेख पढ़ें.

अहम जानकारी: किसी असिस्टेंट ऐप्लिकेशन को सिस्टम में इंस्टॉल किए गए सभी मीडिया ऐप्लिकेशन के MediaBrowseService से कनेक्ट करने के लिए, यह ज़रूरी है कि:

  1. सिस्टम-साइन किए गए ऐप्लिकेशन के तौर पर इंस्टॉल किया गया हो. इसके लिए, AAOS के लिए मीडिया ऐप्लिकेशन डेवलपमेंट के दिशा-निर्देश और PackageValidator कोड का सैंपल देखें.
  2. उसके पास android.permission.MEDIA_CONTENT_CONTROL सिस्टम से जुड़ी खास अनुमति होनी चाहिए. इसके लिए, सिस्टम से जुड़ी खास अनुमतियां देना लेख पढ़ें.

AAOS में MediaBrowserCompat और MediaControllerCompat के अलावा, ये सुविधाएं भी मिलती हैं:

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

ध्यान दें कि मीडिया सोर्स को किसी भी समय इंस्टॉल या अनइंस्टॉल किया जा सकता है. सही सूची बनाए रखने के लिए, हमारा सुझाव है कि इंटेंट ऐक्शन ACTION_PACKAGE_ADDED, ACTION_PACKAGE_CHANGED, ACTION_PACKAGE_REPLACED, और ACTION_PACKAGE_REMOVED के लिए, BroadcastReceiver इंस्टेंस लागू करें.

फ़िलहाल चल रहे मीडिया सोर्स से कनेक्ट करना

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

    
}

लोकल मीडिया सोर्स (रेडियो, सीडी प्लेयर, ब्लूटूथ, यूएसबी) से जुड़े कमांड मैनेज करना

लोकल मीडिया सोर्स, सिस्टम को अपनी सुविधाओं के बारे में बताते हैं. इसके लिए, वे ऊपर बताए गए MediaSession और MediaBrowse API का इस्तेमाल करते हैं. हर तरह के हार्डवेयर की खास बातों को ध्यान में रखते हुए, MediaBrowse सेवाएं अपनी जानकारी और मीडिया कमांड को व्यवस्थित करने के लिए, खास नियमों का इस्तेमाल करती हैं.

रेडियो को मैनेज करना

Radio MediaBrowseService की पहचान, ACTION_PLAY_BROADCASTRADIO इंटेंट फ़िल्टर से की जा सकती है. उन्हें रेडियो लागू करना में बताए गए, मीडिया ब्राउज़ करने और प्लेबैक कंट्रोल के स्ट्रक्चर का पालन करना होगा. AAOS, car-broadcastradio-support लाइब्रेरी उपलब्ध कराता है. इसमें ऐसे कॉन्स्टेंट और तरीके शामिल होते हैं जिनकी मदद से ओईएम, रेडियो सेवाओं के लिए MediaBrowseService लागू कर सकते हैं. ये सेवाएं, तय किए गए प्रोटोकॉल का पालन करती हैं. साथ ही, यह उन ऐप्लिकेशन के लिए सहायता उपलब्ध कराता है जो ब्राउज़ ट्री का इस्तेमाल करते हैं. उदाहरण के लिए, वीआईए.

ऑक्ज़िलियरी इनपुट, सीडी ऑडियो, और यूएसबी मीडिया को मैनेज करना

AOSP में, इन मीडिया सोर्स को डिफ़ॉल्ट तौर पर लागू नहीं किया जाता. हमारा सुझाव है कि आप:

ब्लूटूथ को मैनेज करना

ब्लूटूथ मीडिया कॉन्टेंट, AVRCP ब्लूटूथ प्रोफ़ाइल के ज़रिए दिखाया जाता है. इस सुविधा को ऐक्सेस करने के लिए, AAOS में MediaBrowserService और MediaSession को लागू किया गया है. इससे कम्यूनिकेशन की जानकारी को अलग रखा जाता है (packages/apps/Bluetooth देखें).

मीडिया ब्राउज़र के ट्री स्ट्रक्चर को BrowseTree क्लास में तय किया जाता है. मीडिया सेशन लागू करने की सुविधा का इस्तेमाल करके, किसी भी अन्य ऐप्लिकेशन की तरह ही, वीडियो चलाने से जुड़े कंट्रोल के लिए निर्देश दिए जा सकते हैं.

स्ट्रीमिंग मीडिया से जुड़े निर्देशों को मैनेज करना

सर्वर साइड मीडिया स्ट्रीमिंग लागू करने के लिए, वीआईए को खुद मीडिया सोर्स बनना होगा. इसके लिए, उसे MediaBrowse और MediaSession API लागू करना होगा. कार के लिए मीडिया ऐप्लिकेशन बनाना लेख पढ़ें. इन एपीआई को लागू करने पर, आवाज़ से कंट्रोल करने वाला ऐप्लिकेशन ये काम कर पाएगा (इनके अलावा और भी काम कर पाएगा):

  • मीडिया सोर्स चुनने की प्रोसेस में आसानी से हिस्सा लेना
  • कार को रीस्टार्ट करने के बाद, अपने-आप फिर से शुरू हो जाए
  • Media Center के यूज़र इंटरफ़ेस (यूआई) का इस्तेमाल करके, प्लेबैक और ब्राउज़िंग कंट्रोल उपलब्ध कराना
  • हार्डवेयर के मीडिया बटन के स्टैंडर्ड इवेंट पाना

सभी नेविगेशन ऐप्लिकेशन के साथ इंटरैक्ट करने का कोई स्टैंडर्ड तरीका नहीं है. Google Maps के साथ इंटिग्रेशन के लिए, Android के लिए Google Maps इंटेंट देखें. अन्य ऐप्लिकेशन के साथ इंटिग्रेशन के लिए, सीधे तौर पर ऐप्लिकेशन के डेवलपर से संपर्क करें. Google Maps के साथ-साथ किसी भी ऐप्लिकेशन में इंटेंट लॉन्च करने से पहले, पुष्टि करें कि इंटेंट को हल किया जा सकता है. इसके लिए, Google Maps के इंटेंट देखें. इससे, उपयोगकर्ता को यह जानकारी देने का मौका मिलता है कि टारगेट ऐप्लिकेशन उपलब्ध नहीं है.

वाहन से जुड़ी कमांड पूरी करना

CarPropertyManager के ज़रिए, वाहन की प्रॉपर्टी को पढ़ने और लिखने, दोनों के लिए ऐक्सेस दिया जाता है. वाहन की प्रॉपर्टी के टाइप, उन्हें लागू करने का तरीका, और अन्य जानकारी प्रॉपर्टी कॉन्फ़िगरेशन में दी गई है. Android के साथ काम करने वाली प्रॉपर्टी के बारे में सटीक जानकारी पाने के लिए, सीधे hardware/interfaces/automotive/vehicle/2.0/types.hal देखें. वहां तय किए गए VehicleProperty enum में, स्टैंडर्ड और वेंडर के हिसाब से तय की गई प्रॉपर्टी, डेटा टाइप, बदलाव का मोड, यूनिट, और पढ़ने/लिखने के ऐक्सेस की परिभाषा, ये सभी शामिल होती हैं.

Java से इन कॉन्स्टेंट को ऐक्सेस करने के लिए, VehiclePropertyIds और इसकी कंपैनियन क्लास का इस्तेमाल किया जा सकता है. अलग-अलग प्रॉपर्टी के लिए, Android की अलग-अलग अनुमतियां होती हैं. इनसे उनके ऐक्सेस को कंट्रोल किया जाता है. इन अनुमतियों के बारे में CarService manifest में बताया गया है. साथ ही, प्रॉपर्टी और अनुमतियों के बीच मैपिंग के बारे में 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"));
    }

    …
}

कम्यूनिकेशन से जुड़ी कमांड पूरी करना

मैसेजिंग कमांड मैनेज करना

वीआईए को, वॉइस असिस्टेंट की 'टैप करके सुनें' सुविधा में बताए गए "टैप करके सुनें" फ़्लो के मुताबिक, आने वाले मैसेज मैनेज करने होंगे. वीआईए के पास, मैसेज भेजने वाले को जवाब भेजने का विकल्प भी होता है. इसके अलावा, वीआईए SmsManager (android.telephony पैकेज का हिस्सा) का इस्तेमाल करके, सीधे कार से या ब्लूटूथ के ज़रिए एसएमएस मैसेज लिख सकते हैं और भेज सकते हैं.

कॉल से जुड़े निर्देश मैनेज करना

इसी तरह, वीआईए, फ़ोन कॉल करने और उपयोगकर्ता के वॉइस मेल नंबर पर कॉल करने के लिए TelephonyManager का इस्तेमाल कर सकते हैं. इन मामलों में, वीआईए सीधे तौर पर टेलीफ़ोनी स्टैक या Car Dialer ऐप्लिकेशन के साथ इंटरैक्ट करेंगे. किसी भी मामले में, Car Dialer ऐप्लिकेशन को उपयोगकर्ता को वॉइस कॉल से जुड़ा यूज़र इंटरफ़ेस (यूआई) दिखाना चाहिए.

अन्य निर्देश पूरे करना

VIA और सिस्टम के बीच इंटिग्रेशन के अन्य संभावित पॉइंट की सूची के लिए, Android इंटेंट की जानी-मानी सूची देखें. उपयोगकर्ता की कई कमांड को सर्वर-साइड पर हल किया जा सकता है. उदाहरण के लिए, उपयोगकर्ताओं के ईमेल और कैलेंडर इवेंट पढ़ना. इसके लिए, सिस्टम के साथ किसी भी तरह के इंटरैक्शन की ज़रूरत नहीं होती.

इमर्सिव ऐक्शन (विज़ुअल कॉन्टेंट दिखाना)

अगर किसी वीआईए से उपयोगकर्ता की कार्रवाइयों या समझ को बेहतर बनाया जा सकता है, तो वह कार की स्क्रीन पर अतिरिक्त विज़ुअल कॉन्टेंट दिखा सकता है. ड्राइवर का ध्यान बंटने से बचाने के लिए, इस तरह के कॉन्टेंट को आसान, छोटा, और काम का रखें. इमर्सिव ऐक्शन के लिए, यूज़र इंटरफ़ेस (यूआई)/यूज़र एक्सपीरियंस (यूएक्स) से जुड़े दिशा-निर्देशों के बारे में जानने के लिए, पहले से लोड की गई असिस्टेंट: यूज़र एक्सपीरियंस से जुड़े दिशा-निर्देश देखें.

कस्टम स्टाइलिंग की सुविधा चालू करने और मुख्य यूनिट (एचयू) के बाकी डिज़ाइन के साथ एक जैसा अनुभव देने के लिए, वीआईए को ज़्यादातर यूआई एलिमेंट के लिए Car UI Library कॉम्पोनेंट का इस्तेमाल करना चाहिए. ज़्यादा जानकारी के लिए, पसंद के मुताबिक बनाना लेख पढ़ें.