บลูทูธ

Android มีบลูทูธเต็มรูปแบบ พร้อมรองรับโปรไฟล์บลูทูธในรถยนต์โดยทั่วไป นอกจากนี้ยังมี การเพิ่มประสิทธิภาพหลายอย่างที่ช่วยปรับปรุงประสิทธิภาพและประสบการณ์ใช้งานอุปกรณ์อื่นๆ และ บริการต่างๆ

การจัดการการเชื่อมต่อบลูทูธ

ใน Android Car BluetoothService จะดูแลอุปกรณ์บลูทูธและลำดับความสำคัญของผู้ใช้ปัจจุบัน รายการสำหรับแต่ละการเชื่อมต่อโปรไฟล์กับ IVI อุปกรณ์เชื่อมต่อกับโปรไฟล์ใน ลำดับความสำคัญที่กำหนดไว้ เมื่อใดที่ควรเปิดใช้ ปิดใช้ และเชื่อมต่ออุปกรณ์กับโปรไฟล์ เกิดขึ้นจากนโยบายการเชื่อมต่อเริ่มต้น ซึ่งสามารถลบล้างด้วยการใช้ การซ้อนทับทรัพยากรหาก ที่ต้องการ

กำหนดค่าการจัดการการเชื่อมต่อยานยนต์

ปิดใช้นโยบายโทรศัพท์เริ่มต้น

สแต็กบลูทูธของ Android จะรักษานโยบายการเชื่อมต่อสำหรับโทรศัพท์ที่เปิดใช้โดย "ค่าเริ่มต้น" คุณต้องปิดใช้นโยบายนี้ในอุปกรณ์เพื่อไม่ให้ขัดแย้งกับ นโยบายยานยนต์ใน Car BluetoothService แม้ว่าการวางซ้อนผลิตภัณฑ์ "รถยนต์" จะช่วยแก้ไขปัญหานี้ คุณจะปิดใช้งานนโยบายโทรศัพท์ได้ใน การวางซ้อนทรัพยากรโดยการตั้งค่า 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 เรียก API ของ 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 ของคุณ และตรวจสอบว่า 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 สามารถรองรับอุปกรณ์หลายเครื่องที่เชื่อมต่อพร้อมกัน ผ่านบลูทูธ บริการโทรศัพท์บลูทูธแบบหลายอุปกรณ์ช่วยให้ผู้ใช้เชื่อมต่อได้ อุปกรณ์แยกกันในเวลาเดียวกัน เช่น โทรศัพท์ส่วนตัว และโทรศัพท์ที่ทำงาน 1 โทรออกแบบแฮนด์ฟรีจากอุปกรณ์เครื่องใดก็ได้

โปรไฟล์บลูทูธแต่ละโปรไฟล์จะเป็นตัวกำหนดขีดจำกัดการเชื่อมต่อ ซึ่งโดยปกติจะอยู่ภายใน การใช้บริการโปรไฟล์ด้วยตนเอง โดยค่าเริ่มต้น Car BluetoothService จะตัดสินเพิ่มเติมเกี่ยวกับจำนวนการเชื่อมต่อสูงสุดที่เชื่อมต่อไม่ได้ อุปกรณ์ที่อนุญาต

โปรไฟล์แฮนด์ฟรี

โปรไฟล์แฮนด์ฟรีบลูทูธ (HFP) ช่วยให้รถยนต์โทรออกและรับสายได้ การโทรผ่านอุปกรณ์ระยะไกลที่เชื่อมต่ออยู่ การเชื่อมต่ออุปกรณ์แต่ละครั้งจะลงทะเบียนโทรศัพท์คนละเครื่อง บัญชีกับ TelecomManager ซึ่งจะโฆษณาบัญชีโทรศัพท์ที่พร้อมใช้งานกับแอป IVI

IVI เชื่อมต่อกับอุปกรณ์หลายเครื่องผ่าน HFP ได้ MAX_STATE_MACHINES_POSSIBLE MAXIMUM_CONNECTED_DEVICES ใน HeadsetClientService กำหนดจำนวน HFP พร้อมกันสูงสุด การเชื่อมต่อ

