Bluetooth

Android zapewnia pełną implementację Bluetooth z obsługą wielu popularnych profili Bluetooth w samochodzie. Istnieje również wiele ulepszeń, które poprawiają wydajność i doświadczenie z innymi urządzeniami i usługami.

Zarządzanie połączeniem Bluetooth

W systemie Android CarBluetoothService przechowuje urządzenia Bluetooth bieżącego użytkownika i listy priorytetów dla każdego połączenia profilu z IVI. Urządzenia są podłączane do profili w określonej kolejności priorytetów. To, kiedy włączyć, wyłączyć i podłączyć urządzenia do profilu, zależy od domyślnych zasad połączeń, które w razie potrzeby można zastąpić za pomocą nakładki zasobów .

Skonfiguruj zarządzanie połączeniami samochodowymi

Wyłącz domyślne zasady dotyczące telefonu

Stos Bluetooth systemu Android utrzymuje zasady połączeń dla telefonów, które są domyślnie włączone. Ta zasada musi być wyłączona na Twoim urządzeniu, aby nie kolidowała z zamierzoną polityką motoryzacyjną w CarBluetoothService . Chociaż nakładka produktu samochodowego powinna zająć się tym za Ciebie, możesz wyłączyć zasady 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 .

Użyj domyślnej polityki motoryzacyjnej

CarBluetoothService zachowuje domyślne uprawnienia profilu. Lista znanych urządzeń i ich priorytetów ponownego łączenia profili znajduje się w service/src/com/android/car/BluetoothProfileDeviceManager.java .

Zasady zarządzania połączeniami Bluetooth można również znaleźć w service/src/com/android/car/BluetoothDeviceConnectionPolicy.java . Domyślnie ta zasada definiuje przypadki, w których Bluetooth powinien łączyć się i rozłączać z połączonymi urządzeniami. Zarządza także przypadkami specyficznymi dla samochodu, określając, kiedy należy włączyć i wyłączyć adapter.

Stwórz własną, niestandardową politykę zarządzania połączeniami motoryzacyjnymi

Jeżeli domyślna polisa samochodowa nie jest dla Twoich potrzeb wystarczająca, możesz ją również wyłączyć na rzecz własnej polisy niestandardowej. Twoja niestandardowa polityka odpowiada co najmniej za określenie, kiedy włączyć i wyłączyć adapter Bluetooth, a także kiedy podłączyć urządzenia. Można używać różnych zdarzeń do włączania/wyłączania adaptera Bluetooth i inicjowania połączeń z urządzeniami, włączając w to zdarzenia spowodowane zmianami określonych właściwości samochodu.

Wyłącz domyślną politykę motoryzacyjną

Po pierwsze, aby użyć polityki niestandardowej, należy wyłączyć domyślną politykę samochodową, ustawiając useDefaultBluetoothConnectionPolicy na false w nakładce zasobów . Zasób ten jest oryginalnie zdefiniowany jako część MAXIMUM_CONNECTED_DEVICES w packages/services/Car/service/res/values/config.xml .

Włącz i wyłącz adapter Bluetooth

Jedną z podstawowych funkcji Twojej polityki jest włączanie i wyłączanie adaptera Bluetooth w odpowiednim czasie. Do włączania i wyłączania adaptera można używać interfejsów API platformy BluetoothAdapter.enable() i BluetoothAdapter.disable() . Wywołania te powinny uwzględniać utrwalony stan wybrany przez użytkownika w Ustawieniach lub w jakikolwiek inny sposób. Można to zrobić w następujący 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łączyć i wyłączyć adapter Bluetooth

Dzięki niestandardowym zasadom możesz określić, które zdarzenia wskazują najlepszy moment na włączenie i wyłączenie adaptera. Jednym z takich 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śl, kiedy podłączyć urządzenia

Podobnie, gdy określisz zdarzenia, które powinny spowodować rozpoczęcie połączeń urządzeń, CarBluetoothManager udostępnia wywołanie API connectDevices() , które powoduje połączenie urządzeń w oparciu o listy priorytetów zdefiniowane dla każdego profilu Bluetooth.

Jednym z przykładów sytuacji, w której warto to zrobić, jest włączenie adaptera 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();
            }
        }
    }
}

Sprawdź zarządzanie połączeniami samochodowymi

Najłatwiejszym sposobem sprawdzenia działania zasad połączeń jest włączenie funkcji Bluetooth w urządzeniu IVI i sprawdzenie, czy automatycznie łączy się ono z właściwymi urządzeniami w odpowiedniej kolejności. Możesz przełączać adapter Bluetooth za pomocą interfejsu ustawień lub za pomocą następujących 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

