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 według 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 pojazdów. Nakładka na produkt Car powinna załatwić to za Ciebie, ale możesz wyłączyć zasadę dotyczącą telefonu w
nakładzie zasobów, 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 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 określają, kiedy Bluetooth powinien łączyć się z połączonymi urządzeniami i rozłączać z nimi. 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 pojazdów
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ć i 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 połą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
Aby wyświetlić informacje debugowania dotyczące połączeń Bluetooth, możesz też 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 kilku urządzeń, np. telefonu osobistego i służbowego, 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.
Domyślna aplikacja Dialer nie obsługuje połączeń z kilkoma urządzeniami HFP jednocześnie. Aby wdrożyć HFP na wielu urządzeniach, musisz dostosować aplikację, aby umożliwić użytkownikom wybór konta urządzenia, którego mają 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 tego 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 IV.
- 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
- korzystanie z telefonu połączonego 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ć usługi ConnectionService. Daje to też możliwość wprowadzenia opcji 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 (np. automatycznego uruchamiania po wykryciu niebezpieczeństwa lub działania użytkownika). W Androidzie 10 i nowszych aplikacja 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 agregowaną, 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 uzyskać 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 rozłączy połączenie, baza danych wewnętrznej 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 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) umożliwia pojazdowi odbieranie strumieni audio z podłą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 zakodowana 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 pojazdem 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.