ब्लूटूथ

एंड्रॉइड कई सामान्य इन-कार ब्लूटूथ प्रोफाइल के समर्थन के साथ पूर्ण ब्लूटूथ कार्यान्वयन प्रदान करता है। ऐसे कई संवर्द्धन भी हैं जो अन्य उपकरणों और सेवाओं के साथ प्रदर्शन और अनुभव को बेहतर बनाते हैं।

ब्लूटूथ कनेक्शन प्रबंधन

एंड्रॉइड के भीतर, CarBluetoothService वर्तमान उपयोगकर्ता के ब्लूटूथ डिवाइस और IVI के प्रत्येक प्रोफ़ाइल कनेक्शन के लिए प्राथमिकता सूची बनाए रखता है। डिवाइस एक परिभाषित प्राथमिकता क्रम में प्रोफाइल से जुड़े हुए हैं। किसी प्रोफ़ाइल में डिवाइस को कब सक्षम, अक्षम और कनेक्ट करना एक डिफ़ॉल्ट कनेक्शन नीति द्वारा संचालित होता है जिसे यदि वांछित हो तो संसाधन ओवरले के उपयोग से ओवरराइड किया जा सकता है।

ऑटोमोटिव कनेक्शन प्रबंधन कॉन्फ़िगर करें

डिफ़ॉल्ट फ़ोन नीति अक्षम करें

एंड्रॉइड ब्लूटूथ स्टैक उन फ़ोनों के लिए एक कनेक्शन नीति बनाए रखता है जो डिफ़ॉल्ट रूप से सक्षम होती है। यह नीति आपके डिवाइस पर अक्षम होनी चाहिए ताकि यह CarBluetoothService में इच्छित ऑटोमोटिव नीति के साथ विरोध न करे। जबकि कार उत्पाद ओवरले को आपके लिए इसका ध्यान रखना चाहिए, आप /packages/apps/Bluetooth/res/values/config.xml में MAXIMUM_CONNECTED_DEVICES में enable_phone_policy को false पर सेट करके संसाधन ओवरले में फ़ोन नीति को अक्षम कर सकते हैं।

डिफ़ॉल्ट ऑटोमोटिव नीति का उपयोग करें

CarBluetoothService डिफ़ॉल्ट प्रोफ़ाइल अनुमतियाँ बनाए रखता है। ज्ञात उपकरणों और उनकी प्रोफ़ाइल पुनः कनेक्शन प्राथमिकताओं की सूची service/src/com/android/car/BluetoothProfileDeviceManager.java में है।

साथ ही, ब्लूटूथ कनेक्शन प्रबंधन नीति service/src/com/android/car/BluetoothDeviceConnectionPolicy.java में पाई जा सकती है। डिफ़ॉल्ट रूप से, यह नीति उन उदाहरणों को परिभाषित करती है जब ब्लूटूथ को कनेक्टेड डिवाइस से कनेक्ट और डिस्कनेक्ट करना चाहिए। यह कार-विशिष्ट मामलों का भी प्रबंधन करता है कि एडॉप्टर को कब चालू और बंद किया जाना चाहिए।

अपनी स्वयं की कस्टम ऑटोमोटिव कनेक्शन प्रबंधन नीति बनाएं

यदि डिफ़ॉल्ट ऑटोमोटिव पॉलिसी आपकी आवश्यकताओं के लिए पर्याप्त नहीं है, तो इसे आपकी अपनी कस्टम पॉलिसी के पक्ष में अक्षम भी किया जा सकता है। आपकी कस्टम नीति, कम से कम, यह निर्धारित करने के लिए ज़िम्मेदार है कि ब्लूटूथ एडाप्टर को कब सक्षम और अक्षम करना है, साथ ही डिवाइस को कब कनेक्ट करना है। ब्लूटूथ एडाप्टर को सक्षम/अक्षम करने और डिवाइस कनेक्शन शुरू करने के लिए विभिन्न प्रकार की घटनाओं का उपयोग करना संभव है, जिसमें विशिष्ट कार गुणों में परिवर्तन के कारण होने वाली घटनाएं भी शामिल हैं।

डिफ़ॉल्ट ऑटोमोटिव नीति अक्षम करें

सबसे पहले, एक कस्टम नीति का उपयोग करने के लिए, संसाधन ओवरले में useDefaultBluetoothConnectionPolicy को false पर सेट करके डिफ़ॉल्ट ऑटोमोटिव नीति को अक्षम किया जाना चाहिए। इस संसाधन को मूल रूप से packages/services/Car/service/res/values/config.xml में MAXIMUM_CONNECTED_DEVICES के भाग के रूप में परिभाषित किया गया है।

