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 wygodę korzystania z innych urządzeń i usług.
Zarządzanie połączeniem Bluetooth
W Androidzie usługa CarBluetoothService obsługuje urządzenia Bluetooth bieżącego użytkownika oraz listy priorytetów dla każdego połączenia profilu z interfejsem IVI. Urządzenia są łączone z profilami w zdefiniowanej kolejności priorytetów. Czas włączania, wyłączania i łączenia urządzeń z profilem jest określany przez domyślną zasadę połączenia, którą można zastąpić, jeśli to konieczne, za pomocą nakładki zasobów.
Konfigurowanie zarządzania połączeniami w samochodach
Wyłączanie domyślnej zasady dotyczącej telefonu
Stos Bluetootha na Androidzie zarządza zasadami połączeń na telefonach, które są domyślnie włączone. Ta zasada musi być wyłączona na urządzeniu, aby nie kolidowała z zasadą
CarBluetoothService przeznaczoną dla samochodów. Zazwyczaj funkcja nakładki na potrzeby samochodu powinna załatwić to za Ciebie, ale możesz wyłączyć zasadę dotyczącą telefonu w
nakładce zasobów, ustawiając wartość enable_phone_policy
na false
w pliku MAXIMUM_CONNECTED_DEVICES
w pliku
/packages/apps/Bluetooth/res/values/config.xml
.
Używanie domyślnych zasad dotyczących pojazdów
CarBluetoothService obsługuje domyślne uprawnienia profilu. Lista znanych urządzeń i ich priorytetów ponownego połączenia z profilem znajduje się w sekcji 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 te zasady definiują przypadki, w których Bluetooth powinien łączyć się z połączonymi urządzeniami i z nich się rozłączać. Zarządza on też przypadkami związanymi z samochodem, gdy adapter powinien być włączony lub wyłączony.
Tworzenie własnej niestandardowej zasady zarządzania połączeniami w samochodach
Jeśli domyślna polityka dotycząca pojazdów nie spełnia Twoich potrzeb, możesz ją wyłączyć na rzecz własnej polityki niestandardowej. Twoje zasady niestandardowe określają co najmniej to, kiedy włączać i wyłączać adapter Bluetooth, a także kiedy łączyć urządzenia. Można używać różnych zdarzeń do włączania i wyłączania adaptera Bluetooth oraz do inicjowania połączeń z urządzeniami, w tym zdarzeń związanych ze zmianami w określonych właściwościach samochodu.
Wyłączanie domyślnej zasady dotyczącej pojazdów
Aby użyć niestandardowej zasady, musisz najpierw wyłączyć domyślną zasadę dotyczącą pojazdów, ustawiając wartość 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 podstawowych funkcji zasad jest włączanie i wyłączanie adaptera Bluetooth w odpowiednich momentach. Aby włączyć lub wyłączyć adapter, możesz użyć interfejsów API framework BluetoothAdapter.enable()
i BluetoothAdapter.disable()
.
Te wywołania powinny uwzględniać trwały stan wybrany przez użytkownika w Ustawieniach lub innymi sposobami. Możesz to zrobić na przykład 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śl, kiedy włączać i wyłączać adapter Bluetooth
Dzięki niestandardowym zasadom możesz określić, które zdarzenia wskazują na najlepszy czas włączenia i wyłączenia adaptera. Jednym ze sposobów jest użycie 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 należy łączyć urządzenia
Podobnie, gdy określisz zdarzenia, które powinny inicjować połączenia urządzeń,
CarBluetoothManager uruchamia wywołanie interfejsu API connectDevices()
, które łączy urządzenia na podstawie list priorytetów zdefiniowanych dla poszczególnych profili Bluetooth.
Możesz to zrobić, 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 samochodach
Najprostszym sposobem sprawdzenia działania zasad dotyczących połączeń jest włączenie Bluetootha na IVI i sprawdzenie, czy automatycznie łączy się on z odpowiednimi urządzeniami w odpowiednim porządku. Możesz włączyć lub wyłączyć adapter Bluetooth 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, aby wyświetlić informacje debugowania dotyczące połączeń Bluetooth, możesz użyć wyniku tego polecenia:
adb shell dumpsys car_service
Jeśli masz własną politykę dotyczącą pojazdów, weryfikacja niestandardowych zachowań związanych z połączeniem wymaga kontrolowania zdarzeń, które zostały wybrane do uruchamiania połączeń z urządzeniami.
Profile Bluetooth do samochodów
W Androidzie 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 połączenie różnych urządzeń, takich jak telefony osobiste i służbowe, oraz nawiązywanie połączeń w trybie zestawu głośnomówiącego na dowolnym z nich.
Limity połączeń są wymuszane przez każdy profil Bluetooth, zwykle w ramach implementacji samej usługi profilu. Domyślnie usługa CarBluetoothService nie określa maksymalnej liczby połączonych urządzeń.
Profil bez użycia rąk
Profil Bluetooth zestawu głośnomówiącego (HFP) umożliwia nawiązywanie i odbieranie połączeń przez pojazd za pomocą połączonego urządzenia zdalnego. Każde połączenie z urządzeniem rejestruje oddzielne konto telefonu w TelecomManagerze, który reklamuje wszystkie dostępne konta telefonów w aplikacjach IVI.
Interfejs IVI może łączyć się z wieloma urządzeniami za pomocą 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 z urządzenia, odpowiednie konto telefonu tworzy obiekt HfpClientConnection
. Aplikacja Dialer
współpracuje z obiektem HfpClientConnection
, aby zarządzać funkcjami połączeń, takimi jak akceptowanie połączeń czy rozłączanie.
Należy pamiętać, że domyślna aplikacja Dialer nie obsługuje wielu połączonych jednocześnie urządzeń HFP. Aby wdrożyć HFP na wielu urządzeniach, musisz dostosować aplikację, aby umożliwić użytkownikom wybór konta urządzenia, którego będą używać podczas nawiązywania połączeń. Następnie aplikacja wywołuje usługę telecomManager.placeCall
z odpowiednim kontem. Musisz sprawdzić, czy inne funkcje obsługi wielu urządzeń działają zgodnie z oczekiwaniami.
Weryfikowanie HFP na wielu urządzeniach
Aby sprawdzić, czy połączenie wielu urządzeń działa prawidłowo przez Bluetooth:
- Za pomocą Bluetooth połącz urządzenie z IVI i przesyłaj strumieniowo dźwięk z urządzenia.
- Połącz dwa telefony z IVI przez Bluetooth.
- Wybierz jeden telefon. Wykonywanie połączeń wychodzących bezpośrednio z telefonu,
oraz wykonywanie połączeń wychodzących za pomocą interfejsu IVI.
- W obu przypadkach sprawdź, czy dźwięk strumieniowy jest wstrzymywany, a dźwięk z telefonu odtwarzany przez głośniki połączone z IVI.
- Odbieranie połączeń przychodzących bezpośrednio na tym samym telefonie i za pomocą IVI.
- W obu przypadkach sprawdź, czy dźwięk strumieniowy jest wstrzymywany, a dźwięk telefonu odtwarzany przez głośniki połączone z IVI.
- Powtórz kroki 3 i 4 na drugim połączonym telefonie.
Połączenia alarmowe
Możliwość wykonywania połączeń alarmowych jest ważnym aspektem funkcji telefonicznych i Bluetooth w samochodzie. IVI może wywołać połączenie alarmowe na kilka sposobów:
- Samodzielne rozwiązanie eCall
- Rozwiązanie eCall zintegrowane z IVR
- poleganie na telefonie połączonym przez Bluetooth, gdy nie ma dostępnego wbudowanego systemu;
Nawiązywanie połączenia alarmowego
Urządzenia eCall są ważne dla bezpieczeństwa, ale obecnie nie są zintegrowane z Androidem. Aby udostępnić funkcje połączeń alarmowych w Androidzie, możesz użyć ConnectionService, który ma też tę zaletę, że wprowadza opcje ułatwień dostępu do połączeń alarmowych. Więcej informacji znajdziesz w artykule Tworzenie aplikacji do połączeń.
Oto przykład utworzenia awaryjnego 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 do połączeń alarmowych
Przed Androidem 10 dzwonienie na numer alarmowy wymagało bezpośredniego wybierania numeru z telefonu i użycia specjalnego sprzętu, jeśli jest dostępny (np. automatycznego uruchamiania po wykryciu niebezpieczeństwa lub działania użytkownika). W Androidzie 10 i nowszych Dialer w samochodzie może bezpośrednio zadzwonić pod numer alarmowy, o ile 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 temu inne aplikacje, takie jak rozpoznawanie głosu, mogą również 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 podłączonego urządzenia zdalnego. PBAP utrzymuje zbiorczą, możliwą do wyszukiwania listę kontaktów, która jest aktualizowana przez maszynę stanów klienta PBAP. Każde połączone urządzenie wchodzi w interakcję z osobnym mechanizmem stanu klienta PBAP, co powoduje, że kontakty są powiązane z odpowiednim urządzeniem podczas nawiązywania połączenia.
PBAP jest w jednym kierunku, dlatego wymaga, aby IVI utworzyło instancje połączeń z dowolnym urządzeniem MAXIMUM_CONNECTED_DEVICES
w
PbapClientService
, co określa maksymalną liczbę jednoczesnych połączeń z urządzeniem PBAP dozwolonych dla IVI. Klient PBAP przechowuje kontakty na każdym połączonym urządzeniu w
dostawcy kontaktów, do którego aplikacja może uzyskać dostęp, aby wygenerować książkę adresową na każdym urządzeniu.
Aby można było nawiązać połączenie, profil musi być autoryzowany przez IVI i urządzenie mobilne. Gdy klient PBAP się rozłączy, wewnętrzna baza danych usunie wszystkie kontakty i historię połączeń powiązane z poprzednio 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 na interfejsie IVI. Zamiast tego, gdy połączone urządzenie zdalne odbierz wiadomość, IVI odbiera i analizuje wiadomość, a następnie przekazuje jej treść w ramach wystąpienia intencji, które może zostać odebrane przez aplikację.
Aby połączyć się z urządzeniem mobilnym w celu wysyłania i odbierania wiadomości, IVI musi zainicjować połączenie MAP.
MAXIMUM_CONNECTED_DEVICES
w
MapClientService
określa maksymalną liczbę jednoczesnych połączeń MAP z urządzeniem, które są dozwolone w ramach IVI. Aby można było przenosić wiadomości, każde połączenie musi zostać autoryzowane przez IVI i urządzenie mobilne.
Profil zaawansowanej dystrybucji audio
Profil zaawansowanej dystrybucji audio (A2DP) Bluetooth umożliwia pojazdowi odbieranie strumieni audio z połączonego urządzenia zdalnego.
W odróżnieniu od innych profili maksymalna liczba połączonych urządzeń A2DP jest wymuszana w natywnym stosie, a nie w Javie. Obecnie wartość jest zaszyta na stałe na poziomie 1
za pomocą zmiennej kDefaultMaxConnectedAudioDevices
w
packages/modules/Bluetooth/system/btif/src/btif_av.cc
.
Profil zdalnego sterowania audio/wideo
Profil Bluetooth do zdalnego sterowania dźwiękiem/obrazem (AVRCP) umożliwia sterowanie samochodem i przeglądanie odtwarzaczy multimediów na podłączonym urządzeniu. Ponieważ IVI pełni rolę kontrolera AVRCP, wszystkie wywołane elementy sterujące, które wpływają na odtwarzanie dźwięku, zależą od połączenia A2DP z urządzeniem docelowym.
Aby można było przeglądać określony odtwarzacz multimediów na telefonie z Androidem za pomocą IVI przez AVRCP, aplikacja multimedialna na telefonie musi udostępniać interfejs
MediaBrowserService
i umożliwiać com.android.bluetooth
dostęp do tej usługi. Szczegółowe informacje na ten temat znajdziesz w artykule
Tworzenie usługi przeglądarki multimediów.