Android zapewnia pełną implementację Bluetooth z obsługą wielu popularnych profili Bluetooth w samochodzie. Wprowadziliśmy też wiele ulepszeń, które poprawiają wydajność i komfort korzystania z innych urządzeń i usług.
Zarządzanie połączeniami Bluetooth
W Androidzie CarBluetoothService przechowuje urządzenia Bluetooth bieżącego użytkownika i listy priorytetów dla każdego połączenia profilu z systemem IVI. Urządzenia są połączone z profilami w określonej kolejności priorytetów. Kiedy włączać i wyłączać urządzenia oraz łączyć je z profilem, określa domyślna zasada połączenia, którą w razie potrzeby można zastąpić za pomocą nakładki zasobu.
Konfigurowanie zarządzania połączeniami w przypadku samochodów
Wyłączanie domyślnych zasad dotyczących telefonów
Stos Bluetooth na Androidzie utrzymuje domyślnie włączoną zasadę połączeń dla telefonów. Ta zasada musi być wyłączona na urządzeniu, aby nie kolidowała z zasadą dotyczącą samochodów w
CarBluetoothService. Nakładka na produkt samochodowy powinna się tym zająć, ale możesz wyłączyć zasady dotyczące telefonów w
nakładce na zasób, ustawiając wartość enable_phone_policy
na false
w MAXIMUM_CONNECTED_DEVICES
w
/packages/apps/Bluetooth/res/values/config.xml
.
Używanie domyślnych zasad dotyczących motoryzacji
CarBluetoothService zachowuje domyślne uprawnienia profilu. Lista znanych urządzeń i ich priorytetów ponownego łączenia z profilem znajduje się w service/src/com/android/car/BluetoothProfileDeviceManager.java
.
Zasady zarządzania połączeniami Bluetooth znajdziesz też w
service/src/com/android/car/BluetoothDeviceConnectionPolicy.java
. Domyślnie ta zasada określa, kiedy Bluetooth powinien łączyć się z sparowanymi urządzeniami i rozłączać się z nimi. Zarządza też przypadkami związanymi z samochodem, w których adapter powinien być włączony lub wyłączony.
Tworzenie własnych zasad zarządzania połączeniami w przypadku samochodów
Jeśli domyślna polityka dotycząca motoryzacji nie spełnia Twoich potrzeb, możesz ją wyłączyć i zastąpić własną polityką niestandardową. Twoja niestandardowa zasada musi co najmniej określać, kiedy włączać i wyłączać adapter Bluetooth oraz kiedy łączyć urządzenia. Do włączania i wyłączania adaptera Bluetooth oraz inicjowania połączeń z urządzeniami można używać różnych zdarzeń, w tym zdarzeń wynikających ze zmian w określonych właściwościach samochodu.
Wyłączanie domyślnych zasad dotyczących motoryzacji
Aby użyć niestandardowej zasady, musisz najpierw wyłączyć domyślną zasadę dotyczącą motoryzacji, ustawiając useDefaultBluetoothConnectionPolicy
na false
w nakładce zasobu.
Ten zasób jest pierwotnie zdefiniowany jako część MAXIMUM_CONNECTED_DEVICES
w
packages/services/Car/service/res/values/config.xml
.
Włączanie i wyłączanie adaptera Bluetooth
Jedną z głównych funkcji zasad jest włączanie i wyłączanie adaptera Bluetooth w odpowiednich momentach. Aby włączyć i wyłączyć adapter, możesz użyć interfejsów API platform BluetoothAdapter.enable()
i BluetoothAdapter.disable()
.
Te wywołania powinny uwzględniać stan wybrany przez użytkownika w Ustawieniach lub w inny sposób. Możesz to zrobić w ten sposób:
/** * 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); }
Określanie, kiedy włączać i wyłączać adapter Bluetooth
W ramach zasad niestandardowych możesz określić, które zdarzenia wskazują najlepszy czas na włączenie i wyłączenie adaptera. Jednym ze sposobów na to jest użycie stanów zasilaniaMAXIMUM_CONNECTED_DEVICES
wCarPowerManager
:
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; } } };
Określanie, kiedy połączyć urządzenia
Podobnie, gdy określisz zdarzenia, które powinny uruchamiać połączenia urządzeń,
CarBluetoothManager udostępnia wywołanie interfejsu API connectDevices()
, które
umożliwia łączenie urządzeń na podstawie list priorytetów zdefiniowanych dla każdego profilu Bluetooth.
Możesz to zrobić na przykład za każdym razem, gdy włączasz adapter 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(); } } } }
Weryfikowanie zarządzania połączeniami w samochodzie
Najprostszym sposobem sprawdzenia działania zasad połączenia jest włączenie Bluetootha w systemie IVI i sprawdzenie, czy automatycznie łączy się on z odpowiednimi urządzeniami we właściwej kolejności. Adapter Bluetooth możesz włączyć lub wyłączyć w interfejsie ustawień albo za pomocą tych poleceń 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
Dodatkowo możesz użyć wyniku tego polecenia, aby wyświetlić informacje o debugowaniu związane z połączeniami Bluetooth:
adb shell dumpsys car_service
Jeśli masz własną politykę dotyczącą samochodów, weryfikacja niestandardowego zachowania połączenia wymaga kontrolowania zdarzeń, które mają wywoływać połączenia z urządzeniem.
Profile Bluetooth w samochodzie
W Androidzie system IVI może obsługiwać wiele urządzeń połączonych jednocześnie przez Bluetooth. Usługi telefoniczne Bluetooth na wielu urządzeniach umożliwiają użytkownikom jednoczesne łączenie się z osobnymi urządzeniami, np. telefonem prywatnym i służbowym, oraz prowadzenie rozmów w trybie głośnomówiącym na każdym z nich.
Limity połączeń są egzekwowane przez poszczególne profile Bluetooth, zwykle w ramach implementacji samej usługi profilu. Domyślnie usługa CarBluetoothService nie podejmuje dalszych decyzji dotyczących maksymalnej liczby dozwolonych połączonych urządzeń.
Profil zestawu słuchawkowego
Profil zestawu głośnomówiącego Bluetooth (HFP) umożliwia wykonywanie i odbieranie połączeń telefonicznych w pojeździe za pomocą połączonego urządzenia zdalnego. Każde połączenie urządzenia rejestruje oddzielne konto telefoniczne w usłudze TelecomManager, która udostępnia wszystkie dostępne konta telefoniczne aplikacjom IVI.
System IVI może łączyć się z wieloma urządzeniami za pomocą profilu HFP. MAX_STATE_MACHINES_POSSIBLE
MAXIMUM_CONNECTED_DEVICES
w
HeadsetClientService
określa maksymalną liczbę jednoczesnych połączeń HFP.
Gdy użytkownik nawiązuje lub odbiera połączenie telefoniczne na urządzeniu, odpowiednie konto telefoniczne tworzy obiekt HfpClientConnection
. Aplikacja Telefon
współdziała z obiektem HfpClientConnection
, aby zarządzać funkcjami połączeń, takimi jak odbieranie i rozłączanie połączeń.
Warto pamiętać, że domyślna aplikacja Telefon nie obsługuje wielu jednocześnie połączonych urządzeń HFP. Aby wdrożyć HFP na wielu urządzeniach, konieczne jest dostosowanie, które umożliwi użytkownikom wybór konta urządzenia, z którego będą korzystać podczas nawiązywania połączeń. Aplikacja wywołuje wtedy telecomManager.placeCall
z użyciem właściwego konta. Musisz też sprawdzić, czy inne funkcje na wielu urządzeniach działają zgodnie z oczekiwaniami.
Weryfikacja HFP na wielu urządzeniach
Aby sprawdzić, czy łączność z wieloma urządzeniami działa prawidłowo przez Bluetooth:
- Połącz urządzenie z systemem IVI przez Bluetooth i przesyłaj strumieniowo dźwięk z urządzenia.
- Połącz 2 telefony z systemem IVI przez Bluetooth.
- Wybierz jeden telefon. wykonywać połączenia wychodzące bezpośrednio z telefonu i za pomocą systemu IVI;
- Za każdym razem sprawdź, czy strumieniowany dźwięk jest wstrzymywany, a dźwięk z telefonu jest odtwarzany przez głośniki podłączone do IVI.
- Odbieranie połączeń przychodzących bezpośrednio na telefonie i za pomocą systemu IVI na tym samym telefonie.
- Za każdym razem sprawdź, czy strumieniowe odtwarzanie dźwięku zostało wstrzymane, a dźwięk z telefonu jest odtwarzany przez głośniki połączone z IVI.
- Powtórz kroki 3 i 4 w przypadku drugiego połączonego telefonu.
Połączenia alarmowe
Możliwość nawiązywania połączeń alarmowych jest ważnym aspektem funkcji telefonicznych i Bluetooth w samochodzie. Połączenie alarmowe można zainicjować z systemu IVI na kilka sposobów, m.in.:
- Samodzielne rozwiązanie eCall
- Rozwiązanie eCall zintegrowane z systemem IVI
- korzystanie z połączonego telefonu Bluetooth, gdy nie jest dostępny wbudowany system;
Nawiązywanie połączenia alarmowego
Urządzenia eCall mają kluczowe znaczenie dla bezpieczeństwa, ale obecnie nie są zintegrowane z Androidem. Za pomocą ConnectionService można udostępniać funkcje połączeń alarmowych w Androidzie, co ma też tę zaletę, że wprowadza opcje ułatwień dostępu dla połączeń alarmowych. Więcej informacji znajdziesz w artykule Tworzenie aplikacji do dzwonienia.
Oto przykład nawiązywania połączenia alarmowego za pomocą usługi :
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); } }
Włączanie Bluetootha na potrzeby połączeń alarmowych
W przypadku Androida w wersji starszej niż 10 dzwonienie na numer alarmowy wymagało bezpośredniego wybrania numeru na telefonie i użycia specjalnego sprzętu, jeśli był dostępny (np. automatyczne uruchomienie po wykryciu zagrożenia lub działania użytkownika). Na urządzeniach z Androidem 10 lub nowszym aplikacja Telefon w samochodzie może bezpośrednio dzwonić pod numer alarmowy, pod warunkiem że MAXIMUM_CONNECTED_DEVICES
w
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>
Dzięki takiemu wdrożeniu połączeń alarmowych inne aplikacje, np. rozpoznawanie głosu, również mogą dzwonić pod numer alarmowy.
Profil dostępu do książki telefonicznej
Profil dostępu do książki telefonicznej Bluetooth (PBAP) pobiera kontakty i historię połączeń z połączonego urządzenia zdalnego. PBAP prowadzi zagregowaną listę kontaktów z możliwością wyszukiwania, która jest aktualizowana przez automat stanowy klienta PBAP. Każde połączone urządzenie wchodzi w interakcję z osobnym automatem stanu klienta PBAP, dzięki czemu kontakty są powiązane z odpowiednim urządzeniem podczas nawiązywania połączenia.
PBAP jest jednokierunkowy, dlatego IVI musi tworzyć połączenia z dowolnym urządzeniem MAXIMUM_CONNECTED_DEVICES
. Wartość
PbapClientService
określa maksymalną liczbę jednoczesnych połączeń urządzeń PBAP dozwolonych w przypadku IVI. Klient PBAP przechowuje kontakty dla każdego podłączonego urządzenia w
dostawcy kontaktów, do którego aplikacja może uzyskać dostęp, aby pobrać książkę telefoniczną dla każdego urządzenia.
Dodatkowo połączenie profilu musi być autoryzowane zarówno przez IVI, jak i urządzenie mobilne, aby można było nawiązać połączenie. Gdy klient PBAP rozłączy się, wewnętrzna baza danych usunie wszystkie kontakty i historię połączeń powiązane z wcześniej połączonym urządzeniem.
Profil dostępu do wiadomości
Profil dostępu do wiadomości Bluetooth (MAP) umożliwia pojazdowi wysyłanie i odbieranie SMS-ów za pomocą połączonego urządzenia zdalnego. Obecnie wiadomości nie są przechowywane lokalnie w systemie IVI. Zamiast tego, gdy połączone urządzenie zdalne otrzyma wiadomość, IVI odbiera i analizuje wiadomość oraz rozgłasza jej zawartość w instancji Intent, którą może następnie odebrać aplikacja.
Aby połączyć się z urządzeniem mobilnym w celu wysyłania i odbierania wiadomości, system IVI musi zainicjować połączenie MAP.
MAXIMUM_CONNECTED_DEVICES
w
MapClientService
określa maksymalną liczbę jednoczesnych połączeń urządzenia MAP z systemem IVI. Przed przeniesieniem wiadomości każde połączenie musi zostać autoryzowane przez system IVI i urządzenie mobilne.
Profil zaawansowanej dystrybucji audio
Profil zaawansowanej dystrybucji audio (A2DP) umożliwia pojazdowi odbieranie strumieni audio z połączonego urządzenia zdalnego.
W przeciwieństwie do innych profili maksymalna liczba połączonych urządzeń A2DP jest wymuszana w natywnym stosie, a nie w Javie. Wartość jest obecnie na stałe ustawiona na 1
przy użyciu zmiennej kDefaultMaxConnectedAudioDevices
w
packages/modules/Bluetooth/system/btif/src/btif_av.cc
.
Profil zdalnego sterowania audio/wideo
Profil zdalnego sterowania dźwiękiem/obrazem Bluetooth (AVRCP) umożliwia pojazdowi sterowanie odtwarzaczami multimediów na podłączonym urządzeniu zdalnym i przeglądanie ich zawartości. Ponieważ system IVI pełni rolę kontrolera AVRCP, wszystkie wywoływane elementy sterujące, które wpływają na odtwarzanie dźwięku, opierają się na połączeniu A2DP z urządzeniem docelowym.
Aby konkretny odtwarzacz multimediów na telefonie z Androidem był dostępny dla IVI za pomocą AVRCP, aplikacja multimedialna na telefonie musi udostępniać
MediaBrowserService
i umożliwiać com.android.bluetooth
dostęp do tej usługi. Więcej informacji znajdziesz w artykule
Tworzenie usługi przeglądarki multimediów.