ब्लूटूथ एडाप्टर को सक्षम और अक्षम करें

आपकी नीति का एक मुख्य कार्य ब्लूटूथ एडाप्टर को उचित समय पर चालू और बंद करना है। आप एडॉप्टर को सक्षम और अक्षम करने के लिए BluetoothAdapter.enable() और BluetoothAdapter.disable() फ्रेमवर्क API का उपयोग कर सकते हैं। इन कॉलों को उपयोगकर्ता द्वारा सेटिंग्स या किसी अन्य माध्यम से चुनी गई निरंतर स्थिति का सम्मान करना चाहिए। ऐसा करने का एक तरीका इस प्रकार है:

/**
 * Turn on the Bluetooth adapter.
 */
private void enableBluetooth() {
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (bluetoothAdapter == null) {
        return;
    }
    bluetoothAdapter.enable();
}

/**
 * Turn off the Bluetooth adapter.
 */
private void disableBluetooth() {
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (bluetoothAdapter == null) {
        return;
    }
    // Will shut down _without_ persisting the off state as the desired state
    // of the Bluetooth adapter for next start up. This does nothing if the adapter
    // is already off, keeping the existing saved desired state for next reboot.
    bluetoothAdapter.disable(false);
}

निर्धारित करें कि ब्लूटूथ एडाप्टर को कब चालू और बंद करना है

अपनी कस्टम नीति के साथ आप यह निर्धारित करने के लिए स्वतंत्र हैं कि कौन सी घटनाएँ एडॉप्टर को सक्षम और अक्षम करने के लिए सर्वोत्तम समय का संकेत देती हैं। ऐसा करने का एक तरीका CarPowerManager में पावर स्थिति MAXIMUM_CONNECTED_DEVICES का उपयोग करना है:

private final CarPowerStateListenerWithCompletion mCarPowerStateListener =
        new CarPowerStateListenerWithCompletion() {
    @Override
    public void onStateChanged(int state, CompletableFuture<Void> future) {
        if (state == CarPowerManager.CarPowerStateListener.ON) {
            if (isBluetoothPersistedOn()) {
                enableBluetooth();
            }
            return;
        }

        // "Shutdown Prepare" is when the user perceives the car as off
        // This is a good time to turn off Bluetooth
        if (state == CarPowerManager.CarPowerStateListener.SHUTDOWN_PREPARE) {
            disableBluetooth();

            // Let CarPowerManagerService know we're ready to shut down
            if (future != null) {
                future.complete(null);
            }
            return;
        }
    }
};

निर्धारित करें कि डिवाइस कब कनेक्ट करना है

इसी प्रकार, जब आप उन घटनाओं को निर्धारित करते हैं जो डिवाइस कनेक्शन को शुरू करने के लिए ट्रिगर करना चाहिए, तो CarBluetoothManager connectDevices() एपीआई कॉल प्रदान करता है जो प्रत्येक ब्लूटूथ प्रोफ़ाइल के लिए परिभाषित प्राथमिकता सूचियों के आधार पर डिवाइस कनेक्ट करने के लिए आगे बढ़ता है।

आप ऐसा कब करना चाहेंगे इसका एक उदाहरण यह है कि जब भी ब्लूटूथ एडाप्टर चालू होता है:

private class BluetoothBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
            if (state == BluetoothAdapter.STATE_ON) {
                // mContext should be your app's context
                Car car = Car.createCar(mContext);
                CarBluetoothManager carBluetoothManager =
                        (CarBluetoothManager) car.getCarManager(Car.BLUETOOTH_SERVICE);
                carBluetoothManager.connectDevices();
            }
        }
    }
}

ऑटोमोटिव कनेक्शन प्रबंधन सत्यापित करें

अपनी कनेक्शन नीति के व्यवहार को सत्यापित करने का सबसे आसान तरीका अपने आईवीआई पर ब्लूटूथ को सक्षम करना और सत्यापित करना है कि यह स्वचालित रूप से उचित क्रम में सही डिवाइस से कनेक्ट होता है। आप सेटिंग्स यूआई के माध्यम से, या निम्नलिखित एडीबी कमांड के साथ ब्लूटूथ एडाप्टर को टॉगल कर सकते हैं:

