Android fornisce un'implementazione completa del Bluetooth con il supporto di molti profili Bluetooth comuni in auto. Esistono inoltre molti miglioramenti che migliorano le prestazioni e l'esperienza con altri dispositivi e servizi.
Gestione della connessione Bluetooth
In Android, CarBluetoothService gestisce i dispositivi Bluetooth e gli elenchi di priorità dell'utente corrente per ogni connessione del profilo all'IVI. I dispositivi sono collegati ai profili in un ordine di priorità definito. I momenti in cui attivare, disattivare e connettere i dispositivi a un profilo sono basati su un criterio di connessione predefinito che può essere sostituito con l'uso di un overlay di risorse, se lo si desidera.
Configurare la gestione delle connessioni per i veicoli
Disattivare il criterio predefinito per il telefono
Lo stack Bluetooth di Android gestisce un criterio di connessione per gli smartphone abilitato per impostazione predefinita. Questo criterio deve essere disattivato sul dispositivo in modo che non entri in conflitto con il
criterio per i veicoli auto e motori previsto in
CarBluetoothService. Sebbene l'overlay del prodotto auto debba occuparsene per te,
puoi disattivare il criterio per gli smartphone in un
overlay delle risorse impostando enable_phone_policy
su false
in
MAXIMUM_CONNECTED_DEVICES
in
/packages/apps/Bluetooth/res/values/config.xml
.
Utilizza il criterio per i veicoli predefinito
CarBluetoothService mantiene le autorizzazioni del profilo predefinite. L'elenco dei dispositivi
noti e le relative priorità di ricollegamento del profilo sono riportati in
service/src/com/android/car/BluetoothProfileDeviceManager.java
.
Inoltre, il criterio di gestione della connessione Bluetooth è disponibile in
service/src/com/android/car/BluetoothDeviceConnectionPolicy.java
. Per impostazione predefinita,
questo criterio definisce le istanze in cui il Bluetooth deve connettersi e disconnettersi dai dispositivi associati. Gestisce anche casi specifici per l'auto per quando l'adattatore deve essere acceso e spento.
Creare un criterio di gestione delle connessioni per i veicoli personalizzato
Se il criterio per i veicoli a motore predefinito non è sufficiente per le tue esigenze, può anche essere disattivato in favore del tuo criterio personalizzato. Il criterio personalizzato è responsabile, come minimo, di determinare quando attivare e disattivare l'adattatore Bluetooth e quando connettere i dispositivi. È possibile utilizzare una serie di eventi per attivare/disattivare l'adattatore Bluetooth e avviare le connessioni dei dispositivi, inclusi gli eventi dovuti a modifiche in proprietà specifiche dell'auto.
Disattivare il criterio per i veicoli a motore predefinito
Innanzitutto, per utilizzare un criterio personalizzato, il criterio per i veicoli a motore predefinito deve essere disattivato impostando useDefaultBluetoothConnectionPolicy
su false
in un overlay delle risorse.
Questa risorsa è originariamente definita come parte di
MAXIMUM_CONNECTED_DEVICES
in
packages/services/Car/service/res/values/config.xml
.
Attivare e disattivare l'adattatore Bluetooth
Una delle funzioni principali del criterio è attivare e disattivare l'adattatore Bluetooth al momento opportuno. Puoi utilizzare le API del framework BluetoothAdapter.enable()
e
BluetoothAdapter.disable()
per attivare e disattivare l'adattatore.
Queste chiamate devono rispettare lo stato permanente selezionato dall'utente tramite Impostazioni o qualsiasi altro mezzo. Un modo per farlo è il seguente:
/** * 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); }
Determinare quando attivare e disattivare l'adattatore Bluetooth
Con il criterio personalizzato, puoi determinare quali eventi indicano i momenti migliori per attivare e disattivare l'adattatore. Un modo per farlo è utilizzare gli stati di alimentazione
MAXIMUM_CONNECTED_DEVICES
in
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; } } };
Determinare quando connettere i dispositivi
Analogamente, quando stabilisci gli eventi che devono attivare l'inizio delle connessioni dei dispositivi,
CarBluetoothManager fornisce la chiamata all'API connectDevices()
che procede alla connessione dei dispositivi in base agli elenchi di priorità definiti per ogni profilo Bluetooth.
Un esempio di quando potresti voler eseguire questa operazione è quando l'adattatore Bluetooth si accende:
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(); } } } }
Verificare la gestione della connessione per i veicoli
Il modo più semplice per verificare il comportamento del criterio di connessione è attivare il Bluetooth sul tuo IVI e verificare che si connetta automaticamente ai dispositivi corretti nell'ordine appropriato. Puoi attivare/disattivare l'adattatore Bluetooth tramite l'interfaccia utente delle impostazioni o con i seguenti comandi 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
Inoltre, l'output del seguente comando può essere utilizzato per visualizzare le informazioni di debug relative alle connessioni Bluetooth:
adb shell dumpsys car_service
Infine, se hai creato i tuoi criteri per i veicoli, la verifica di eventuali comportamenti di connessione personalizzati richiede il controllo degli eventi che hai scelto per attivare le connessioni dei dispositivi.
Profili Bluetooth per auto e motori
In Android, l'IVI può supportare più dispositivi connessi contemporaneamente tramite Bluetooth. I servizi telefonici Bluetooth multi-dispositivo consentono agli utenti di connettere contemporaneamente dispositivi distinti, ad esempio uno smartphone personale e uno di lavoro, ed effettuare chiamate in vivavoce da entrambi i dispositivi.
I limiti di connessione vengono applicati da ogni singolo profilo Bluetooth, in genere nell'implementazione del servizio del profilo stesso. Per impostazione predefinita, CarBluetoothService non effettua ulteriori valutazioni sul numero massimo di dispositivi collegati consentiti.
Profilo Hands-Free
Il profilo Hands-Free (HFP) Bluetooth consente al veicolo di effettuare e ricevere telefonate tramite un dispositivo remoto connesso. Ogni connessione del dispositivo registra un account telefono distinto con TelecomManager, che pubblicizza tutti gli account telefono disponibili per le app IVI.
L'IVI può connettersi a più dispositivi tramite HFP. MAX_STATE_MACHINES_POSSIBLE
MAXIMUM_CONNECTED_DEVICES
in
HeadsetClientService
definisce il numero massimo di connessioni HFP
simultanee.
Quando un utente effettua o riceve una chiamata da un dispositivo, l'account associato allo smartphone crea un oggetto HfpClientConnection
. L'app Telefono interagisce con l'oggetto HfpClientConnection
per gestire le funzionalità di chiamata, ad esempio accettare una chiamata o riagganciare.
Tieni presente che l'app Telefono predefinita non supporta più dispositivi HFP connessi contemporaneamente. Per implementare HFP multi-dispositivo, è necessaria la personalizzazione per consentire agli utenti di selezionare l'account del dispositivo da utilizzare quando effettuano una chiamata. L'app quindi chiama telecomManager.placeCall
con l'account corretto. Devi verificare anche che le altre funzionalità multi-dispositivo funzionino come previsto.
Verificare HFP multi-dispositivo
Per verificare che la connettività multi-dispositivo funzioni correttamente tramite Bluetooth:
- Utilizzando il Bluetooth, connetti un dispositivo all'IVI e riproduci in streaming l'audio dal dispositivo.
- Collega due smartphone all'IVI tramite Bluetooth.
- Scegli uno smartphone. Effettua una chiamata in uscita direttamente dallo smartphone e una chiamata in uscita utilizzando l'IVI.
- In entrambe le occasioni, verifica che l'audio in streaming venga messo in pausa e che l'audio dello smartphone venga riprodotto sugli altoparlanti collegati all'IVI.
- Utilizzando lo stesso smartphone, ricevi una chiamata in arrivo direttamente sullo smartphone e
ricevi una chiamata in arrivo utilizzando l'IVI.
- In entrambe le occasioni, verifica che l'audio in streaming venga messo in pausa e che l'audio dello smartphone venga riprodotto sugli altoparlanti collegati all'IVI.
- Ripeti i passaggi 3 e 4 con l'altro smartphone connesso.
Chiamate di emergenza
La possibilità di effettuare chiamate di emergenza è un aspetto importante delle funzioni di telefonia e Bluetooth nell'auto. Esistono diversi modi per avviare una chiamata di emergenza dall'IVI, tra cui:
- Soluzione eCall autonoma
- Soluzione eCall integrata nell'IVI
- Fare affidamento su uno smartphone con Bluetooth connesso quando non è disponibile alcun sistema integrato
Effettuare una chiamata di emergenza
Sebbene l'apparecchiatura eCall sia fondamentale per la sicurezza, al momento non è integrata in Android. È possibile utilizzare ConnectionService per esporre le funzionalità di chiamata di emergenza tramite Android, il che ha anche il vantaggio di introdurre opzioni di accessibilità per le chiamate di emergenza. Per scoprire di più, consulta Creare un'app di chiamata.
Ecco un esempio di come stabilire un servizio di connessione di emergenza :
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); } }
Attivare il Bluetooth per le chiamate di emergenza
Prima di Android 10, per chiamare i servizi di emergenza era necessario comporre il numero direttamente da uno smartphone e invocare equipment speciale, se disponibile (ad esempio, attivazione automatica al rilevamento di un pericolo o un'azione dell'utente). In Android 10 e versioni successive, il tastierino nell'auto può chiamare direttamente un
numero di emergenza, a condizione che MAXIMUM_CONNECTED_DEVICES
in
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>
Se implementi le chiamate di emergenza in questo modo, anche altre app, come il riconoscimento vocale, possono chiamare un numero di emergenza.
Profilo di accesso alla rubrica
Il profilo Phonebook Access (PBAP) Bluetooth scarica i contatti e le cronologie chiamate da un dispositivo remoto connesso. PBAP gestisce un elenco aggregato e ricercabile di contatti che viene aggiornato dalla macchina a stati del client PBAP. Ogni dispositivo connesso interagisce con una macchina a stati client PBAP separata, con il risultato che i contatti vengono associati al dispositivo corretto quando si effettua una chiamata.
PBAP è unidirezionale e pertanto richiede che l'IVI instantizi le connessioni a qualsiasi
MAXIMUM_CONNECTED_DEVICES
in
PbapClientService
definisce il numero massimo di connessioni simultanee dei dispositivi PBAP
consentite con l'IVI. Il client PBAP memorizza i contatti di ogni
dispositivo connesso nel
provider di contatti a cui un'app può accedere per ricavare la rubrica
di ogni dispositivo.
Inoltre, affinché la connessione venga stabilita, il collegamento del profilo deve essere autorizzato sia dall'IVI sia dal dispositivo mobile. Quando un client PBAP si disconnette, il database interno rimuove tutti i contatti e la cronologia chiamate associati al dispositivo collegato in precedenza.
Profilo di accesso ai messaggi
Il profilo Bluetooth Message Access (MAP) consente al veicolo di inviare e ricevere messaggi SMS tramite un dispositivo remoto connesso. Al momento, i messaggi non vengono memorizzati localmente sull'IVI. Invece, ogni volta che il dispositivo remoto connesso riceve un messaggio, l'IVI lo riceve e lo analizza, poi ne trasmette i contenuti in un'istanza Intent, che può essere ricevuta da un'app.
Per connettersi a un dispositivo mobile al fine di inviare e ricevere messaggi, l'IVI deve avviare la connessione MAP.
MAXIMUM_CONNECTED_DEVICES
in
MapClientService
definisce il numero massimo di connessioni simultanee dei dispositivi MAP consentite con l'IVI. Ogni connessione deve essere autorizzata dall'IVI e dal
dispositivo mobile prima che i messaggi possano essere trasferiti.
Advanced Audio Distribution Profile
Il profilo A2DP (Advanced Audio Distribution Profile) Bluetooth consente al veicolo di ricevere stream audio da un dispositivo remoto connesso.
A differenza di altri profili, il numero massimo di dispositivi A2DP connessi viene applicato nello
stato nativo e non in Java. Al momento il valore è impostato come 1
utilizzando
la variabile kDefaultMaxConnectedAudioDevices
in
packages/modules/Bluetooth/system/btif/src/btif_av.cc
.
Profilo di controllo remoto audio/video
Il profilo AVRCP (Audio/Video Remote Control) Bluetooth consente al veicolo di controllare e sfogliare i lettori multimediali su un dispositivo remoto connesso. Poiché l'IVI svolge il ruolo di un controller AVRCP, tutti i controlli attivati che influiscono sulla riproduzione audio si basano su una connessione A2DP al dispositivo di destinazione.
Affinché un media player specifico su uno smartphone Android sia sfogliabile dall'IVI tramite AVRCP,
l'app multimediale sullo smartphone deve fornire un
MediaBrowserService
e consentire l'accesso di com.android.bluetooth
a quel servizio. La pagina
Creare un servizio di browser multimediale spiega come eseguire questa operazione in dettaglio.