Android มีการใช้งานบลูทูธอย่างเต็มรูปแบบพร้อมรองรับโปรไฟล์บลูทูธในรถยนต์ทั่วไปหลายรายการ นอกจากนี้ ยังมีการปรับปรุงมากมายที่ช่วยเพิ่มประสิทธิภาพและประสบการณ์การใช้งานกับอุปกรณ์และ บริการอื่นๆ
การจัดการการเชื่อมต่อบลูทูธ
ภายใน Android CarBluetoothService จะเก็บรักษาอุปกรณ์บลูทูธของผู้ใช้ปัจจุบันและรายการลำดับความสำคัญ สำหรับการเชื่อมต่อโปรไฟล์แต่ละรายการกับ IVI อุปกรณ์จะเชื่อมต่อกับโปรไฟล์ตามลำดับความสำคัญที่ กำหนด ระบบจะกำหนดเวลาในการเปิดใช้ ปิดใช้ และเชื่อมต่ออุปกรณ์กับโปรไฟล์ตามนโยบายการเชื่อมต่อเริ่มต้น ซึ่งสามารถลบล้างได้โดยใช้ การซ้อนทับทรัพยากรหากต้องการ
กำหนดค่าการจัดการการเชื่อมต่อยานยนต์
ปิดใช้นโยบายโทรศัพท์เริ่มต้น
สแต็กบลูทูธของ Android จะเก็บรักษานโยบายการเชื่อมต่อสำหรับโทรศัพท์ซึ่งเปิดใช้โดย
ค่าเริ่มต้น คุณต้องปิดใช้นโยบายนี้ในอุปกรณ์เพื่อไม่ให้นโยบายขัดแย้งกับ
นโยบายยานยนต์ที่ต้องการใน
CarBluetoothService แม้ว่าการซ้อนทับผลิตภัณฑ์ Car จะจัดการเรื่องนี้ให้คุณ
คุณก็สามารถปิดใช้นโยบายโทรศัพท์ในการ
ซ้อนทับทรัพยากรได้โดยตั้งค่า 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
เปิดและปิดใช้อแดปเตอร์บลูทูธ
ฟังก์ชันหลักอย่างหนึ่งของนโยบายคือการเปิดและปิดใช้อแดปเตอร์บลูทูธในเวลาที่เหมาะสม
คุณสามารถใช้ 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); }
กำหนดเวลาที่จะเปิดและปิดใช้อแดปเตอร์บลูทูธ
นโยบายที่กำหนดเองช่วยให้คุณกำหนดเหตุการณ์ที่จะระบุเวลาที่ดีที่สุดในการ
เปิดและปิดใช้อแดปเตอร์ได้อย่างอิสระ วิธีหนึ่งในการดำเนินการนี้คือการใช้สถานะพลังงาน
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 ทั้ง 2 ครั้ง
- ใช้โทรศัพท์เครื่องเดียวกันเพื่อรับสายเรียกเข้าโดยตรงในโทรศัพท์ และ
รับสายเรียกเข้าโดยใช้ IVI
- ตรวจสอบว่าเสียงที่สตรีมหยุดชั่วคราวและเสียงโทรศัพท์เล่นผ่านลำโพงที่เชื่อมต่อกับ IVI ทั้ง 2 ครั้ง
- ทำซ้ำขั้นตอนที่ 3 และ 4 กับโทรศัพท์เครื่องอื่นที่เชื่อมต่อ
การโทรหาหมายเลขฉุกเฉิน
ความสามารถในการโทรหาหมายเลขฉุกเฉินเป็นส่วนสำคัญของฟังก์ชันโทรศัพท์และ บลูทูธในรถยนต์ คุณเริ่มการโทรหาหมายเลขฉุกเฉินจาก IVI ได้หลายวิธี ซึ่งรวมถึงวิธีต่อไปนี้
- โซลูชัน eCall แบบสแตนด์อโลน
- โซลูชัน eCall ที่ผสานรวมกับ IVI
- การใช้โทรศัพท์บลูทูธที่เชื่อมต่อเมื่อไม่มีระบบในตัว
เชื่อมต่อการโทรหาหมายเลขฉุกเฉิน
แม้ว่าอุปกรณ์ eCall จะมีความสำคัญต่อความปลอดภัย แต่ปัจจุบันอุปกรณ์นี้ยังไม่ได้ผสานรวมกับ Android คุณสามารถใช้ ConnectionService เพื่อแสดงฟีเจอร์การโทรหาหมายเลขฉุกเฉินผ่าน Android ซึ่งมีประโยชน์เพิ่มเติมคือ การนำเสนอตัวเลือกการช่วยเหลือพิเศษสำหรับการโทรหาหมายเลขฉุกเฉิน ดูข้อมูลเพิ่มเติมได้ที่ Building a calling app
ต่อไปนี้เป็นตัวอย่างวิธีสร้าง 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 จะจัดเก็บรายชื่อติดต่อสำหรับอุปกรณ์ที่เชื่อมต่อแต่ละเครื่องไว้ใน
Contacts Provider ซึ่งแอปจะเข้าถึงได้เพื่อรับสมุดโทรศัพท์สำหรับอุปกรณ์แต่ละเครื่อง
นอกจากนี้ ทั้ง IVI และ อุปกรณ์เคลื่อนที่ต้องให้สิทธิ์การเชื่อมต่อโปรไฟล์จึงจะทำการเชื่อมต่อได้ เมื่อไคลเอ็นต์ PBAP ยกเลิกการเชื่อมต่อ ฐานข้อมูลภายในจะนำรายชื่อติดต่อทั้งหมดและประวัติการโทรที่เชื่อมโยงกับ อุปกรณ์ที่เชื่อมต่อก่อนหน้านี้ออก
โปรไฟล์การเข้าถึงข้อความ
โปรไฟล์การเข้าถึงข้อความ (MAP) ของบลูทูธช่วยให้ยานพาหนะส่งและรับข้อความ SMS ผ่านอุปกรณ์ระยะไกลที่เชื่อมต่อได้ ปัจจุบันระบบไม่ได้จัดเก็บข้อความไว้ใน IVI แต่เมื่อใดก็ตามที่อุปกรณ์ระยะไกลที่เชื่อมต่อได้รับข้อความ IVI รับและแยกวิเคราะห์ข้อความ รวมถึงออกอากาศเนื้อหาของข้อความในอินสแตนซ์ Intent ซึ่งแอปจะรับได้
หากต้องการเชื่อมต่อกับอุปกรณ์เคลื่อนที่เพื่อส่งและรับ
ข้อความ IVI ต้องเริ่มการเชื่อมต่อ MAP
MAXIMUM_CONNECTED_DEVICES ใน
MapClientService จะกำหนดจำนวนการเชื่อมต่ออุปกรณ์ MAP พร้อมกันสูงสุดที่อนุญาตกับ IVI ทั้ง IVI และ
อุปกรณ์เคลื่อนที่ต้องให้สิทธิ์การเชื่อมต่อแต่ละรายการก่อนจึงจะโอนข้อความได้
โปรไฟล์การกระจายเสียงขั้นสูง
โปรไฟล์การกระจายเสียงขั้นสูง (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 เข้าถึง
บริการดังกล่าว
Building a media browser service อธิบายวิธีดำเนินการนี้โดยละเอียด