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

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

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

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

  • बाहरी मीडिया सोर्स, जैसे कि AAOS में इंस्टॉल किया गया Spotify.
  • बैकएंड मीडिया सोर्स, जैसे कि वीआईए के ज़रिए स्ट्रीम किया गया संगीत.
  • स्थानीय मीडिया सोर्स, जैसे कि कार रेडियो.

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

बाहरी मीडिया सोर्स, 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;
}

ध्यान दें कि मीडिया सोर्स को कभी भी इंस्टॉल या अनइंस्टॉल किया जा सकता है. सही सूची बनाए रखने के लिए, 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;
    }

    
}

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

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

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

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

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

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

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

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

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

स्ट्रीमिंग मीडिया के कमांड मैनेज करना

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

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

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

वाहन के कमांड पूरे करना

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

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

    …
}

कम्यूनिकेशन के कमांड पूरे करना

मैसेज भेजने से जुड़े कमांड मैनेज करना

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

कॉल करने से जुड़े कमांड मैनेज करना

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

अन्य कमांड पूरे करना

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

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

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

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