Android zapewnia pełną implementację Bluetootha z obsługą wielu popularnych profili Bluetooth w samochodzie. Wprowadzono też wiele ulepszeń, które zwiększają wydajność i poprawiają komfort korzystania z innych urządzeń i usług.
Zarządzanie połączeniami Bluetooth
W Androidzie usługa CarBluetoothService utrzymuje listę urządzeń Bluetooth bieżącego użytkownika oraz listy priorytetów dla każdego połączenia profilu z systemem IVI. Urządzenia są połączone z profilami w określonej kolejności priorytetowej. Decyzja o włączeniu, wyłączeniu i połączeniu urządzeń z profilem jest podejmowana na podstawie domyślnej zasady połączenia, którą w razie potrzeby można zastąpić za pomocą nakładki zasobów.
Konfigurowanie zarządzania połączeniami w samochodzie
Wyłączanie domyślnej zasady dotyczącej telefonu
Stos Bluetootha w Androidzie utrzymuje zasadę połączenia dla telefonów, która jest domyślnie włączona. Tę zasadę należy wyłączyć na urządzeniu, aby nie kolidowała z
zamierzoną zasadą dotyczącą samochodu w
usłudze CarBluetoothService. Nakładka produktu Car powinna się tym zająć,
możesz wyłączyć zasadę dotyczącą telefonu w
nakładce zasobów ustawiając enable_phone_policy na false w
MAXIMUM_CONNECTED_DEVICES w
/packages/apps/Bluetooth/res/values/config.xml.
Korzystanie z domyślnej zasady dotyczącej samochodu
Usługa CarBluetoothService utrzymuje domyślne uprawnienia profilu. Lista znanych
urządzeń i ich priorytetów ponownego połączenia z profilem znajduje się w
service/src/com/android/car/BluetoothProfileDeviceManager.java.
Zasadę zarządzania połączeniami Bluetooth można też znaleźć w pliku
service/src/com/android/car/BluetoothDeviceConnectionPolicy.java. Domyślnie,
ta zasada określa, kiedy Bluetooth powinien łączyć się z urządzeniami sparowanymi i rozłączać je. Zarządza też przypadkami specyficznymi dla samochodu, w których adapter powinien być włączony i
wyłączony.
Tworzenie własnej zasady zarządzania połączeniami w samochodzie
Jeśli domyślna zasada dotycząca samochodu nie spełnia Twoich potrzeb, możesz ją wyłączyć i użyć własnej zasady. Twoja zasada niestandardowa musi co najmniej określać, kiedy włączyć i wyłączyć adapter Bluetooth oraz kiedy połą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ń spowodowanych zmianami określonych właściwości samochodu.
Wyłączanie domyślnej zasady dotyczącej samochodu
Aby używać zasady niestandardowej, musisz najpierw wyłączyć domyślną zasadę dotyczącą samochodu, ustawiając wartość useDefaultBluetoothConnectionPolicy na false w nakładce zasobów.
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 podstawowych funkcji Twojej zasady jest włączanie i wyłączanie adaptera Bluetooth w
odpowiednich momentach. Do włączania i wyłączania adaptera możesz używać interfejsów API platformy BluetoothAdapter.enable() i
BluetoothAdapter.disable()
Te wywołania powinny uwzględniać stan zapisany przez użytkownika w Ustawieniach lub
w inny sposób. Możesz to zrobić na przykład tak:
/** * 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łączyć i wyłączyć adapter Bluetooth
Dzięki zasadzie niestandardowej możesz określić, które zdarzenia wskazują najlepsze momenty na
włączenie i wyłączenie adaptera. Możesz to zrobić na przykład za pomocą stanów zasilania
MAXIMUM_CONNECTED_DEVICES w
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;
}
}
};Określanie, kiedy połączyć urządzenia
Podobnie, gdy określisz zdarzenia, które powinny wywoływać rozpoczęcie połączeń z urządzeniami,
usługa
CarBluetoothManager udostępni wywołanie connectDevices() API, które
będzie łączyć urządzenia na podstawie list priorytetów zdefiniowanych dla każdego profilu Bluetooth.
Możesz to zrobić na przykład za każdym razem, gdy włączy się 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
Najłatwiejszym sposobem na sprawdzenie działania zasady połączenia jest włączenie Bluetootha w systemie IVI i sprawdzenie, czy automatycznie łączy się z odpowiednimi urządzeniami w odpowiedniej kolejności. Adapter Bluetooth możesz włączać i wyłączać w interfejsie ustawień lub 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 do wyświetlania informacji o debugowaniu związanych z połączeniami Bluetooth można używać danych wyjściowych tego polecenia:
adb shell dumpsys car_service
Jeśli masz własną zasadę dotyczącą samochodu, sprawdzenie niestandardowego działania połączenia wymaga kontrolowania zdarzeń, które mają wywoływać połączenia z urządzeniami.
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 oddzielnych urządzeń, np. telefonu osobistego i służbowego, oraz wykonywanie połączeń w trybie zestawu głośnomówiącego z dowolnego z tych urządzeń.
Limity połączeń są egzekwowane przez każdy profil Bluetooth, zwykle w ramach implementacji samej usługi profilu. Domyślnie usługa CarBluetoothService nie podejmuje dalszych decyzji dotyczących maksymalnej dozwolonej liczby połączonych urządzeń.
Profil zestawu głośnomówiącego
Profil Bluetooth Hands-Free Profile (HFP) umożliwia pojazdowi wykonywanie i odbieranie połączeń telefonicznych za pomocą połączonego urządzenia zdalnego. Każde połączenie z urządzeniem rejestruje oddzielne konto telefoniczne w usłudze TelecomManager, która reklamuje wszystkie dostępne konta telefoniczne w aplikacjach 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
connections.
Gdy użytkownik nawiązuje lub odbiera połączenie telefoniczne z urządzenia, odpowiednie
konto telefoniczne tworzy obiekt HfpClientConnection. Aplikacja Telefon
współdziała z obiektem HfpClientConnection, aby zarządzać funkcjami połączeń
, takimi jak odbieranie połączeń czy rozłączanie się.
Pamiętaj, że domyślna aplikacja Telefon nie obsługuje wielu jednocześnie
połączonych urządzeń HFP. Aby zaimplementować profil HFP na wielu urządzeniach, musisz wprowadzić zmiany
które umożliwią użytkownikom wybieranie konta urządzenia, z którego chcą korzystać podczas nawiązywania połączenia. Aplikacja wywołuje wtedy
funkcję telecomManager.placeCall z odpowiednim kontem. Musisz też
sprawdzić, czy inne funkcje na wielu urządzeniach działają zgodnie z oczekiwaniami.
Sprawdzanie profilu HFP na wielu urządzeniach
Aby sprawdzić, czy połączenie na wielu urządzeniach działa prawidłowo przez Bluetooth:
- Połącz urządzenie z systemem IVI przez Bluetooth i przesyłaj z niego dźwięk z urządzenia.
- Połącz 2 telefony z systemem IVI przez Bluetooth.
- Wybierz jeden telefon. Nawiąż połączenie wychodzące bezpośrednio z telefonu,
i nawiąż połączenie wychodzące za pomocą systemu IVI.
- W obu przypadkach sprawdź, czy przesyłany dźwięk jest wstrzymywany, a dźwięk z telefonu jest odtwarzany przez głośniki połączone z systemem IVI.
- Na tym samym telefonie odbierz połączenie przychodzące bezpośrednio na telefonie i
odbierz połączenie przychodzące za pomocą systemu IVI.
- W obu przypadkach sprawdź, czy przesyłany dźwięk jest wstrzymywany, a dźwięk z telefonu jest odtwarzany przez głośniki połączone z systemem IVI.
- Powtórz kroki 3 i 4 na drugim połączonym telefonie.
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
Sprzęt eCall ma kluczowe znaczenie dla bezpieczeństwa, ale nie jest obecnie zintegrowany z Androidem. Możesz użyć usługi ConnectionService, aby udostępnić funkcje połączeń alarmowych w Androidzie. Ma to też tę zaletę, że wprowadza opcje ułatwień dostępu do połączeń alarmowych. Więcej informacji znajdziesz w artykule Tworzenie aplikacji do nawiązywania połączeń.
Oto przykład, jak nawiązać połączenie alarmowe za pomocą usługi 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); } }
Włączanie Bluetootha na potrzeby połączeń alarmowych
Przed Androidem 10 dzwonienie pod numer alarmowy wymagało bezpośredniego wybrania numeru na telefonie i wywołania
specjalnego sprzętu, jeśli był dostępny (np. automatyczne wywołanie po wykryciu zagrożenia lub działania
użytkownika). W Androidzie 10 i nowszym aplikacja Telefon w samochodzie może bezpośrednio dzwonić pod numer alarmowy, o ile w pliku
apps/Bluetooth/res/values/config.xml jest ustawiona wartość MAXIMUM_CONNECTED_DEVICES:
<!-- 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, też mogą dzwonić pod numer alarmowy.
Profil dostępu do książki telefonicznej
Profil Bluetooth Phone Book Access Profile (PBAP) pobiera kontakty i historię połączeń z połączonego urządzenia zdalnego. Profil PBAP utrzymuje zagregowaną listę kontaktów, którą można przeszukiwać i która jest aktualizowana przez automat stanów klienta PBAP. Każde połączone urządzenie współdziała z oddzielnym automatem stanów klienta PBAP, dzięki czemu podczas nawiązywania połączenia kontakty są powiązane z odpowiednim urządzeniem.
Profil PBAP jest jednokierunkowy, dlatego wymaga, aby system IVI inicjował połączenia z dowolnym
MAXIMUM_CONNECTED_DEVICES w
PbapClientService określa maksymalną liczbę jednoczesnych połączeń z urządzeniami PBAP
dozwolonych w systemie IVI. Klient PBAP przechowuje kontakty każdego
połączonego urządzenia w usłudniu
dostawca kontaktów, do której aplikacja może uzyskać dostęp, aby pobrać książkę telefoniczną
każdego urządzenia.
Aby można było nawiązać połączenie, musi ono zostać autoryzowane zarówno przez system IVI, jak i urządzenie mobilne. Gdy klient PBAP się rozłączy, 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 Bluetooth Message Access Profile (MAP) umożliwia pojazdowi wysyłanie i odbieranie wiadomości SMS wiadomości za pomocą połączonego urządzenia zdalnego. Obecnie wiadomości nie są przechowywane lokalnie w systemie IVI. Gdy połączone urządzenie zdalne otrzyma wiadomość, system IVI odbiera i analizuje ją 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ń z urządzeniami MAP dozwolonych w systemie IVI. Przed przesłaniem wiadomości każde połączenie musi zostać autoryzowane przez system IVI i
urządzenie mobilne.
Profil zaawansowanej dystrybucji audio
Profil Bluetooth Advanced Audio Distribution Profile (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 egzekwowana w
natywnym stosie, a nie w Javie. Wartość jest obecnie zakodowana na stałe jako 1 za pomocą
zmiennej kDefaultMaxConnectedAudioDevices w
packages/modules/Bluetooth/system/btif/src/btif_av.cc.
Profil zdalnego sterowania audio/wideo
Profil Bluetooth Audio/Video Remote Control Profile (AVRCP) umożliwia pojazdowi sterowanie odtwarzaczami multimediów na połączonym urządzeniu zdalnym i przeglądanie ich. Ponieważ system IVI pełni rolę kontrolera AVRCP, wszystkie wywołane elementy sterujące, które wpływają na odtwarzanie dźwięku, korzystają z połączenia A2DP z urządzeniem docelowym.
Aby samochodowy system multimedialny mógł przeglądać określony odtwarzacz multimediów na telefonie z Androidem za pomocą profilu AVRCP, aplikacja do multimediów na telefonie musi udostępniać
MediaBrowserService i zezwalać na dostęp docom.android.bluetooth do tej usługi.
Szczegółowe informacje o tym, jak to zrobić, znajdziesz w artykule Tworzenie usługi przeglądarki multimediów.