Bluetooth

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

Управление Bluetooth-подключением

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

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

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

Стек Bluetooth 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 .

Также политика управления подключением 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
  • Решение 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 и выше Dialer в автомобиле может напрямую вызывать номер экстренной помощи, при условии, что указано 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 хранит контакты для каждого подключенного устройства в Contacts Provider , к которому затем может получить доступ приложение для получения телефонной книги для каждого устройства.

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

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

Профиль доступа к сообщениям Bluetooth (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 .

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

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

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