Bluetooth

Android fournit une implémentation Bluetooth complète compatible avec de nombreux profils Bluetooth courants dans les voitures. De nombreuses améliorations ont également été apportées pour améliorer les performances et l'expérience avec d'autres appareils et services.

Gestion des connexions Bluetooth

Dans Android, CarBluetoothService gère les appareils Bluetooth de l'utilisateur actuel et les listes de priorité pour chaque connexion de profil à l'IVI. Les appareils sont connectés aux profils dans un ordre de priorité défini. L'activation, la désactivation et la connexion des appareils à un profil sont régies par une règle de connexion par défaut qui peut être remplacée à l'aide d'une superposition de ressources, si vous le souhaitez.

Configurer la gestion des connexions automobiles

Désactiver la règle de téléphone par défaut

La pile Bluetooth Android gère une règle de connexion pour les téléphones, qui est activée par défaut. Cette règle doit être désactivée sur votre appareil afin qu'elle n'entre pas en conflit avec la règle automobile prévue dans CarBluetoothService. Bien que la superposition de produits automobiles doive s'en charger pour vous, vous pouvez désactiver la règle de téléphone dans une superposition de ressources en définissant enable_phone_policy sur false dans MAXIMUM_CONNECTED_DEVICES dans /packages/apps/Bluetooth/res/values/config.xml.

Utiliser la règle automobile par défaut

CarBluetoothService gère les autorisations de profil par défaut. La liste des appareils connus et leurs priorités de reconnexion de profil se trouve dans service/src/com/android/car/BluetoothProfileDeviceManager.java.

La règle de gestion des connexions Bluetooth se trouve également dans service/src/com/android/car/BluetoothDeviceConnectionPolicy.java. Par défaut, cette règle définit les instances où le Bluetooth doit se connecter aux appareils associés et s'en déconnecter. Elle gère également les cas spécifiques aux voitures où l'adaptateur doit être activé et désactivé.

Créer votre propre règle de gestion des connexions automobiles personnalisée

Si la règle automobile par défaut ne répond pas à vos besoins, vous pouvez également la désactiver au profit de votre propre règle personnalisée. Votre règle personnalisée est au minimum chargée de déterminer quand activer et désactiver l'adaptateur Bluetooth, ainsi que quand connecter des appareils. Vous pouvez utiliser différents événements pour activer/désactiver l'adaptateur Bluetooth et lancer des connexions d'appareils, y compris des événements dus à des modifications de propriétés spécifiques de la voiture.

Désactiver la règle automobile par défaut

Tout d'abord, pour utiliser une règle personnalisée, la règle automobile par défaut doit être désactivée en définissant useDefaultBluetoothConnectionPolicy sur false dans une superposition de ressources. Cette ressource est initialement définie dans MAXIMUM_CONNECTED_DEVICES dans packages/services/Car/service/res/values/config.xml.

Activer et désactiver l'adaptateur Bluetooth

L'une des fonctions principales de votre règle consiste à activer et à désactiver l'adaptateur Bluetooth aux moments appropriés. Vous pouvez utiliser les BluetoothAdapter.enable() et BluetoothAdapter.disable() API de framework pour activer et désactiver l'adaptateur. Ces appels doivent respecter l'état persistant que l'utilisateur a sélectionné dans les paramètres ou par tout autre moyen. Voici une façon de procéder :

