Android มีการใช้งานบลูทูธอย่างเต็มรูปแบบที่รองรับโปรไฟล์บลูทูธในรถยนต์ทั่วไปหลายรายการ นอกจากนี้ยังมีการปรับปรุงอีกมากมายที่ช่วยเพิ่มประสิทธิภาพและประสบการณ์การใช้งานกับอุปกรณ์และบริการอื่นๆ
การจัดการการเชื่อมต่อบลูทูธ
ใน Android นั้น CarBluetoothService จะดูแลอุปกรณ์บลูทูธของผู้ใช้ปัจจุบันและรายการลำดับความสำคัญสำหรับการเชื่อมต่อโปรไฟล์แต่ละรายการกับ IVI อุปกรณ์จะเชื่อมต่อกับโปรไฟล์ตามลําดับความสําคัญที่กําหนด ช่วงเวลาที่จะเปิดใช้ ปิดใช้ และเชื่อมต่ออุปกรณ์กับโปรไฟล์จะขึ้นอยู่กับนโยบายการเชื่อมต่อเริ่มต้นที่ลบล้างได้โดยใช้ การวางซ้อนทรัพยากร หากต้องการ
กำหนดค่าการจัดการการเชื่อมต่อยานยนต์
ปิดใช้นโยบายโทรศัพท์เริ่มต้น
สแต็กบลูทูธของ Android จะรักษานโยบายการเชื่อมต่อสำหรับโทรศัพท์ที่เปิดใช้โดยค่าเริ่มต้น คุณต้องปิดใช้นโยบายนี้ในอุปกรณ์เพื่อไม่ให้ขัดแย้งกับนโยบายยานยนต์ที่ต้องการใน
CarBluetoothService แม้ว่าการวางซ้อนผลิตภัณฑ์รถยนต์จะจัดการเรื่องนี้ให้คุณแล้ว แต่คุณก็ปิดใช้นโยบายโทรศัพท์ใน
การวางซ้อนทรัพยากรได้โดยตั้งค่า enable_phone_policy
เป็น false
ใน MAXIMUM_CONNECTED_DEVICES
ใน
/packages/apps/Bluetooth/res/values/config.xml
ใช้นโยบายยานยนต์เริ่มต้น
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
เปิดและปิดใช้อะแดปเตอร์บลูทูธ
ฟังก์ชันหลักอย่างหนึ่งของนโยบายคือการเปิดและปิดอะแดปเตอร์บลูทูธในเวลาที่เหมาะสม คุณสามารถใช้ API ของเฟรมเวิร์ก 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()
API ที่ดําเนินการต่อเพื่อเชื่อมต่ออุปกรณ์ตามรายการลําดับความสําคัญที่กําหนดไว้สําหรับโปรไฟล์บลูทูธแต่ละรายการ
ตัวอย่างกรณีที่คุณอาจต้องการดำเนินการนี้คือเมื่อใดก็ตามที่อะแดปเตอร์บลูทูธเปิดอยู่
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 และตรวจสอบว่าอุปกรณ์เชื่อมต่อกับอุปกรณ์ที่ถูกต้องตามลําดับที่เหมาะสมโดยอัตโนมัติ คุณสลับอะแดปเตอร์บลูทูธผ่าน UI การตั้งค่าหรือใช้คำสั่ง 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 นั้น IVI จะรองรับอุปกรณ์หลายเครื่องที่เชื่อมต่อพร้อมกันผ่านบลูทูธ บริการโทรศัพท์บลูทูธหลายอุปกรณ์ช่วยให้ผู้ใช้เชื่อมต่ออุปกรณ์แยกต่างหากได้พร้อมกัน เช่น โทรศัพท์ส่วนตัวและโทรศัพท์งาน และโทรแบบแฮนด์ฟรีจากอุปกรณ์ใดก็ได้
ขีดจำกัดการเชื่อมต่อจะบังคับใช้โดยโปรไฟล์บลูทูธแต่ละรายการ โดยปกติแล้วจะอยู่ในการใช้งานบริการโปรไฟล์นั้นๆ โดยค่าเริ่มต้น CarBluetoothService จะไม่ตัดสินเพิ่มเติมเกี่ยวกับจำนวนอุปกรณ์ที่เชื่อมต่อสูงสุดที่อนุญาต
โปรไฟล์แฮนด์ฟรี
โปรไฟล์แฮนด์ฟรี (HFP) ของบลูทูธช่วยให้ยานพาหนะโทรออกและรับสายโทรศัพท์ผ่านอุปกรณ์ระยะไกลที่เชื่อมต่อได้ การเชื่อมต่ออุปกรณ์แต่ละรายการจะลงทะเบียนบัญชีโทรศัพท์แยกต่างหากกับ TelecomManager ซึ่งจะแสดงบัญชีโทรศัพท์ที่ใช้ได้ทั้งหมดแก่แอป IVI
IVI สามารถเชื่อมต่อกับอุปกรณ์หลายเครื่องผ่าน HFP MAX_STATE_MACHINES_POSSIBLE
MAXIMUM_CONNECTED_DEVICES
ใน
HeadsetClientService
กำหนดจำนวนการเชื่อมต่อ HFP สูงสุดพร้อมกัน
เมื่อผู้ใช้โทรออกหรือรับสายจากอุปกรณ์ บัญชีโทรศัพท์ที่เกี่ยวข้องจะสร้างออบเจ็กต์ HfpClientConnection
แอปโทรศัพท์โต้ตอบกับออบเจ็กต์ HfpClientConnection
เพื่อจัดการฟีเจอร์การโทร เช่น การยอมรับสายหรือวางสาย
โปรดทราบว่าแอปโทรศัพท์เริ่มต้นไม่รองรับอุปกรณ์ HFP ที่เชื่อมต่อพร้อมกันหลายเครื่อง หากต้องการใช้ HFP หลายอุปกรณ์ ต้องมีการปรับแต่งเพื่อให้ผู้ใช้เลือกบัญชีอุปกรณ์ที่จะใช้เมื่อโทรออก จากนั้นแอปจะโทรหา telecomManager.placeCall
ด้วยบัญชีที่ถูกต้อง คุณต้องตรวจสอบว่าฟังก์ชันการทำงานแบบหลายอุปกรณ์อื่นๆ ทำงานได้ตามที่ต้องการด้วย
ยืนยัน HFP สำหรับหลายอุปกรณ์
วิธีตรวจสอบว่าการเชื่อมต่อหลายอุปกรณ์ผ่านบลูทูธทำงานอย่างถูกต้อง
- ใช้บลูทูธเชื่อมต่ออุปกรณ์กับ IVI และสตรีมเสียงจากอุปกรณ์
- เชื่อมต่อโทรศัพท์ 2 เครื่องกับ IVI ผ่านบลูทูธ
- เลือกโทรศัพท์ 1 เครื่อง โทรออกโดยตรงจากโทรศัพท์ และโทรออกโดยใช้ IVI
- ตรวจสอบว่าเสียงที่สตรีมหยุดชั่วคราวและเสียงของโทรศัพท์เล่นผ่านลำโพงที่เชื่อมต่อ IVI ทั้งสองครั้ง
- รับสายเรียกเข้าโดยตรงในโทรศัพท์และรับสายเรียกเข้าโดยใช้ IVI โดยใช้โทรศัพท์เครื่องเดียวกัน
- ตรวจสอบว่าเสียงสตรีมมิงหยุดชั่วคราวและเสียงของโทรศัพท์เล่นผ่านลำโพงที่เชื่อมต่อ IVI ทั้งสองครั้ง
- ทำซ้ำขั้นตอนที่ 3 และ 4 ด้วยโทรศัพท์เครื่องอื่นที่เชื่อมต่ออยู่
การโทรหาหมายเลขฉุกเฉิน
ความสามารถในการโทรฉุกเฉินเป็นสิ่งสำคัญของฟังก์ชันโทรศัพท์และบลูทูธในรถยนต์ การโทรฉุกเฉินจาก IVI ทำได้หลายวิธี ดังนี้
- โซลูชัน eCall แบบสแตนด์อโลน
- โซลูชัน eCall ที่ผสานรวมเข้ากับ IVI
- การใช้โทรศัพท์ที่เชื่อมต่อบลูทูธเมื่อไม่มีระบบในตัว
เชื่อมต่อการโทรฉุกเฉิน
แม้ว่าอุปกรณ์ eCall จะมีความสำคัญต่อความปลอดภัย แต่ปัจจุบันอุปกรณ์ดังกล่าวยังไม่ผสานรวมกับ Android คุณสามารถใช้ ConnectionService เพื่อแสดงฟีเจอร์การโทรฉุกเฉินผ่าน 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); } }
เปิดใช้บลูทูธสำหรับการโทรหาหมายเลขฉุกเฉิน
การโทรหาหมายเลขฉุกเฉินก่อน 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 แยกต่างหาก ซึ่งจะทำให้รายชื่อติดต่อเชื่อมโยงกับอุปกรณ์ที่เหมาะสมเมื่อโทรออก
PBAP เป็นการเชื่อมต่อแบบทิศทางเดียว จึงกำหนดให้ IVI ต้องสร้างการเชื่อมต่อกับ MAXIMUM_CONNECTED_DEVICES
ใน
PbapClientService
ซึ่งจะกำหนดจำนวนการเชื่อมต่ออุปกรณ์ PBAP สูงสุดที่อนุญาตพร้อมกันกับ IVI ไคลเอ็นต์ PBAP จะจัดเก็บรายชื่อติดต่อของอุปกรณ์ที่เชื่อมต่อแต่ละเครื่องไว้ใน
ผู้ให้บริการรายชื่อติดต่อ จากนั้นแอปจะเข้าถึงเพื่อดึงข้อมูลสมุดโทรศัพท์ของอุปกรณ์แต่ละเครื่องได้
นอกจากนี้ ทั้ง IVI และอุปกรณ์เคลื่อนที่ต้องให้สิทธิ์การเชื่อมต่อโปรไฟล์จึงจะเชื่อมต่อได้ เมื่อไคลเอ็นต์ PBAP ตัดการเชื่อมต่อ ฐานข้อมูลภายในจะนำรายชื่อติดต่อและประวัติการโทรทั้งหมดที่เชื่อมโยงกับอุปกรณ์ที่เชื่อมต่อก่อนหน้านี้ออก
โปรไฟล์การเข้าถึงข้อความ
โปรไฟล์การเข้าถึงข้อความ (MAP) ของบลูทูธช่วยให้ยานพาหนะสามารถส่งและรับข้อความ SMS ผ่านอุปกรณ์ระยะไกลที่เชื่อมต่อ ปัจจุบันระบบไม่ได้จัดเก็บข้อความไว้ใน IVI แต่ทุกครั้งที่อุปกรณ์ระยะไกลที่เชื่อมต่ออยู่ได้รับข้อความ IVI จะรับและแยกวิเคราะห์ข้อความนั้น แล้วออกอากาศเนื้อหาในอินสแตนซ์ Intent ซึ่งแอปจะรับได้
IVI ต้องเริ่มการเชื่อมต่อ MAP เพื่อเชื่อมต่อกับอุปกรณ์เคลื่อนที่เพื่อส่งและรับข้อความ
MAXIMUM_CONNECTED_DEVICES
ใน
MapClientService
กำหนดจำนวนการเชื่อมต่ออุปกรณ์ MAP สูงสุดที่อนุญาตพร้อมกันกับ IVI IVI และอุปกรณ์เคลื่อนที่ต้องให้สิทธิ์การเชื่อมต่อแต่ละรายการก่อนจึงจะโอนข้อความได้
Advanced Audio Distribution Profile
โปรไฟล์การกระจายเสียงขั้นสูง (A2DP) ของบลูทูธช่วยให้รถยนต์รับสตรีมเสียงจากอุปกรณ์ระยะไกลที่เชื่อมต่อได้
ซึ่งแตกต่างจากโปรไฟล์อื่นๆ เนื่องจากระบบจะบังคับใช้จำนวนอุปกรณ์ A2DP ที่เชื่อมต่อได้สูงสุดในสแต็กเนทีฟ ไม่ใช่ใน Java ปัจจุบันค่านี้ได้รับการกำหนดค่าแบบฮาร์ดโค้ดเป็น 1
โดยใช้ตัวแปร kDefaultMaxConnectedAudioDevices
ใน
packages/modules/Bluetooth/system/btif/src/btif_av.cc
โปรไฟล์การควบคุมอุปกรณ์เสียง/วิดีโอจากระยะไกล
โปรไฟล์ควบคุมเสียง/วิดีโอระยะไกล (AVRCP) ของบลูทูธช่วยให้รถควบคุมและเรียกดูโปรแกรมเล่นสื่อในอุปกรณ์ระยะไกลที่เชื่อมต่อได้ เนื่องจาก IVI ทำหน้าที่เป็นตัวควบคุม AVRCP การควบคุมที่ทริกเกอร์ซึ่งส่งผลต่อการเล่นเสียงจึงต้องใช้การเชื่อมต่อ A2DP กับอุปกรณ์เป้าหมาย
หากต้องการให้ IVI เรียกดูโปรแกรมเล่นสื่อที่เฉพาะเจาะจงในโทรศัพท์ Android ผ่าน AVRCP ได้ แอปสื่อในโทรศัพท์ต้องระบุ
MediaBrowserService
และอนุญาตให้ com.android.bluetooth
เข้าถึงบริการนั้น
การสร้างบริการเบราว์เซอร์สื่อจะอธิบายวิธีการนี้โดยละเอียด