Bluetooth

Android fournit une implémentation Bluetooth complète avec prise en charge de nombreux profils Bluetooth courants dans les voitures. Il existe également de nombreuses améliorations qui améliorent les performances et l'expérience avec d'autres appareils et services.

Gestion de la connexion Bluetooth

Dans Android, CarBluetoothService gère les appareils Bluetooth de l'utilisateur actuel et les listes de priorités pour chaque connexion de profil à l'IVI. Les appareils sont connectés aux profils dans un ordre de priorité défini. Le moment d'activer, de désactiver et de connecter des appareils à un profil dépend d'une stratégie de connexion par défaut qui peut être remplacée par l'utilisation d'une superposition de ressources , si vous le souhaitez.

Configurer la gestion des connexions automobiles

Désactiver la politique téléphonique par défaut

La pile Bluetooth Android maintient une stratégie de connexion pour les téléphones activée par défaut. Cette stratégie doit être désactivée sur votre appareil afin qu'elle n'entre pas en conflit avec la stratégie automobile prévue dans CarBluetoothService . Bien que la superposition de produits Car doive s'en charger pour vous, vous pouvez désactiver la stratégie téléphonique 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 politique automobile par défaut

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

De plus, la politique de gestion des connexions Bluetooth se trouve dans service/src/com/android/car/BluetoothDeviceConnectionPolicy.java . Par défaut, cette stratégie définit les cas dans lesquels Bluetooth doit se connecter et se déconnecter des appareils liés. Il gère également les cas spécifiques à la voiture pour lesquels l'adaptateur doit être allumé et éteint.

Créez votre propre politique de gestion des connexions automobiles personnalisée

Si la politique automobile par défaut n'est pas suffisante à vos besoins, elle peut également être désactivée au profit de votre propre politique personnalisée. Votre stratégie personnalisée est au minimum chargée de déterminer quand activer et désactiver l'adaptateur Bluetooth, ainsi que quand connecter les appareils. Il est possible d'utiliser divers événements pour activer/désactiver l'adaptateur Bluetooth et initier des connexions d'appareils, y compris des événements dus à des modifications des propriétés spécifiques de la voiture.

Désactiver la politique automobile par défaut

Tout d’abord, pour utiliser une stratégie personnalisée, la stratégie 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 le cadre de 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 politique consiste à allumer et éteindre l'adaptateur Bluetooth aux moments appropriés. Vous pouvez utiliser les API de structure BluetoothAdapter.enable() et BluetoothAdapter.disable() pour activer et désactiver l'adaptateur. Ces appels doivent respecter l'état persistant que l'utilisateur a sélectionné via les paramètres ou tout autre moyen. Une façon de procéder est la suivante :

/**
 * 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 allumer et éteindre l’adaptateur Bluetooth

Avec votre stratégie personnalisée, vous êtes libre de déterminer quels événements indiquent les meilleurs moments pour activer et désactiver l'adaptateur. Une telle façon de procéder consiste à 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 les appareils

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

Un exemple de cas où vous souhaiterez peut-être procéder ainsi est chaque fois que l'adaptateur Bluetooth s'allume :

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 stratégie de connexion consiste à activer Bluetooth sur votre IVI et à vérifier qu'il se connecte automatiquement aux appareils appropriés dans l'ordre approprié. Vous pouvez basculer l'adaptateur Bluetooth via l'interface utilisateur des paramètres ou avec les 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 les informations de débogage liées aux connexions Bluetooth :

adb shell dumpsys car_service

Enfin, si vous avez créé votre propre stratégie 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 des appareils.

Profils Bluetooth automobiles

Sous 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 simultanément des appareils distincts, tels qu'un téléphone personnel et un téléphone professionnel, et de passer des appels mains libres depuis l'un ou l'autre appareil.

Les limites de connexion sont appliquées par chaque profil Bluetooth individuel, généralement dans le cadre de la mise en œuvre du service de profil lui-même. Par défaut, CarBluetoothService ne porte aucun autre jugement sur le nombre maximum d'appareils connectés autorisés.

Profil mains libres

Le profil mains libres Bluetooth (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 téléphonique distinct auprès de TelecomManager , qui annonce tous les comptes téléphoniques disponibles dans les applications IVI.

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

Lorsqu'un utilisateur passe ou reçoit un appel téléphonique depuis un appareil, le compte téléphonique correspondant crée un objet HfpClientConnection . L'application Dialer interagit avec l'objet HfpClientConnection pour gérer les fonctionnalités d'appel, telles que accepter un appel ou raccrocher.

Il convient de noter que l'application Dialer par défaut ne prend pas en charge plusieurs appareils HFP connectés simultanément. Afin de mettre en œuvre un 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 bon compte. 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 de Bluetooth, connectez un appareil à l’IVI et diffusez 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 les pauses audio diffusées et le son du téléphone est diffusé sur les haut-parleurs connectés à l'IVI.
  4. En utilisant le même téléphone, recevez un appel entrant directement sur le téléphone et recevez un appel entrant en utilisant l'IVI.
    1. Dans les deux cas, vérifiez que la diffusion audio s'interrompt et que l'audio du téléphone est diffusé sur les haut-parleurs connectés à l'IVI.
  5. Répétez les étapes 3 et 4 avec l'autre téléphone connecté.

Appel 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 à partir de l'IVI, notamment :

  • 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. Il est possible d'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éation d'une application d'appel .

Voici un exemple de la façon d’établir un 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 Bluetooth pour les appels d'urgence

Les appels d'urgence avant Android 10 impliquaient une numérotation directe à partir d'un téléphone et l'appel d'un équipement spécial si disponible (par exemple, déclenchement automatique lors de la détection d'un danger ou d'une action de l'utilisateur). Sous Android 10 et supérieur, le composeur dans la voiture peut appeler directement un numéro d'urgence, à condition que ce 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 mettant en œuvre 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 d'accès au répertoire téléphonique Bluetooth (PBAP) télécharge les contacts et l'historique des appels à partir d'un appareil distant connecté. PBAP maintient une liste agrégée et consultable de contacts qui est mise à jour par la machine à états client PBAP. Chaque appareil connecté interagit avec une machine à états client PBAP distincte, ce qui permet d'associer les contacts au périphérique approprié lors d'un appel.

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

De plus, la connexion du profil doit être autorisée à la fois par l'IVI et par l'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 d'accès aux messages Bluetooth (MAP) permet au véhicule d'envoyer et de recevoir des messages SMS 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 reçoit et analyse le message et diffuse son contenu dans une instance Intent , qui peut ensuite être reçue par une application.

Afin de se connecter à un appareil mobile dans le but d'envoyer et de recevoir des messages, l'IVI doit initier la connexion MAP. MAXIMUM_CONNECTED_DEVICES dans MapClientService définit le nombre maximum de connexions simultanées de périphériques MAP autorisées avec l'IVI. Chaque connexion doit être autorisée par l'IVI et l'appareil mobile avant que les messages puissent être transférés.

Profil de distribution audio avancé

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

Contrairement à d'autres profils, le nombre maximum d'appareils A2DP connectés est appliqué dans la pile native et non dans 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 de télécommande audio/vidéo Bluetooth (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 d'un contrôleur AVRCP, tous les contrôles déclenchés affectant la lecture audio reposent sur une connexion A2DP au périphérique 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 sur le téléphone doit fournir un MediaBrowserService et autoriser l'accès com.android.bluetooth à ce service. La création d'un service de navigateur multimédia explique comment procéder en détail.