Ponadto dane wyjściowe następującego polecenia można wykorzystać do wyświetlenia informacji debugowania związanych z połączeniami Bluetooth:

adb shell dumpsys car_service

Wreszcie, jeśli masz własną politykę motoryzacyjną, weryfikacja niestandardowego zachowania połączenia wymaga kontrolowania zdarzeń wybranych do wyzwalania połączeń urządzeń.

Samochodowe profile Bluetooth

W systemie Android IVI może obsługiwać wiele urządzeń jednocześnie podłączonych przez Bluetooth. Usługi telefoniczne Bluetooth obsługujące wiele urządzeń umożliwiają użytkownikom jednoczesne podłączanie oddzielnych urządzeń, takich jak telefon osobisty i telefon służbowy, oraz wykonywanie połączeń w trybie głośnomówiącym z dowolnego urządzenia.

Limity połączeń są egzekwowane przez każdy indywidualny profil Bluetooth, zwykle w ramach samej implementacji usługi profilu. Domyślnie CarBluetoothService nie ocenia maksymalnej dozwolonej liczby podłączonych urządzeń.

Profil głośnomówiący

Profil zestawu głośnomówiącego Bluetooth (HFP) umożliwia wykonywanie i odbieranie połączeń telefonicznych za pośrednictwem podłączonego urządzenia zdalnego. Każde połączenie urządzenia rejestruje osobne konto telefoniczne w TelecomManager , który reklamuje wszystkie dostępne konta telefoniczne w aplikacjach IVI.

IVI może łączyć się z wieloma urządzeniami za pośrednictwem HFP. MAX_STATE_MACHINES_POSSIBLE MAXIMUM_CONNECTED_DEVICES w HeadsetClientService definiuje maksymalną liczbę jednoczesnych połączeń HFP.

Gdy użytkownik nawiązuje lub odbiera połączenie telefoniczne z urządzenia, odpowiednie konto telefoniczne tworzy obiekt HfpClientConnection . Aplikacja Dialer współdziała z obiektem HfpClientConnection w celu zarządzania funkcjami połączeń, takimi jak akceptowanie połączenia lub rozłączanie się.

Należy zauważyć, że domyślna aplikacja Dialer nie obsługuje wielu jednocześnie podłączonych urządzeń HFP. Aby wdrożyć HFP obsługujący wiele urządzeń, wymagane jest dostosowanie umożliwiające użytkownikom wybór konta urządzenia, z którego będą korzystać podczas wykonywania połączenia. Następnie aplikacja wywołuje telecomManager.placeCall z właściwym kontem. Musisz sprawdzić, czy inne funkcje wielu urządzeń również działają zgodnie z oczekiwaniami.

Sprawdź HFP obsługujący wiele urządzeń

Aby sprawdzić, czy łączność z wieloma urządzeniami działa prawidłowo przez Bluetooth:

  1. Korzystając z Bluetooth, podłącz urządzenie do IVI i przesyłaj strumieniowo dźwięk z urządzenia.
  2. Podłącz dwa telefony do IVI przez Bluetooth.
  3. Wybierz jeden telefon. Nawiązuj połączenie wychodzące bezpośrednio z telefonu i nawiązuj połączenie wychodzące za pomocą IVI.
    1. W obu przypadkach sprawdź, czy dźwięk przesyłany strumieniowo jest przerywany, a dźwięk telefonu jest odtwarzany przez głośniki podłączone do IVI.
  4. Korzystając z tego samego telefonu, możesz odbierać połączenia przychodzące bezpośrednio na telefonie i odbierać połączenia przychodzące za pomocą IVI.
    1. W obu przypadkach sprawdź, czy przesyłanie strumieniowe dźwięku zostaje wstrzymane, a dźwięk telefonu jest odtwarzany przez podłączone głośniki IVI.
  5. Powtórz kroki 3 i 4 z drugim podłączonym telefonem.

Połączenia alarmowe

Możliwość wykonywania połączeń alarmowych jest ważnym aspektem funkcji telefonii i Bluetooth w samochodzie. Istnieje wiele sposobów zainicjowania połączenia alarmowego z IVI, w tym:

  • Samodzielne rozwiązanie eCall
  • Rozwiązanie eCall zintegrowane z IVI
  • Poleganie na podłączonym telefonie Bluetooth, gdy nie jest dostępny żaden wbudowany system