adb shell su u$(adb shell am get-current-user)_system svc bluetooth disable
adb shell su u$(adb shell am get-current-user)_system svc bluetooth enable

इसके अलावा, ब्लूटूथ कनेक्शन से संबंधित डिबग जानकारी देखने के लिए निम्न कमांड के आउटपुट का उपयोग किया जा सकता है:

adb shell dumpsys car_service

अंत में, यदि आपने अपनी स्वयं की ऑटोमोटिव नीति बनाई है, तो किसी भी कस्टम कनेक्शन व्यवहार को सत्यापित करने के लिए उन घटनाओं को नियंत्रित करने की आवश्यकता होती है जिन्हें आपने डिवाइस कनेक्शन को ट्रिगर करने के लिए चुना है।

ऑटोमोटिव ब्लूटूथ प्रोफाइल

एंड्रॉइड में, IVI ब्लूटूथ पर एक साथ जुड़े कई उपकरणों का समर्थन कर सकता है। मल्टी-डिवाइस ब्लूटूथ फ़ोन सेवाएँ उपयोगकर्ताओं को व्यक्तिगत फ़ोन और कार्य फ़ोन जैसे अलग-अलग डिवाइस को एक साथ कनेक्ट करने देती हैं, और किसी भी डिवाइस से हैंड्स-फ़्री कॉल करने देती हैं।

कनेक्शन सीमाएँ प्रत्येक व्यक्तिगत ब्लूटूथ प्रोफ़ाइल द्वारा लागू की जाती हैं, आमतौर पर प्रोफ़ाइल सेवा के कार्यान्वयन के भीतर ही। डिफ़ॉल्ट रूप से, CarBluetoothService अनुमत कनेक्टेड डिवाइसों की अधिकतम संख्या पर कोई निर्णय नहीं लेता है।

हैंड्स-फ़्री प्रोफ़ाइल

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

IVI HFP के माध्यम से कई उपकरणों से जुड़ सकता है। HeadsetClientService में MAX_STATE_MACHINES_POSSIBLE MAXIMUM_CONNECTED_DEVICES एक साथ HFP कनेक्शन की अधिकतम संख्या को परिभाषित करता है।

जब कोई उपयोगकर्ता किसी डिवाइस से फ़ोन कॉल करता है या प्राप्त करता है, तो संबंधित फ़ोन खाता एक HfpClientConnection ऑब्जेक्ट बनाता है। डायलर ऐप कॉल सुविधाओं को प्रबंधित करने के लिए HfpClientConnection ऑब्जेक्ट के साथ इंटरैक्ट करता है, जैसे कॉल स्वीकार करना या हैंग करना।

यह ध्यान दिया जाना चाहिए कि डिफ़ॉल्ट डायलर ऐप एक साथ जुड़े कई एचएफपी उपकरणों का समर्थन नहीं करता है। मल्टी-डिवाइस एचएफपी को लागू करने के लिए, उपयोगकर्ताओं को कॉल करते समय किस डिवाइस खाते का उपयोग करना है, इसका चयन करने के लिए अनुकूलन की आवश्यकता होती है। इसके बाद ऐप सही अकाउंट से telecomManager.placeCall पर कॉल करता है। आपको यह सत्यापित करने की आवश्यकता है कि अन्य मल्टी-डिवाइस कार्यक्षमता भी अपेक्षानुसार काम करती है।

मल्टी-डिवाइस एचएफपी सत्यापित करें

यह जांचने के लिए कि मल्टी-डिवाइस कनेक्टिविटी ब्लूटूथ पर ठीक से काम करती है:

  1. ब्लूटूथ का उपयोग करके, डिवाइस को IVI से कनेक्ट करें और डिवाइस से ऑडियो स्ट्रीम करें।
  2. ब्लूटूथ के माध्यम से दो फोन को आईवीआई से कनेक्ट करें।
  3. एक फ़ोन चुनें. सीधे फ़ोन से आउटगोइंग कॉल करें, और IVI का उपयोग करके आउटगोइंग कॉल करें।
    1. दोनों बार, स्ट्रीम किए गए ऑडियो के रुकने और IVI कनेक्टेड स्पीकर पर फ़ोन ऑडियो चलने की पुष्टि करें।
  4. एक ही फ़ोन का उपयोग करके, सीधे फ़ोन पर इनकमिंग कॉल प्राप्त करें, और IVI का उपयोग करके इनकमिंग कॉल प्राप्त करें।
    1. दोनों बार, स्ट्रीमिंग ऑडियो के रुकने और आईवीआई से जुड़े स्पीकर पर फोन के ऑडियो चलने की पुष्टि करें।
  5. दूसरे कनेक्टेड फ़ोन के साथ चरण 3 और 4 दोहराएँ।