/**
 * 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);
}

Déterminer quand activer et désactiver l'adaptateur Bluetooth

Avec votre règle personnalisée, vous êtes libre de déterminer les événements qui indiquent les meilleurs moments pour activer et désactiver l'adaptateur. Vous pouvez par exemple utiliser les états d'alimentation MAXIMUM_CONNECTED_DEVICES dans 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;
        }
    }
};

Déterminer quand connecter des appareils

De même, lorsque vous déterminez les événements qui doivent déclencher le début des connexions d'appareils, CarBluetoothManager fournit l'appel d'API connectDevices() qui procède à la connexion des appareils en fonction des listes de priorité définies pour chaque profil Bluetooth.

Voici un exemple de cas où vous pouvez effectuer cette opération : chaque fois que l'adaptateur Bluetooth est activé :

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

Vérifier la gestion des connexions automobiles

Le moyen le plus simple de vérifier le comportement de votre règle de connexion consiste à activer le Bluetooth sur votre IVI et à vérifier qu'il se connecte automatiquement aux appareils appropriés dans l'ordre approprié. Vous pouvez activer ou désactiver l'adaptateur Bluetooth via l'interface utilisateur des paramètres ou à l'aide des commandes adb suivantes :

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

De plus, le résultat de la commande suivante peut être utilisé pour afficher des informations de débogage liées aux connexions Bluetooth :

adb shell dumpsys car_service

Enfin, si vous avez créé votre propre règle automobile, la vérification de tout comportement de connexion personnalisé nécessite de contrôler les événements que vous avez choisis pour déclencher les connexions d'appareils.

Profils Bluetooth automobiles

Dans Android, l'IVI peut prendre en charge plusieurs appareils connectés simultanément via Bluetooth. Les services téléphoniques Bluetooth multi-appareils permettent aux utilisateurs de connecter des appareils distincts simultanément, tels qu'un téléphone personnel et un téléphone professionnel, et de passer des appels en mode mains libres depuis l'un ou l'autre.

Les limites de connexion sont appliquées par chaque profil Bluetooth individuel, généralement dans l' implémentation du service de profil lui-même. Par défaut, CarBluetoothService ne porte aucun autre jugement sur le nombre maximal d'appareils connectés autorisés.

Profil mains libres

Le profil Bluetooth mains libres (HFP) permet au véhicule de passer et de recevoir des appels téléphoniques via un appareil distant connecté. Chaque connexion d'appareil enregistre un compte de téléphone distinct auprès de TelecomManager, qui annonce tous les comptes de téléphone disponibles aux applications IVI.

L'IVI peut se connecter à plusieurs appareils via HFP. MAX_STATE_MACHINES_POSSIBLE MAXIMUM_CONNECTED_DEVICES dans HeadsetClientService définit le nombre maximal de connexions HFP simultanées.

Lorsqu'un utilisateur passe ou reçoit un appel téléphonique depuis un appareil, le compte de téléphone correspondant crée un objet HfpClientConnection. L'application Téléphone interagit avec l'objet HfpClientConnection pour gérer les fonctionnalités d'appel, telles que l'acceptation d'un appel ou la fin de la communication.

Il convient de noter que l'application Téléphone par défaut n'est pas compatible avec plusieurs appareils HFP connectés simultanément. Pour implémenter HFP multi-appareils, une personnalisation est nécessaire pour permettre aux utilisateurs de sélectionner le compte d'appareil à utiliser lors d'un appel. L'application appelle ensuite telecomManager.placeCall avec le compte approprié. Vous devez également vérifier que les autres fonctionnalités multi-appareils fonctionnent comme prévu.

Vérifier HFP multi-appareils

Pour vérifier que la connectivité multi-appareils fonctionne correctement via Bluetooth :

  1. À l'aide du Bluetooth, connectez un appareil à l'IVI et diffusez de l'audio depuis l' appareil.
  2. Connectez deux téléphones à l'IVI via Bluetooth.
  3. Choisissez un téléphone. Passez un appel sortant directement depuis le téléphone, et passez un appel sortant à l'aide de l'IVI.
    1. Dans les deux cas, vérifiez que l'audio diffusé est mis en pause et que l'audio du téléphone est lu sur les haut-parleurs connectés à l'IVI.
  4. À l'aide du même téléphone, recevez un appel entrant directement sur le téléphone et recevez un appel entrant à l'aide de l'IVI.
    1. Dans les deux cas, vérifiez que l'audio diffusé est mis en pause et que l' audio du téléphone est lu sur les haut-parleurs connectés à l'IVI.
  5. Répétez les étapes 3 et 4 avec l'autre téléphone connecté.

Appels d'urgence

La possibilité de passer des appels d'urgence est un aspect important des fonctions de téléphonie et Bluetooth dans la voiture. Il existe plusieurs façons de lancer un appel d'urgence depuis l'IVI, y compris :

  • Solution eCall autonome
  • Solution eCall intégrée à l'IVI
  • S'appuyer sur un téléphone Bluetooth connecté lorsqu'aucun système intégré n'est disponible

Connecter un appel d'urgence

Bien que l'équipement eCall soit essentiel pour la sécurité, il n'est actuellement pas intégré à Android. Vous pouvez utiliser ConnectionService pour exposer les fonctionnalités d'appel d'urgence via Android, ce qui présente également l'avantage d'introduire des options d'accessibilité pour les appels d'urgence. Pour en savoir plus, consultez Créer une application d'appel.

Voici un exemple d'établissement d'un service ConnectionService d'urgence :

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

Activer le Bluetooth pour les appels d'urgence

Avant Android 10, les appels d'urgence impliquaient une numérotation directe depuis un téléphone et l'appel d'un équipement spécial si disponible (par exemple, un déclenchement automatique lors de la détection d'un danger ou d'une action de l'utilisateur). Dans Android 10 et versions ultérieures, l'application Téléphone de la voiture peut appeler directement un numéro d'urgence, à condition que MAXIMUM_CONNECTED_DEVICES dans 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>

En implémentant les appels d'urgence de cette manière, d'autres applications, telles que la reconnaissance vocale, peuvent également appeler un numéro d'urgence.

Profil d'accès au répertoire téléphonique

Le profil Bluetooth d'accès au répertoire téléphonique (PBAP) télécharge les contacts et les historiques d'appels depuis un appareil distant connecté. PBAP gère une liste agrégée et consultable de contacts mise à jour par la machine d'état du client PBAP. Chaque appareil connecté interagit avec une machine d'état de client PBAP distincte, ce qui permet d'associer les contacts à l'appareil approprié lors d'un appel.

PBAP est unidirectionnel et nécessite donc que l'IVI instancie des connexions à n'importe quel MAXIMUM_CONNECTED_DEVICES dans PbapClientService définit le nombre maximal de connexions d'appareils PBAP simultanées autorisées avec l'IVI. Le client PBAP stocke les contacts de chaque appareil connecté dans le Contacts Provider, auquel une application peut ensuite accéder pour obtenir le répertoire téléphonique de chaque appareil.

De plus, la connexion de profil doit être autorisée à la fois par l'IVI et le appareil mobile pour qu'une connexion puisse être établie. Lorsqu'un client PBAP se déconnecte, la base de données interne supprime tous les contacts et l'historique des appels associés à l'appareil précédemment connecté.

Profil d'accès aux messages

Le profil Bluetooth d'accès aux messages (MAP) permet au véhicule d'envoyer et de recevoir des SMS messages via un appareil distant connecté. Actuellement, les messages ne sont pas stockés localement sur l'IVI. Au lieu de cela, chaque fois que l'appareil distant connecté reçoit un message, l'IVI le reçoit et l'analyse, puis diffuse son contenu dans une instance Intent, qui peut ensuite être reçue par une application.

Pour se connecter à un appareil mobile afin d'envoyer et de recevoir messages, l'IVI doit lancer la connexion MAP. MAXIMUM_CONNECTED_DEVICES dans MapClientService définit le nombre maximal de connexions d'appareils MAP simultanées autorisées avec l'IVI. Chaque connexion doit être autorisée par l'IVI et le appareil mobile avant que les messages puissent être transférés.

Profil de distribution audio avancé

Le profil Bluetooth de distribution audio avancé (A2DP) permet au véhicule de recevoir des flux audio depuis un appareil distant connecté.

Contrairement à d'autres profils, le nombre maximal d'appareils A2DP connectés est appliqué dans la pile native et non en Java. La valeur est actuellement codée en dur sur 1 à l'aide de la variable kDefaultMaxConnectedAudioDevices dans packages/modules/Bluetooth/system/btif/src/btif_av.cc.

Profil de télécommande audio/vidéo

Le profil Bluetooth de télécommande audio/vidéo (AVRCP) permet au véhicule de contrôler et de parcourir les lecteurs multimédias sur un appareil distant connecté. Étant donné que l'IVI joue le rôle de contrôleur AVRCP, tous les contrôles déclenchés qui affectent la lecture audio s'appuient sur une connexion A2DP à l'appareil cible.

Pour qu'un lecteur multimédia spécifique sur un téléphone Android puisse être parcouru par l'IVI via AVRCP, l'application multimédia du téléphone doit fournir un MediaBrowserService et autoriser l'accès com.android.bluetooth à ce service. La section Créer un service de navigateur multimédia explique en détail comment procéder.