เมื่อผู้ใช้โทรออกหรือรับสายจากอุปกรณ์ อุปกรณ์ บัญชีโทรศัพท์สร้างออบเจ็กต์ HfpClientConnection แอปแป้นโทรศัพท์ โต้ตอบกับออบเจ็กต์ HfpClientConnection เพื่อจัดการการโทร เช่น การรับสายหรือวางสาย

โปรดทราบว่าแอปโทรศัพท์เริ่มต้นไม่รองรับการใช้หลายบัญชีพร้อมกัน อุปกรณ์ HFP ที่เชื่อมต่ออยู่ ในการใช้ HFP หลายอุปกรณ์ จะต้องมีการปรับแต่ง เพื่อให้ผู้ใช้เลือกบัญชีอุปกรณ์ที่จะใช้เมื่อโทรออกได้ จากนั้นแอป โทรหา telecomManager.placeCall ด้วยบัญชีที่ถูกต้อง สิ่งที่คุณต้องทำ ตรวจสอบว่าฟังก์ชันการทำงานอื่นๆ ของหลายอุปกรณ์ทำงานได้ตามที่ตั้งใจไว้เช่นกัน

ยืนยัน HFP หลายอุปกรณ์

วิธีตรวจสอบว่าการเชื่อมต่อหลายอุปกรณ์ทำงานอย่างถูกต้องผ่านบลูทูธ

  1. ใช้บลูทูธ เชื่อมต่ออุปกรณ์กับ IVI และสตรีมเสียงจาก อุปกรณ์
  2. เชื่อมต่อโทรศัพท์ 2 เครื่องเข้ากับ IVI ผ่านบลูทูธ
  3. เลือกโทรศัพท์ 1 เครื่อง โทรออกจากโทรศัพท์โดยตรง และโทรออกโดยใช้ IVI
    1. ทั้ง 2 ครั้ง ให้ยืนยันว่าเสียงที่สตรีมหยุดชั่วคราวและเสียงในโทรศัพท์ จะเล่นผ่านลำโพงที่เชื่อมต่อ IVI
  4. รับสายเรียกเข้าทางโทรศัพท์โดยตรงโดยใช้โทรศัพท์เครื่องเดียวกัน และ รับสายเรียกเข้าโดยใช้ IVI
    1. ให้ยืนยันการหยุดเสียงสตรีมมิงชั่วคราวและ เสียงของโทรศัพท์จะเล่นผ่านลำโพงที่เชื่อมต่อ IVI
  5. ทำขั้นตอนที่ 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>

การโทรหาหมายเลขฉุกเฉินในลักษณะนี้จะทำให้แอปอื่นๆ เช่น การจดจำเสียง สามารถทำสิ่งต่อไปนี้ได้ โทรหาหมายเลขฉุกเฉินได้ด้วย

โปรไฟล์การเข้าถึงสมุดโทรศัพท์

Bluetooth Phone Book Access Profile (PBAP) จะดาวน์โหลดรายชื่อติดต่อและประวัติการโทร จากอุปกรณ์ระยะไกลที่เชื่อมต่ออยู่ PBAP รักษารายการที่รวบรวมไว้และค้นหาได้ของ รายชื่อติดต่อที่อัปเดตโดยเครื่องสถานะไคลเอ็นต์ PBAP อุปกรณ์ที่เชื่อมต่อแต่ละเครื่อง มีการโต้ตอบกับเครื่องสถานะไคลเอ็นต์ PBAP แยกต่างหาก เป็นผลให้รายชื่อติดต่อ ที่เชื่อมโยงกับอุปกรณ์ที่เหมาะสมเมื่อโทรออก

PBAP เป็นการทำงานแบบทิศทางเดียว ดังนั้นจึงต้องใช้ IVI เพื่อสร้างการเชื่อมต่อกับ MAXIMUM_CONNECTED_DEVICES นิ้ว PbapClientService กำหนดจำนวนอุปกรณ์ PBAP พร้อมกันสูงสุด อนุญาตการเชื่อมต่อด้วย IVI ไคลเอ็นต์ PBAP จะจัดเก็บรายชื่อติดต่อสำหรับ อุปกรณ์ที่เชื่อมต่อใน ผู้ให้บริการรายชื่อติดต่อ ซึ่งแอปสามารถเข้าถึงได้เพื่อดึงข้อมูลโทรศัพท์ สำหรับอุปกรณ์แต่ละเครื่อง