आपातकालीन कॉलिंग

आपातकालीन कॉल करने की क्षमता कार में टेलीफोनी और ब्लूटूथ फ़ंक्शन का एक महत्वपूर्ण पहलू है। ऐसे कई तरीके हैं जिनसे आईवीआई से आपातकालीन कॉल शुरू की जा सकती है, जिनमें शामिल हैं:

  • स्टैंडअलोन ई-कॉल समाधान
  • ईकॉल समाधान आईवीआई में एकीकृत है
  • जब कोई अंतर्निहित सिस्टम उपलब्ध न हो तो कनेक्टेड ब्लूटूथ फोन पर निर्भर रहना

एक आपातकालीन कॉल कनेक्ट करें

जबकि eCall उपकरण सुरक्षा-महत्वपूर्ण है, यह वर्तमान में Android में एकीकृत नहीं है। एंड्रॉइड के माध्यम से आपातकालीन कॉलिंग सुविधाओं को उजागर करने के लिए ConnectionService का उपयोग करना संभव है, जिसमें आपातकालीन कॉल के लिए पहुंच विकल्प पेश करने का लाभ भी है। अधिक जानने के लिए, कॉलिंग ऐप बनाना देखें।

आपातकालीन कनेक्शन सेवा कैसे स्थापित करें इसका एक उदाहरण यहां दिया गया है:

public class YourEmergencyConnectionService extends ConnectionService {

    @Override
    public Connection onCreateOutgoingConnection(
            PhoneAccountHandle connectionManagerAccount,
            ConnectionRequest request) {
        // Your equipment specific procedure to make ecall
        // ...
    }

    private void onYourEcallEquipmentReady() {

        PhoneAccountHandle handle =
            new PhoneAccountHandle(new ComponentName(context, YourEmergencyConnectionService),
                    YourEmergencyConnectionId);
        PhoneAccount account =
            new PhoneAccount.Builder(handle, eCallOnlyAccount)
            .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_TEL))
            .setCapabilities(PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS
                    | PhoneAccount.CAPABILITY_MULTI_USER)
            .build():
        mTelecomManager.registerPhoneAccount(account);
        mTelecomManager.enablePhoneAccount(account.getAccountHandle(), true);
    }
}

आपातकालीन कॉल के लिए ब्लूटूथ सक्षम करें

एंड्रॉइड 10 से पहले आपातकालीन कॉल करने में फोन से सीधे डायल करना और यदि उपलब्ध हो तो विशेष उपकरण लागू करना शामिल था (उदाहरण के लिए, खतरे का पता चलने पर या उपयोगकर्ता की कार्रवाई पर ऑटो-ट्रिगर)। एंड्रॉइड 10 और उच्चतर में, कार में डायलर सीधे एक आपातकालीन नंबर पर कॉल कर सकता है, बशर्ते कि यह MAXIMUM_CONNECTED_DEVICES apps/Bluetooth/res/values/config.xml में हो:

<!-- For supporting emergency call through the hfp client connection service --> <bool name=”hfp_client_connection_service_support_emergency_call”>true</bool>

इस तरह से आपातकालीन कॉलिंग लागू करके, अन्य ऐप्स, जैसे ध्वनि पहचान, भी आपातकालीन नंबर पर कॉल कर सकते हैं।

फ़ोन बुक एक्सेस प्रोफ़ाइल

ब्लूटूथ फोन बुक एक्सेस प्रोफाइल (पीबीएपी) कनेक्टेड रिमोट डिवाइस से संपर्क और कॉल इतिहास डाउनलोड करता है। पीबीएपी संपर्कों की एक एकत्रित, खोजने योग्य सूची बनाए रखता है जिसे पीबीएपी क्लाइंट स्टेट मशीन द्वारा अद्यतन किया जाता है। प्रत्येक कनेक्टेड डिवाइस एक अलग पीबीएपी क्लाइंट स्टेट मशीन के साथ इंटरैक्ट करता है, जिसके परिणामस्वरूप कॉल करते समय संपर्क उचित डिवाइस से जुड़े होते हैं।

