Bluetooth

Android обеспечивает полную реализацию Bluetooth с поддержкой многих распространенных профилей Bluetooth в автомобиле. Также имеется множество улучшений, улучшающих производительность и удобство работы с другими устройствами и службами.

Управление Bluetooth-соединением

В Android CarBluetoothService поддерживает устройства Bluetooth текущего пользователя и списки приоритетов для каждого профиля подключения к IVI. Устройства подключаются к профилям в определенном порядке приоритета. Когда включать, отключать и подключать устройства к профилю, определяется политикой подключения по умолчанию, которую при желании можно переопределить с помощью наложения ресурса .

Настройка управления автомобильными соединениями

Отключить политику телефона по умолчанию

Стек Android Bluetooth поддерживает политику подключения для телефонов, которая включена по умолчанию. Эту политику необходимо отключить на вашем устройстве, чтобы она не конфликтовала с предполагаемой автомобильной политикой в ​​CarBluetoothService . Хотя оверлей продукта Car должен позаботиться об этом за вас, вы можете отключить политику телефона в оверлее ресурса , установив для enable_phone_policy значение false в MAXIMUM_CONNECTED_DEVICES в /packages/apps/Bluetooth/res/values/config.xml .

Использовать автомобильную политику по умолчанию

CarBluetoothService сохраняет разрешения профиля по умолчанию. Список известных устройств и приоритеты повторного подключения их профилей находятся в service/src/com/android/car/BluetoothProfileDeviceManager.java .

Кроме того, политику управления соединениями Bluetooth можно найти в service/src/com/android/car/BluetoothDeviceConnectionPolicy.java . По умолчанию эта политика определяет случаи, когда Bluetooth должен подключаться к подключенным устройствам и отключаться от них. Он также управляет конкретными автомобильными случаями, когда адаптер следует включать и выключать.

Создайте собственную политику управления автомобильными подключениями.

Если автомобильной политики по умолчанию недостаточно для ваших нужд, ее также можно отключить в пользу вашей собственной пользовательской политики. Ваша пользовательская политика, как минимум, отвечает за определение того, когда включать и отключать адаптер Bluetooth, а также когда подключать устройства. Для включения/отключения адаптера Bluetooth и инициации подключения устройств можно использовать различные события, в том числе события, связанные с изменением конкретных свойств автомобиля.

Отключить автомобильную политику по умолчанию

Во-первых, чтобы использовать пользовательскую политику, автомобильную политику по умолчанию необходимо отключить, задав useDefaultBluetoothConnectionPolicy значение false в наложении ресурса . Этот ресурс изначально определен как часть MAXIMUM_CONNECTED_DEVICES в packages/services/Car/service/res/values/config.xml .

Включить и отключить адаптер Bluetooth

Одна из основных функций вашей политики — включение и выключение адаптера Bluetooth в подходящее время. Вы можете использовать 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);
}

Определите, когда включать и выключать адаптер Bluetooth

С помощью вашей пользовательской политики вы можете определить, какие события указывают на лучшее время для включения и отключения адаптера. Один из таких способов сделать это — использовать состояния питания 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() , который приступает к подключению устройств на основе списков приоритетов, определенных для каждого профиля Bluetooth.

Одним из примеров того, когда вы можете это сделать, является каждый раз, когда включается адаптер Bluetooth:

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();
            }
        }
    }
}

Проверка управления автомобильными соединениями

Самый простой способ проверить поведение вашей политики подключения — включить Bluetooth на вашем IVI и убедиться, что он автоматически подключается к нужным устройствам в соответствующем порядке. Вы можете переключить адаптер Bluetooth через пользовательский интерфейс настроек или с помощью следующих команд 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

Кроме того, выходные данные следующей команды можно использовать для просмотра отладочной информации, связанной с соединениями Bluetooth:

adb shell dumpsys car_service

Наконец, если вы создали собственную автомобильную политику, проверка любого пользовательского поведения подключения требует управления событиями, которые вы выбрали для запуска подключений устройств.

Автомобильные профили Bluetooth

В Android IVI может поддерживать несколько устройств, подключенных одновременно через Bluetooth. Телефонные службы Bluetooth для нескольких устройств позволяют пользователям одновременно подключать отдельные устройства, например личный телефон и рабочий телефон, и совершать звонки в режиме громкой связи с любого устройства.

Ограничения на подключение устанавливаются каждым отдельным профилем Bluetooth, обычно в рамках реализации самой службы профилей. По умолчанию CarBluetoothService не принимает дальнейших решений относительно максимально допустимого количества подключенных устройств.

Профиль громкой связи

Профиль Bluetooth Hands-Free (HFP) позволяет автомобилю совершать и принимать телефонные звонки через подключенное удаленное устройство. Каждое подключение устройства регистрирует отдельную учетную запись телефона в TelecomManager , который объявляет любые доступные учетные записи телефона приложениям IVI.

IVI может подключаться к нескольким устройствам через HFP. MAX_STATE_MACHINES_POSSIBLE MAXIMUM_CONNECTED_DEVICES в HeadsetClientService определяет максимальное количество одновременных подключений HFP.

