藍牙

Android 提供完整藍牙 實作,支援許多常見的車內藍牙設定檔。此外, 許多強化功能可改善其他裝置的使用體驗與使用體驗,並 免費 Google Cloud 服務

藍牙連線管理

在 Android 中, CarBluetoothService 能維護目前使用者的藍牙裝置和優先順序 每個設定檔連結的 IVI 都會有一份清單。裝置會連線至以下設定檔中的設定檔: 定義優先順序啟用、停用裝置並連結至設定檔的時機為 由預設連線政策驅動,可以使用 資源疊加層 (如果有的話)

設定汽車連線管理

停用預設手機政策

Android 藍牙堆疊會為 預設值。你必須在裝置上停用這項政策,以免與 或其他國家/地區 CarBluetoothService」。雖然車輛產品疊加層應為你處理這個問題 可以在 資源重疊,方法是將 enable_phone_policy 設為 false /packages/apps/Bluetooth/res/values/config.xml 中的 MAXIMUM_CONNECTED_DEVICES

使用預設汽車政策

CarBluetoothService 會維持預設的設定檔權限。由於您必須建立 裝置與設定檔重新連線的優先目標為 service/src/com/android/car/BluetoothProfileDeviceManager.java

您也可以在 service/src/com/android/car/BluetoothDeviceConnectionPolicy.java 中找到藍牙連線管理政策。根據預設 這項政策會定義藍牙連線和連線中斷時間的執行個體 裝置。這項設定還可管理車輛專用保護殼的開啟時機 關閉。

建立自訂汽車連線管理政策

如果預設汽車政策不符合您的需求,也可以停用政策 而非自訂政策您的自訂政策至少要負責 ,以決定何時啟用和停用藍牙轉接器,以及何時 連線裝置。你可以透過各種事件啟用/停用藍牙 及啟動裝置連線,包括因特定 。

停用預設汽車政策

您必須先將預設汽車政策停用,才能使用自訂政策 在useDefaultBluetoothConnectionPolicyfalse 資源重疊」。 這項資源原先定義為 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 與 。您可以透過設定使用者介面切換藍牙轉接器,或 以下 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

最後,如果您自行建立汽車政策,驗證所有自訂連線 必須控制您選擇觸發裝置的事件 連線狀態。

Automotive 藍牙設定檔

在 Android 中,IVI 可以支援同時連接多部裝置 透過藍牙多裝置藍牙電話服務可讓使用者 同時讓兩部裝置同時運作 (例如個人手機和公司手機),並 。

每個個別藍牙設定檔都會強制執行連線限制,通常在 實作設定檔服務本身的實作。根據預設 CarBluetoothService 不會進一步決定連線數量上限 已允許裝置。

免持聽筒設定檔

藍牙免持聽筒設定檔 (HFP) 可讓車輛收發手機 透過連線的遠端裝置進行通話每部裝置連線都會註冊獨立的手機 帳戶: TelecomManager,向 IVI 應用程式宣傳任何可用的手機帳戶。

IVI 可以透過 HFP 連線至多部裝置。MAX_STATE_MACHINES_POSSIBLE HeadsetClientService 中的 MAXIMUM_CONNECTED_DEVICES 定義同時的 HFP 數量上限 連線狀態。

當使用者透過裝置撥打或接聽電話時,相應應用程式的 手機帳戶會建立 HfpClientConnection 物件。「撥號」應用程式 與 HfpClientConnection 物件互動以管理呼叫 功能,例如接聽來電或掛斷電話。

請注意,預設的撥號應用程式無法同時支援多個 連線 HFP 裝置如要導入多裝置 HFP,必須自訂設定 ,讓使用者選取撥打電話時要使用的裝置帳戶。接著 使用正確的帳戶呼叫 telecomManager.placeCall。您需要執行的操作 確認其他多裝置功能正常運作

驗證多裝置 HFP

如何透過藍牙檢查多裝置連線是否正常運作:

  1. 使用藍牙將裝置連線到 IVI,然後透過 裝置。
  2. 透過藍牙將兩支手機連線至 IVI。
  3. 挑選一支手機。直接透過電話撥出電話、 然後使用 IVI 撥打電話
    1. 兩次都檢查串流音訊是否暫停和手機音訊 透過 IVI 連線的喇叭播放。
  4. 使用同一支手機直接接聽電話。 使用 IVI 接聽來電。
    1. 這兩種方式都檢查串流音訊是否暫停,以及 手機音訊會透過與 IVI 連線的喇叭播放。
  5. 使用另一個已連結的手機重複執行步驟 3 和 4。

緊急電話撥號

能夠撥打緊急電話 在車內開啟藍牙功能。緊急電話可透過多種方式撥打, 是從 IVI 啟動,包括:

  • 獨立電子通話解決方案
  • 整合於 IVI 的電子通話解決方案
  • 在沒有內建系統的情況下,使用已連線的藍牙手機

撥打緊急電話

雖然電費設備具有安全感,但目前尚未與 Android 整合。 您可能可以使用 ConnectionServiceAndroid 手機,顯示緊急電話撥號功能, 為緊急電話導入無障礙選項的好處詳情請參閱: 建構通話應用程式

以下範例說明如何設定緊急事件 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) 可讓車輛收發簡訊 透過連線的遠端裝置傳送訊息。目前,訊息並非儲存在本機 IVI。相反地,每當已連線的遠端裝置收到訊息時,IVI 接收及剖析訊息,並在 Intent 執行個體, 應用程式接收的指令

為了連線至行動裝置以便收發郵件 訊息,IVI 必須啟動 MAP 連線。 MapClientService 中的 MAXIMUM_CONNECTED_DEVICES 定義同時發生的 MAP 裝置數量上限 連線允許與 IVI 連線。每個連線都必須由 IVI 和 行動裝置,系統才能傳輸訊息。

進階音訊發布設定檔

藍牙進階音訊發布設定檔 (A2DP) 可讓車輛接收 擷取音訊串流。

與其他設定檔不同,系統會在 而非 Java 中此值目前硬式編碼為 1kDefaultMaxConnectedAudioDevices 變數用於 packages/modules/Bluetooth/system/btif/src/btif_av.cc

音訊/視訊遠端控制設定檔

藍牙音訊/視訊遙控設定檔 (AVRCP) 可讓車輛控制 並透過連線的遠端裝置瀏覽媒體播放器IVI 扮演著角色 AVRCP 控制器,任何會影響音訊播放的觸發控制項都必須使用 A2DP 連線至目標裝置

如要讓 IVI 透過 AVRCP 瀏覽 Android 手機上的特定媒體播放器, 手機上的媒體應用程式必須提供 「 MediaBrowserService」並將存取權授予「com.android.bluetooth」 該服務。 建立媒體瀏覽器服務的詳細做法。