Połącz połączenie alarmowe

Chociaż sprzęt eCall ma kluczowe znaczenie dla bezpieczeństwa, obecnie nie jest zintegrowany z systemem Android. Możliwe jest użycie usługi ConnectionService w celu udostępnienia funkcji połączeń alarmowych za pośrednictwem systemu Android, co ma również tę zaletę, że wprowadza opcje ułatwień dostępu dla połączeń alarmowych. Aby dowiedzieć się więcej, zobacz Tworzenie aplikacji do połączeń .

Oto przykład ustanawiania usługi połączenia awaryjnego:

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łącz Bluetooth dla połączeń alarmowych

Wezwanie alarmowe przed Androidem 10 wymagało bezpośredniego wybierania numeru z telefonu i wywoływania specjalnego sprzętu, jeśli był dostępny (na przykład automatycznego wyzwalania po wykryciu niebezpieczeństwa lub działaniu użytkownika). W Androidzie 10 i nowszych Dialer w samochodzie może bezpośrednio zadzwonić na 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>

Implementując w ten sposób połączenia alarmowe, inne aplikacje, takie jak 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 historie połączeń z podłączonego urządzenia zdalnego. PBAP utrzymuje zagregowaną listę kontaktów z możliwością przeszukiwania, która jest aktualizowana przez maszynę stanu klienta PBAP. Każde podłączone urządzenie współdziała z oddzielną maszyną stanu klienta PBAP, co powoduje, że podczas wykonywania połączenia kontakty są kojarzone z właściwym urządzeniem.

PBAP jest jednokierunkowy i dlatego wymaga, aby IVI utworzył instancję połączeń z dowolnymi MAXIMUM_CONNECTED_DEVICES w PbapClientService . Określa maksymalną liczbę jednoczesnych połączeń urządzeń PBAP dozwolonych przez IVI. Klient PBAP przechowuje kontakty dla każdego podłączonego urządzenia w dostawcy kontaktów , do którego aplikacja może następnie uzyskać dostęp w celu uzyskania książki telefonicznej dla każdego urządzenia.

Ponadto, aby połączenie mogło zostać nawiązane, połączenie profilowe musi zostać autoryzowane zarówno przez IVI, jak i urządzenie mobilne. Kiedy klient PBAP rozłączy się, wewnętrzna baza danych usuwa wszystkie kontakty i historię połączeń powiązaną z poprzednio podłączonym urządzeniem.

Profil dostępu do wiadomości

Profil dostępu do wiadomości Bluetooth (MAP) umożliwia wysyłanie i odbieranie wiadomości SMS za pośrednictwem podłączonego urządzenia zdalnego. Obecnie wiadomości nie są przechowywane lokalnie w IVI. Zamiast tego, za każdym razem, gdy podłączone urządzenie zdalne odbierze wiadomość, IVI odbiera i analizuje wiadomość, a następnie emituje jej zawartość w instancji Intent , która może zostać następnie odebrana 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 definiuje maksymalną liczbę jednoczesnych połączeń urządzeń MAP dozwolonych z IVI. Każde połączenie musi zostać autoryzowane przez IVI i urządzenie mobilne, zanim będzie można przesłać wiadomości.

Zaawansowany profil dystrybucji audio

Profil zaawansowanej dystrybucji audio Bluetooth (A2DP) umożliwia odbieranie przez pojazd strumieni audio z podłączonego urządzenia zdalnego.

W przeciwieństwie do innych profili, maksymalna liczba podłączonych urządzeń A2DP jest wymuszana w natywnym stosie, a nie w Javie. Wartość jest obecnie zakodowana na stałe 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 audio/wideo Bluetooth (AVRCP) umożliwia sterowanie i przeglądanie odtwarzaczy multimedialnych na podłączonym urządzeniu zdalnym. Ponieważ IVI pełni rolę kontrolera AVRCP, wszelkie wyzwalane elementy sterujące wpływające na odtwarzanie dźwięku opierają się na połączeniu A2DP z urządzeniem docelowym.

Aby określony odtwarzacz multimedialny w telefonie z systemem Android mógł być przeglądany przez IVI za pośrednictwem AVRCP, aplikacja multimedialna w telefonie musi udostępniać usługę MediaBrowserService i umożliwiać com.android.bluetooth dostęp do tej usługi. Tworzenie usługi przeglądarki multimediów szczegółowo wyjaśnia, jak to zrobić.