Когда пользователь совершает или принимает телефонный звонок с устройства, соответствующая учетная запись телефона создает объект HfpClientConnection . Приложение Dialer взаимодействует с объектом HfpClientConnection для управления функциями вызова, такими как принятие вызова или завершение разговора.

Следует отметить, что приложение Dialer по умолчанию не поддерживает несколько одновременно подключенных устройств HFP. Для реализации HFP с несколькими устройствами необходима настройка, позволяющая пользователям выбирать, какую учетную запись устройства использовать при совершении вызова. Затем приложение вызывает telecomManager.placeCall с правильной учетной записью. Вам необходимо убедиться, что другие функции работы с несколькими устройствами также работают должным образом.

Проверка HFP для нескольких устройств

Чтобы проверить правильность работы подключения нескольких устройств через Bluetooth:

  1. Используя Bluetooth, подключите устройство к IVI и транслируйте звук с устройства.
  2. Подключите два телефона к IVI через Bluetooth.
  3. Выберите один телефон. Выполните исходящий вызов непосредственно с телефона и выполните исходящий вызов с помощью IVI.
    1. Оба раза проверьте, что потоковая передача звука приостанавливается и звук телефона воспроизводится через подключенные динамики IVI.
  4. Используя тот же телефон, примите входящий вызов прямо на телефон и примите входящий вызов с помощью IVI.
    1. Оба раза проверьте, что потоковое аудио приостанавливается и звук телефона воспроизводится через подключенные динамики IVI.
  5. Повторите шаги 3 и 4 с другим подключенным телефоном.

Экстренный вызов

Возможность совершать экстренные вызовы — важный аспект функций телефонии и Bluetooth в автомобиле. Существует несколько способов инициировать вызов службы экстренной помощи с IVI, в том числе:

  • Автономное решение для электронных звонков
  • Решение eCall, интегрированное в IVI
  • Использование подключенного телефона Bluetooth, когда встроенная система недоступна

Подключите экстренный вызов

Хотя оборудование 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);
    }
}

Включить Bluetooth для экстренных вызовов

Вызов службы экстренной помощи до 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 (PBAP) загружает контакты и историю вызовов с подключенного удаленного устройства. PBAP поддерживает агрегированный список контактов с возможностью поиска, который обновляется конечным автоматом клиента PBAP. Каждое подключенное устройство взаимодействует с отдельным конечным автоматом клиента PBAP, в результате чего при совершении вызова контакты связываются с соответствующим устройством.

PBAP является однонаправленным и поэтому требует, чтобы IVI создавал экземпляры подключений к любому MAXIMUM_CONNECTED_DEVICES в PbapClientService , определяющем максимальное количество одновременных подключений устройств PBAP, разрешенных с помощью IVI. Клиент PBAP сохраняет контакты для каждого подключенного устройства в поставщике контактов , к которому затем может получить доступ приложение для получения телефонной книги для каждого устройства.

Кроме того, для установки соединения профиль должен быть авторизован как IVI, так и мобильным устройством. Когда клиент PBAP отключается, внутренняя база данных удаляет все контакты и историю вызовов, связанные с ранее подключенным устройством.

Профиль доступа к сообщениям

Профиль доступа к сообщениям Bluetooth (MAP) позволяет автомобилю отправлять и получать SMS-сообщения через подключенное удаленное устройство. В настоящее время сообщения не хранятся локально на IVI. Вместо этого всякий раз, когда подключенное удаленное устройство получает сообщение, IVI получает и анализирует сообщение и передает его содержимое в экземпляре намерения , которое затем может быть получено приложением.

Чтобы подключиться к мобильному устройству с целью отправки и получения сообщений, IVI должен инициировать соединение MAP. MAXIMUM_CONNECTED_DEVICES в MapClientService определяет максимальное количество одновременных подключений устройств MAP, разрешенных с помощью IVI. Перед передачей сообщений каждое соединение должно быть авторизовано IVI и мобильным устройством.

Расширенный профиль распространения аудио

Профиль расширенного распределения звука Bluetooth (A2DP) позволяет автомобилю получать аудиопотоки от подключенного удаленного устройства.

В отличие от других профилей, максимальное количество подключенных устройств A2DP устанавливается в собственном стеке, а не в Java. В настоящее время это значение жестко закодировано как 1 с использованием переменной kDefaultMaxConnectedAudioDevices в packages/modules/Bluetooth/system/btif/src/btif_av.cc .

Профиль дистанционного управления аудио/видео

Профиль дистанционного управления аудио/видео Bluetooth (AVRCP) позволяет автомобилю управлять медиаплеерами и просматривать их на подключенном удаленном устройстве. Поскольку IVI играет роль контроллера AVRCP, любые триггерные элементы управления, влияющие на воспроизведение звука, зависят от соединения A2DP с целевым устройством.

Чтобы определенный медиаплеер на телефоне Android можно было просматривать с помощью IVI через AVRCP, мультимедийное приложение на телефоне должно предоставить MediaBrowserService и разрешить com.android.bluetooth доступ к этой службе. Создание службы медиабраузера подробно объясняет, как это сделать.