นอกจากนี้ การเชื่อมต่อโปรไฟล์ต้องได้รับอนุญาตจากทั้ง IVI และ อุปกรณ์เคลื่อนที่ เพื่อให้สามารถเชื่อมต่อได้ เมื่อไคลเอ็นต์ PBAP ตัดการเชื่อมต่อ ฐานข้อมูลภายในจะนำที่อยู่ติดต่อและประวัติการโทรที่เชื่อมโยงกับ อุปกรณ์ที่เชื่อมต่อก่อนหน้านี้

โปรไฟล์การเข้าถึงข้อความ

Bluetooth Message Access Profile (MAP) ช่วยให้รถยนต์ส่งและรับ SMS ได้ ข้อความผ่านอุปกรณ์ระยะไกลที่เชื่อมต่ออยู่ ในขณะนี้ ข้อความต่างๆ ไม่ได้จัดเก็บภายในเครื่องบน IVI เมื่อใดก็ตามที่อุปกรณ์ระยะไกลที่เชื่อมต่อได้รับข้อความ IVI รับและแยกวิเคราะห์ข้อความ และประกาศเนื้อหาใน Intent ซึ่งแอปสามารถรับได้

ในการเชื่อมต่อกับอุปกรณ์เคลื่อนที่เพื่อจุดประสงค์ในการส่งและรับ IVI จะต้องเริ่มต้นการเชื่อมต่อ MAP MAXIMUM_CONNECTED_DEVICES ใน MapClientService กำหนดจำนวนอุปกรณ์ MAP พร้อมกันสูงสุด อนุญาตการเชื่อมต่อด้วย IVI การเชื่อมต่อแต่ละครั้งต้องได้รับอนุญาตจาก IVI และ อุปกรณ์เคลื่อนที่ก่อนที่จะโอนข้อความได้

โปรไฟล์การกระจายเสียงขั้นสูง

Bluetooth Advanced Audio Distribution Profile (A2DP) ช่วยให้รถได้รับ สตรีมเสียงจากอุปกรณ์ระยะไกลที่เชื่อมต่ออยู่

โปรไฟล์นี้แตกต่างจากโปรไฟล์อื่นๆ ตรงที่มีการบังคับใช้จำนวนอุปกรณ์ A2DP สูงสุดที่เชื่อมต่อใน สแต็กดั้งเดิม ไม่ใช่ใน Java ขณะนี้ค่านี้ถูกฮาร์ดโค้ดเป็น 1 โดยใช้ ตัวแปร kDefaultMaxConnectedAudioDevices ใน packages/modules/Bluetooth/system/btif/src/btif_av.cc

โปรไฟล์ควบคุมเสียง/วิดีโอระยะไกล

โปรไฟล์ควบคุมเสียง/วิดีโอระยะไกล (AVRCP) ของบลูทูธช่วยให้รถควบคุมได้ และเรียกดูมีเดียเพลเยอร์ บนอุปกรณ์ระยะไกลที่เชื่อมต่ออยู่ เนื่องจาก IVI มีบทบาท ตัวควบคุม AVRCP โดยการควบคุมที่ทริกเกอร์ซึ่งส่งผลต่อการเล่นเสียงต้องอาศัย A2DP เชื่อมต่อกับอุปกรณ์เป้าหมาย

สำหรับมีเดียเพลเยอร์ที่เจาะจงในโทรศัพท์ Android ให้ IVI เรียกดูผ่าน AVRCP ได้ แอปสื่อบนโทรศัพท์ต้องระบุ MediaBrowserService และอนุญาตให้ com.android.bluetooth เข้าถึง บริการนั้น การสร้างบริการเบราว์เซอร์สื่อจะอธิบายวิธีการโดยละเอียด