PBAP यूनिडायरेक्शनल है और इसलिए PbapClientService में किसी भी MAXIMUM_CONNECTED_DEVICES से कनेक्शन को इंस्टेंट करने के लिए IVI की आवश्यकता होती है, जो IVI के साथ अनुमत एक साथ PBAP डिवाइस कनेक्शन की अधिकतम संख्या को परिभाषित करता है। पीबीएपी क्लाइंट संपर्क प्रदाता में प्रत्येक कनेक्टेड डिवाइस के संपर्कों को संग्रहीत करता है जिसे फिर प्रत्येक डिवाइस के लिए फोन बुक प्राप्त करने के लिए एक ऐप द्वारा एक्सेस किया जा सकता है।

इसके अलावा, कनेक्शन बनाने के लिए प्रोफ़ाइल कनेक्शन को आईवीआई और मोबाइल डिवाइस दोनों द्वारा अधिकृत किया जाना चाहिए। जब कोई पीबीएपी क्लाइंट डिस्कनेक्ट हो जाता है, तो आंतरिक डेटाबेस पहले से कनेक्टेड डिवाइस से जुड़े सभी संपर्क और कॉल इतिहास को हटा देता है।

संदेश पहुँच प्रोफ़ाइल

ब्लूटूथ मैसेज एक्सेस प्रोफाइल (एमएपी) वाहन को कनेक्टेड रिमोट डिवाइस के माध्यम से एसएमएस संदेश भेजने और प्राप्त करने की अनुमति देता है। वर्तमान में, संदेश IVI पर स्थानीय रूप से संग्रहीत नहीं होते हैं। इसके बजाय, जब भी कनेक्टेड रिमोट डिवाइस एक संदेश प्राप्त करता है, आईवीआई संदेश प्राप्त करता है और उसे पार्स करता है और उसकी सामग्री को एक इंटेंट इंस्टेंस में प्रसारित करता है, जिसे बाद में एक ऐप द्वारा प्राप्त किया जा सकता है।

संदेश भेजने और प्राप्त करने के उद्देश्य से किसी मोबाइल डिवाइस से कनेक्ट करने के लिए, IVI को MAP कनेक्शन आरंभ करना होगा। MapClientService में MAXIMUM_CONNECTED_DEVICES IVI के साथ अनुमत एक साथ MAP डिवाइस कनेक्शन की अधिकतम संख्या को परिभाषित करता है। संदेशों को स्थानांतरित करने से पहले प्रत्येक कनेक्शन को आईवीआई और मोबाइल डिवाइस द्वारा अधिकृत किया जाना चाहिए।

उन्नत ऑडियो वितरण प्रोफ़ाइल

ब्लूटूथ एडवांस्ड ऑडियो डिस्ट्रीब्यूशन प्रोफाइल (ए2डीपी) वाहन को कनेक्टेड रिमोट डिवाइस से ऑडियो स्ट्रीम प्राप्त करने की अनुमति देता है।

अन्य प्रोफ़ाइलों के विपरीत, कनेक्टेड A2DP डिवाइसों की अधिकतम संख्या मूल स्टैक में लागू होती है, जावा में नहीं। मान को वर्तमान में packages/modules/Bluetooth/system/btif/src/btif_av.cc में kDefaultMaxConnectedAudioDevices वेरिएबल का उपयोग करके 1 पर हार्डकोड किया गया है।

ऑडियो/वीडियो रिमोट कंट्रोल प्रोफ़ाइल

ब्लूटूथ ऑडियो/वीडियो रिमोट कंट्रोल प्रोफाइल (एवीआरसीपी) वाहन को कनेक्टेड रिमोट डिवाइस पर मीडिया प्लेयर्स को नियंत्रित करने और ब्राउज़ करने की अनुमति देता है। चूंकि IVI एक AVRCP नियंत्रक की भूमिका निभाता है, इसलिए ऑडियो प्लेबैक को प्रभावित करने वाला कोई भी ट्रिगर नियंत्रण लक्ष्य डिवाइस के A2DP कनेक्शन पर निर्भर करता है।

एंड्रॉइड फोन पर एक विशिष्ट मीडिया प्लेयर को IVI द्वारा AVRCP के माध्यम से ब्राउज़ करने योग्य बनाने के लिए, फोन पर मीडिया ऐप को एक MediaBrowserService प्रदान करना होगा और com.android.bluetooth को उस सेवा तक पहुंच की अनुमति देनी होगी। मीडिया ब्राउज़र सेवा का निर्माण यह कैसे करना है इसके बारे में विस्तार से बताता है।