Android, ब्लूटूथ की सभी सुविधाओं के साथ-साथ, कार में इस्तेमाल होने वाली कई सामान्य ब्लूटूथ प्रोफ़ाइल के साथ काम करता है. इसके अलावा, कई ऐसे सुधार भी किए गए हैं जिनसे अन्य डिवाइसों और सेवाओं के साथ इसकी परफ़ॉर्मेंस और अनुभव बेहतर होता है.
ब्लूटूथ कनेक्शन मैनेज करना
Android में, CarBluetoothService, मौजूदा उपयोगकर्ता के ब्लूटूथ डिवाइसों और IVI से कनेक्ट की गई हर प्रोफ़ाइल के लिए प्राथमिकता वाली सूचियों को मैनेज करता है. डिवाइस, प्रोफ़ाइलों से प्राथमिकता के क्रम में कनेक्ट किए जाते हैं. डिवाइसों को किसी प्रोफ़ाइल से कब कनेक्ट करना है, कब डिसकनेक्ट करना है, और कब कनेक्ट करने की सुविधा चालू करनी है, यह डिफ़ॉल्ट कनेक्शन नीति के हिसाब से तय होता है. हालांकि, अगर चाहें, तो संसाधन ओवरले का इस्तेमाल करके इस नीति को बदला जा सकता है.
ऑटोमोटिव कनेक्शन मैनेजमेंट को कॉन्फ़िगर करना
फ़ोन के लिए डिफ़ॉल्ट नीति बंद करना
Android का ब्लूटूथ स्टैक, फ़ोन के लिए कनेक्शन की नीति बनाए रखता है. यह नीति डिफ़ॉल्ट रूप से चालू होती है. आपके डिवाइस पर यह नीति बंद होनी चाहिए, ताकि यह
CarBluetoothService में मौजूद, Automotive से जुड़ी नीति के साथ टकराव न करे. कार के प्रॉडक्ट ओवरले को इस बात का ध्यान रखना चाहिए. हालांकि,
संसाधन ओवरले में जाकर, फ़ोन से जुड़ी नीति को बंद किया जा सकता है. इसके लिए,
/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 में
HeadsetClientService, एक साथ HFP कनेक्शन की ज़्यादा से ज़्यादा संख्या तय करता है.
जब कोई उपयोगकर्ता किसी डिवाइस से फ़ोन कॉल करता है या उसे कोई फ़ोन कॉल आता है, तो उससे जुड़ा फ़ोन खाता एक HfpClientConnection ऑब्जेक्ट बनाता है. डायल करने वाला ऐप्लिकेशन, कॉल से जुड़ी सुविधाओं को मैनेज करने के लिए HfpClientConnection ऑब्जेक्ट के साथ इंटरैक्ट करता है. जैसे, कॉल स्वीकार करना या कॉल काटना.
ध्यान दें कि डिफ़ॉल्ट Dialer ऐप्लिकेशन, एक साथ कनेक्ट किए गए एक से ज़्यादा एचएफ़पी डिवाइसों के साथ काम नहीं करता. एक से ज़्यादा डिवाइसों पर एचएफ़पी की सुविधा लागू करने के लिए, उपयोगकर्ताओं को यह चुनने की सुविधा देनी होगी कि कॉल करते समय उन्हें किस डिवाइस खाते का इस्तेमाल करना है. इसके लिए, आपको सुविधा को अपनी ज़रूरत के हिसाब से बनाना होगा. इसके बाद, ऐप्लिकेशन सही खाते से telecomManager.placeCall को कॉल करता है. आपको यह पुष्टि करनी होगी कि मल्टी-डिवाइस की अन्य सुविधाएं भी ठीक से काम कर रही हैं.
मल्टी-डिवाइस एचएफ़पी की पुष्टि करना
यह देखने के लिए कि ब्लूटूथ के ज़रिए मल्टी-डिवाइस कनेक्टिविटी ठीक से काम कर रही है या नहीं:
- ब्लूटूथ का इस्तेमाल करके, किसी डिवाइस को IVI से कनेक्ट करें और उस डिवाइस से ऑडियो स्ट्रीम करें.
- ब्लूटूथ के ज़रिए दो फ़ोन को IVI से कनेक्ट करें.
- कोई एक फ़ोन चुनें. सीधे फ़ोन से आउटगोइंग कॉल करना
और आईवीआई का इस्तेमाल करके आउटगोइंग कॉल करना.
- दोनों बार, पुष्टि करें कि स्ट्रीम किया जा रहा ऑडियो रुक गया है और फ़ोन का ऑडियो, कनेक्ट किए गए IVI के स्पीकर पर चल रहा है.
- उसी फ़ोन पर, सीधे तौर पर इनकमिंग कॉल पाएं. साथ ही, IVI का इस्तेमाल करके इनकमिंग कॉल पाएं.
- दोनों बार, पुष्टि करें कि स्ट्रीमिंग ऑडियो रुक गया हो और फ़ोन का ऑडियो, IVI से कनेक्ट किए गए स्पीकर पर चल रहा हो.
- कनेक्ट किए गए दूसरे फ़ोन के लिए, चरण 3 और 4 दोहराएं.
आपातकालीन स्थिति में कॉल करने की सुविधा
कार में टेलीफ़ोनी और ब्लूटूथ फ़ंक्शन के लिए, आपातकालीन कॉल करने की सुविधा होना ज़रूरी है. आईवीआई से आपातकालीन कॉल शुरू करने के कई तरीके हैं. इनमें ये शामिल हैं:
- स्टैंडअलोन ईकॉल समाधान
- 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 और इसके बाद के वर्शन में, कार में मौजूद Dialer ऐप्लिकेशन से सीधे किसी आपातकालीन नंबर पर कॉल किया जा सकता है. इसके लिए, यह 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 से यह तय होता है कि IVI के साथ एक साथ ज़्यादा से ज़्यादा कितने PBAP डिवाइस कनेक्ट किए जा सकते हैं. PBAP क्लाइंट, कनेक्ट किए गए हर डिवाइस के लिए संपर्कों को
संपर्क सेवा देने वाली कंपनी में सेव करता है. इसके बाद, कोई ऐप्लिकेशन इन संपर्कों को ऐक्सेस करके, हर डिवाइस के लिए फ़ोन बुक बना सकता है.
इसके अलावा, कनेक्शन बनाने के लिए, प्रोफ़ाइल कनेक्शन को IVI और मोबाइल डिवाइस, दोनों से अनुमति मिलनी चाहिए. जब कोई PBAP क्लाइंट डिसकनेक्ट हो जाता है, तो इंटरनल डेटाबेस, पहले से कनेक्ट किए गए डिवाइस से जुड़े सभी संपर्कों और कॉल इतिहास को हटा देता है.
मैसेज ऐक्सेस प्रोफ़ाइल
ब्लूटूथ मैसेज ऐक्सेस प्रोफ़ाइल (एमएपी) की मदद से, वाहन में कनेक्ट किए गए रिमोट डिवाइस से एसएमएस भेजे और पाए जा सकते हैं. फ़िलहाल, मैसेज को IVI पर लोकल तौर पर सेव नहीं किया जाता. इसके बजाय, जब कनेक्ट किए गए रिमोट डिवाइस को कोई मैसेज मिलता है, तो IVI उस मैसेज को पाता है और पार्स करता है. इसके बाद, वह मैसेज के कॉन्टेंट को Intent इंस्टेंस में ब्रॉडकास्ट करता है. इसे कोई ऐप्लिकेशन पा सकता है.
मैसेज भेजने और पाने के लिए, IVI को मोबाइल डिवाइस से कनेक्ट करना होगा. इसके लिए, IVI को MAP कनेक्शन शुरू करना होगा.
MAXIMUM_CONNECTED_DEVICES में
MapClientService से यह तय होता है कि आईवीआई के साथ एक साथ ज़्यादा से ज़्यादा कितने MAP डिवाइस कनेक्ट किए जा सकते हैं. मैसेज ट्रांसफ़र करने से पहले, हर कनेक्शन को IVI और मोबाइल डिवाइस से अनुमति लेनी होगी.
ऐडवांस ऑडियो डिस्ट्रिब्यूशन प्रोफ़ाइल
ब्लूटूथ ऐडवांस्ड ऑडियो डिस्ट्रिब्यूशन प्रोफ़ाइल (ए2डीपी) की मदद से, कार को कनेक्ट किए गए रिमोट डिवाइस से ऑडियो स्ट्रीम मिल सकती हैं.
अन्य प्रोफ़ाइलों के उलट, कनेक्ट किए गए A2DP डिवाइसों की ज़्यादा से ज़्यादा संख्या को नेटिव स्टैक में लागू किया जाता है, न कि Java में. फ़िलहाल, वैल्यू को 1 में kDefaultMaxConnectedAudioDevices वैरिएबल का इस्तेमाल करके
packages/modules/Bluetooth/system/btif/src/btif_av.cc में हार्डकोड किया गया है.
ऑडियो/वीडियो रिमोट कंट्रोल प्रोफ़ाइल
ब्लूटूथ ऑडियो/वीडियो रिमोट कंट्रोल प्रोफ़ाइल (एवीआरसीपी) की मदद से, वाहन में कनेक्ट किए गए रिमोट डिवाइस पर मीडिया प्लेयर को कंट्रोल किया जा सकता है और उन्हें ब्राउज़ किया जा सकता है. IVI, AVRCP कंट्रोलर की भूमिका निभाता है. इसलिए, ऑडियो चलाने पर असर डालने वाले ट्रिगर किए गए कंट्रोल, टारगेट डिवाइस के साथ A2DP कनेक्शन पर निर्भर करते हैं.
अगर आपको Android फ़ोन पर मौजूद किसी मीडिया प्लेयर को AVRCP के ज़रिए IVI से ब्राउज़ करना है, तो फ़ोन पर मौजूद मीडिया ऐप्लिकेशन को
MediaBrowserService उपलब्ध कराना होगा. साथ ही,
MediaBrowserService को उस सेवा का ऐक्सेस देना होगा.com.android.bluetooth
मीडिया ब्राउज़र सेवा बनाना लेख में, इस बारे में पूरी जानकारी दी गई है.