Android, ब्लूटूथ की पूरी सुविधा देता है. यह कार में इस्तेमाल होने वाली कई सामान्य ब्लूटूथ प्रोफ़ाइलों के साथ काम करता है. इसके अलावा, कई ऐसे सुधार भी किए गए हैं जिनसे अन्य डिवाइसों और सेवाओं के साथ-साथ, परफ़ॉर्मेंस और अनुभव को बेहतर बनाया जा सकता है.
ब्लूटूथ कनेक्शन मैनेज करना
Android में, CarBluetoothService, मौजूदा उपयोगकर्ता के ब्लूटूथ डिवाइसों और IVI से हर प्रोफ़ाइल कनेक्शन के लिए प्राथमिकता वाली सूचियों को मैनेज करता है. डिवाइस, प्रोफ़ाइलों से प्राथमिकता के क्रम में कनेक्ट किए जाते हैं. डिवाइसों को किसी प्रोफ़ाइल से कब कनेक्ट करना है, कब डिसकनेक्ट करना है, और कब कनेक्ट करने की सुविधा चालू करनी है, यह कनेक्शन से जुड़ी डिफ़ॉल्ट नीति के हिसाब से तय होता है. हालांकि, अगर चाहें, तो संसाधन ओवरले का इस्तेमाल करके इस नीति को बदला जा सकता है.
वाहन के कनेक्शन को मैनेज करने की सुविधा कॉन्फ़िगर करना
फ़ोन के लिए डिफ़ॉल्ट नीति बंद करना
Android का ब्लूटूथ स्टैक, फ़ोन के लिए कनेक्शन की नीति बनाए रखता है. यह नीति डिफ़ॉल्ट रूप से चालू होती है. आपके डिवाइस पर यह नीति बंद होनी चाहिए, ताकि यह
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
पर सेट करें.
इस संसाधन को मूल रूप से MAXIMUM_CONNECTED_DEVICES
के हिस्से के तौर पर
packages/services/Car/service/res/values/config.xml
में तय किया गया है.
ब्लूटूथ अडैप्टर को चालू और बंद करना
आपकी नीति का एक मुख्य फ़ंक्शन, सही समय पर ब्लूटूथ अडैप्टर को चालू और बंद करना है. अडैप्टर को चालू और बंद करने के लिए, BluetoothAdapter.enable()
और BluetoothAdapter.disable()
फ़्रेमवर्क एपीआई का इस्तेमाल किया जा सकता है.
इन कॉल में, उपयोगकर्ता की चुनी गई सेटिंग का पालन किया जाना चाहिए. उपयोगकर्ता ने यह सेटिंग, सेटिंग या किसी अन्य तरीके से चुनी हो सकती है. इसके लिए, यह तरीका अपनाएं:
/** * 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); }
यह तय करना कि ब्लूटूथ अडैप्टर को कब चालू और बंद करना है
कस्टम नीति की मदद से, यह तय किया जा सकता है कि किन इवेंट से पता चलता है कि अडैप्टर को कब चालू और बंद करना है. ऐसा करने का एक तरीका यह है कि MAXIMUM_CONNECTED_DEVICES
में CarPowerManager
पावर स्टेट का इस्तेमाल किया जाए:
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(); } } } }
वाहन के कनेक्शन मैनेजमेंट की पुष्टि करना
कनेक्शन की नीति के काम करने के तरीके की पुष्टि करने का सबसे आसान तरीका यह है कि आप अपने IVI पर ब्लूटूथ चालू करें. इसके बाद, यह पुष्टि करें कि यह सही क्रम में सही डिवाइसों से अपने-आप कनेक्ट हो रहा है. सेटिंग के यूज़र इंटरफ़ेस (यूआई) या इन adb कमांड का इस्तेमाल करके, ब्लूटूथ अडैप्टर को टॉगल किया जा सकता है:
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
आखिर में, अगर आपने खुद से कोई वाहन नीति बनाई है, तो कस्टम कनेक्शन के किसी भी व्यवहार की पुष्टि करने के लिए, आपको उन इवेंट को कंट्रोल करना होगा जिन्हें आपने डिवाइस कनेक्शन ट्रिगर करने के लिए चुना है.
ऑटोमोटिव ब्लूटूथ प्रोफ़ाइल
Android में, आईवीआई एक साथ कई डिवाइसों को ब्लूटूथ से कनेक्ट कर सकता है. एक साथ कई डिवाइसों पर ब्लूटूथ की मदद से फ़ोन कॉल करने की सुविधा का इस्तेमाल करके, लोग एक साथ अलग-अलग डिवाइसों को कनेक्ट कर सकते हैं. जैसे, निजी फ़ोन और ऑफ़िस का फ़ोन. साथ ही, वे किसी भी डिवाइस से बोलकर कॉल कर सकते हैं.
कनेक्शन की सीमाएं, हर ब्लूटूथ प्रोफ़ाइल के लिए लागू की जाती हैं. आम तौर पर, ये सीमाएं प्रोफ़ाइल सेवा के लागू होने के दौरान तय की जाती हैं. डिफ़ॉल्ट रूप से, CarBluetoothService यह तय नहीं करता कि कितने डिवाइस कनेक्ट किए जा सकते हैं.
हैंड्स-फ़्री प्रोफ़ाइल
ब्लूटूथ हैंड्स-फ़्री प्रोफ़ाइल (एचएफ़पी) की मदद से, वाहन में कनेक्ट किए गए रिमोट डिवाइस से फ़ोन कॉल किए और रिसीव किए जा सकते हैं. हर डिवाइस कनेक्शन, TelecomManager के साथ एक अलग फ़ोन खाता रजिस्टर करता है. यह IVI ऐप्लिकेशन को उपलब्ध फ़ोन खातों के बारे में जानकारी देता है.
आईवीआई, एचएफ़पी के ज़रिए कई डिवाइसों से कनेक्ट हो सकता है. MAX_STATE_MACHINES_POSSIBLE
MAXIMUM_CONNECTED_DEVICES
in
HeadsetClientService
से, एक साथ एचएफ़पी
कनेक्शन की ज़्यादा से ज़्यादा संख्या तय होती है.
जब कोई उपयोगकर्ता किसी डिवाइस से फ़ोन कॉल करता है या उसे कोई फ़ोन कॉल आता है, तो उससे जुड़ा फ़ोन खाता एक HfpClientConnection
ऑब्जेक्ट बनाता है. डायल करने वाला ऐप्लिकेशन, कॉल से जुड़ी सुविधाओं को मैनेज करने के लिए HfpClientConnection
ऑब्जेक्ट के साथ इंटरैक्ट करता है. जैसे, कॉल स्वीकार करना या कॉल काटना.
ध्यान दें कि डिफ़ॉल्ट Dialer ऐप्लिकेशन, एक साथ कनेक्ट किए गए एक से ज़्यादा एचएफ़पी डिवाइसों के साथ काम नहीं करता. एक से ज़्यादा डिवाइसों पर एचएफ़पी की सुविधा लागू करने के लिए, उपयोगकर्ताओं को यह चुनने की सुविधा देनी होगी कि कॉल करते समय उन्हें किस डिवाइस खाते का इस्तेमाल करना है. इसके लिए, डिवाइस को अपनी पसंद के मुताबिक बनाना होगा. इसके बाद, ऐप्लिकेशन सही खाते से telecomManager.placeCall
को कॉल करता है. आपको यह पुष्टि करनी होगी कि मल्टी-डिवाइस की अन्य सुविधाएं भी ठीक से काम कर रही हैं.
मल्टी-डिवाइस एचएफ़पी की पुष्टि करना
यह देखने के लिए कि ब्लूटूथ के ज़रिए एक से ज़्यादा डिवाइसों से कनेक्ट करने की सुविधा ठीक से काम कर रही है या नहीं:
- ब्लूटूथ का इस्तेमाल करके, किसी डिवाइस को IVI से कनेक्ट करें और उस डिवाइस से ऑडियो स्ट्रीम करें.
- ब्लूटूथ की मदद से, दो फ़ोन को IVI से कनेक्ट करें.
- कोई एक फ़ोन चुनें. सीधे फ़ोन से कॉल करना
और आईवीआई का इस्तेमाल करके कॉल करना.
- दोनों बार, पुष्टि करें कि स्ट्रीम किया जा रहा ऑडियो रुक गया हो और फ़ोन का ऑडियो, IVI से कनेक्ट किए गए स्पीकर पर चल रहा हो.
- उसी फ़ोन पर, सीधे तौर पर आने वाला कॉल (इनकमिंग) कॉल पाएं. साथ ही, IVI का इस्तेमाल करके आने वाला कॉल (इनकमिंग) कॉल पाएं.
- दोनों बार, पुष्टि करें कि स्ट्रीमिंग ऑडियो रुक गया है और फ़ोन का ऑडियो, IVI से कनेक्ट किए गए स्पीकर पर चल रहा है.
- कनेक्ट किए गए दूसरे फ़ोन के लिए, तीसरे और चौथे चरण को दोहराएं.
आपातकालीन कॉल करने की सुविधा
कार में टेलीफ़ोनी और ब्लूटूथ फ़ंक्शन के लिए, आपातकालीन कॉल करने की सुविधा होना ज़रूरी है. आईवीआई से आपातकालीन कॉल शुरू करने के कई तरीके हैं. इनमें ये शामिल हैं:
- स्टैंडअलोन eCall सलूशन
- IVI में इंटिग्रेट किया गया eCall सलूशन
- जब गाड़ी में पहले से मौजूद सिस्टम उपलब्ध न हो, तब ब्लूटूथ से कनेक्ट किए गए फ़ोन पर भरोसा करना
आपातकालीन कॉल कनेक्ट करना
eCall की सुविधा देने वाले उपकरण सुरक्षा के लिए बहुत ज़रूरी होते हैं. हालांकि, फ़िलहाल इन्हें Android में इंटिग्रेट नहीं किया गया है. Android के ज़रिए आपातकालीन कॉल की सुविधाओं को उपलब्ध कराने के लिए, ConnectionService का इस्तेमाल किया जा सकता है. इससे आपातकालीन कॉल के लिए सुलभता विकल्प उपलब्ध कराने का फ़ायदा भी मिलता है. ज़्यादा जानने के लिए, कॉलिंग ऐप्लिकेशन बनाना लेख पढ़ें.
आपातकालीन 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); } }
आपातकालीन कॉल के लिए ब्लूटूथ चालू करना
Android 10 से पहले, फ़ोन से सीधे डायल करके इमरजेंसी नंबर पर कॉल किया जाता था. साथ ही, अगर कोई खास उपकरण उपलब्ध होता था, तो उसे चालू किया जाता था. उदाहरण के लिए, खतरे का पता चलने या उपयोगकर्ता की कार्रवाई पर अपने-आप चालू होने वाला उपकरण. Android 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, संपर्कों की एक एग्रीगेट की गई और खोजी जा सकने वाली सूची को बनाए रखता है. इसे PBAP क्लाइंट स्टेट मशीन अपडेट करती है. कनेक्ट किया गया हर डिवाइस, अलग-अलग PBAP क्लाइंट स्टेट मशीन के साथ इंटरैक्ट करता है. इससे कॉल करते समय, संपर्क सही डिवाइस से जुड़े होते हैं.
PBAP एकतरफ़ा होता है. इसलिए, IVI को किसी भी MAXIMUM_CONNECTED_DEVICES
से कनेक्शन शुरू करने के लिए,
PbapClientService
की ज़रूरत होती है.
PbapClientService
यह तय करता है कि IVI के साथ एक साथ कितने PBAP डिवाइस कनेक्ट किए जा सकते हैं. PBAP क्लाइंट, कनेक्ट किए गए हर डिवाइस के लिए संपर्कों को
संपर्क सेवा देने वाली कंपनी में सेव करता है. इसके बाद, कोई ऐप्लिकेशन इन संपर्कों को ऐक्सेस करके, हर डिवाइस के लिए फ़ोन बुक बना सकता है.
इसके अलावा, कनेक्शन बनाने के लिए, IVI और मोबाइल डिवाइस, दोनों से प्रोफ़ाइल कनेक्शन को अनुमति मिलनी चाहिए. जब कोई PBAP क्लाइंट डिसकनेक्ट हो जाता है, तो इंटरनल डेटाबेस, पहले से कनेक्ट किए गए डिवाइस से जुड़े सभी संपर्कों और कॉल इतिहास को हटा देता है.
मैसेज ऐक्सेस प्रोफ़ाइल
ब्लूटूथ मैसेज ऐक्सेस प्रोफ़ाइल (एमएपी) की मदद से, वाहन में मौजूद सिस्टम, कनेक्ट किए गए रिमोट डिवाइस के ज़रिए एसएमएस भेज और पा सकता है. फ़िलहाल, मैसेज को IVI पर सेव नहीं किया जाता. इसके बजाय, जब कनेक्ट किए गए रिमोट डिवाइस को कोई मैसेज मिलता है, तो IVI उस मैसेज को पाता है और पार्स करता है. इसके बाद, वह मैसेज के कॉन्टेंट को Intent इंस्टेंस में ब्रॉडकास्ट करता है. इसे कोई ऐप्लिकेशन पा सकता है.
मैसेज भेजने और पाने के लिए, IVI को मोबाइल डिवाइस से कनेक्ट करना होगा. इसके लिए, IVI को MAP कनेक्शन शुरू करना होगा.
MAXIMUM_CONNECTED_DEVICES
में
MapClientService
, IVI के साथ एक साथ कनेक्ट किए जा सकने वाले MAP डिवाइसों की ज़्यादा से ज़्यादा संख्या तय करता है. मैसेज ट्रांसफ़र करने से पहले, यह ज़रूरी है कि हर कनेक्शन को IVI और मोबाइल डिवाइस से अनुमति मिली हो.
ऐडवांस ऑडियो डिस्ट्रिब्यूशन प्रोफ़ाइल
ब्लूटूथ की ऐडवांस्ड ऑडियो डिस्ट्रिब्यूशन प्रोफ़ाइल (ए2डीपी) की मदद से, कार को कनेक्ट किए गए रिमोट डिवाइस से ऑडियो स्ट्रीम मिलती हैं.
अन्य प्रोफ़ाइलों के उलट, कनेक्ट किए गए A2DP डिवाइसों की ज़्यादा से ज़्यादा संख्या को नेटिव स्टैक में लागू किया जाता है, न कि Java में. फ़िलहाल, वैल्यू को 1
में kDefaultMaxConnectedAudioDevices
वैरिएबल का इस्तेमाल करके
packages/modules/Bluetooth/system/btif/src/btif_av.cc
में हार्डकोड किया गया है.
ऑडियो/वीडियो रिमोट कंट्रोल प्रोफ़ाइल
ब्लूटूथ ऑडियो/वीडियो रिमोट कंट्रोल प्रोफ़ाइल (एवीआरसीपी) की मदद से, वाहन में मौजूद सिस्टम, कनेक्ट किए गए रिमोट डिवाइस पर मीडिया प्लेयर को कंट्रोल कर सकता है और उन्हें ब्राउज़ कर सकता है. IVI, AVRCP कंट्रोलर की भूमिका निभाता है. इसलिए, ऑडियो चलाने पर असर डालने वाले ट्रिगर किए गए कंट्रोल, टारगेट डिवाइस के साथ A2DP कनेक्शन पर निर्भर करते हैं.
अगर आपको Android फ़ोन पर मौजूद किसी मीडिया प्लेयर को AVRCP के ज़रिए IVI से ब्राउज़ करना है, तो फ़ोन पर मौजूद मीडिया ऐप्लिकेशन को
MediaBrowserService
उपलब्ध कराना होगा. साथ ही, उसे com.android.bluetooth
को उस सेवा का ऐक्सेस देना होगा.
मीडिया ब्राउज़र सेवा बनाना लेख में, इस बारे में पूरी जानकारी दी गई है.