Bluetooth

Android bietet eine vollständige Bluetooth Implementierung mit Unterstützung für viele gängige Bluetooth-Profile für Autos. Außerdem gibt es viele Verbesserungen, die die Leistung und die Nutzung mit anderen Geräten und Diensten verbessern.

Bluetooth-Verbindungsverwaltung

In Android verwaltet CarBluetoothService die Bluetooth-Geräte des aktuellen Nutzers und Prioritäts listen für jede Profilverbindung zum IVI. Geräte werden in einer festgelegten Prioritätsreihenfolge mit Profilen verbunden. Wann Geräte aktiviert, deaktiviert und mit einem Profil verbunden werden, wird durch eine Standardverbindungsrichtlinie bestimmt, die bei Bedarf mit einem Ressourcen-Overlay überschrieben werden kann.

Verbindungsverwaltung für Autos konfigurieren

Standardrichtlinie für Smartphones deaktivieren

Der Android-Bluetooth-Stack verwaltet eine Verbindungsrichtlinie für Smartphones, die standardmäßig aktiviert ist. Diese Richtlinie muss auf Ihrem Gerät deaktiviert werden, damit sie nicht mit der beabsichtigten Richtlinie für Autos in CarBluetoothService in Konflikt gerät. Das Car-Produkt-Overlay sollte dies für Sie übernehmen. Sie können die Richtlinie für Smartphones aber auch in einem Ressourcen-Overlay deaktivieren, indem Sie enable_phone_policy in MAXIMUM_CONNECTED_DEVICES in /packages/apps/Bluetooth/res/values/config.xml auf false setzen.

Standardrichtlinie für Autos verwenden

CarBluetoothService verwaltet die Standardberechtigungen für Profile. Die Liste der bekannten Geräte und ihre Prioritäten für die erneute Verbindung mit Profilen finden Sie in service/src/com/android/car/BluetoothProfileDeviceManager.java.

Die Richtlinie für die Bluetooth-Verbindungsverwaltung finden Sie in service/src/com/android/car/BluetoothDeviceConnectionPolicy.java. Standardmäßig werden in dieser Richtlinie die Fälle definiert, in denen eine Bluetooth-Verbindung zu gekoppelten Geräten hergestellt und getrennt werden soll. Außerdem werden darin die spezifischen Fälle für Autos verwaltet, in denen der Adapter ein- und ausgeschaltet werden soll.

Benutzerdefinierte Richtlinie für die Verbindungsverwaltung für Autos erstellen

Wenn die Standardrichtlinie für Autos nicht Ihren Anforderungen entspricht, kann sie auch zugunsten einer benutzerdefinierten Richtlinie deaktiviert werden. Ihre benutzerdefinierte Richtlinie ist mindestens dafür verantwortlich, zu bestimmen, wann der Bluetooth-Adapter aktiviert und deaktiviert und wann eine Verbindung zu Geräten hergestellt werden soll. Es ist möglich, eine Vielzahl von Ereignissen zu verwenden, um den Bluetooth Adapter zu aktivieren/deaktivieren und Geräteverbindungen zu initiieren, einschließlich Ereignissen aufgrund von Änderungen an bestimmten Eigenschaften des Autos.

Standardrichtlinie für Autos deaktivieren

Wenn Sie eine benutzerdefinierte Richtlinie verwenden möchten, muss zuerst die Standardrichtlinie für Autos deaktiviert werden. Setzen Sie dazu useDefaultBluetoothConnectionPolicy in einem Ressourcen-Overlay auf false. Diese Ressource ist ursprünglich als Teil von MAXIMUM_CONNECTED_DEVICES in packages/services/Car/service/res/values/config.xml definiert.

Bluetooth-Adapter aktivieren und deaktivieren

Eine der Kernfunktionen Ihrer Richtlinie besteht darin, den Bluetooth-Adapter zu den entsprechenden Zeiten ein- und auszuschalten. Sie können die BluetoothAdapter.enable() und BluetoothAdapter.disable() Framework-APIs verwenden, um den Adapter zu aktivieren und zu deaktivieren. Bei diesen Aufrufen sollte der gespeicherte Zustand berücksichtigt werden, den der Nutzer über die Einstellungen oder auf andere Weise ausgewählt hat. Eine Möglichkeit hierfür ist folgende:

/**
 * 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);
}

Bestimmen, wann der Bluetooth-Adapter ein- und ausgeschaltet werden soll

Mit Ihrer benutzerdefinierten Richtlinie können Sie kostenlos bestimmen, welche Ereignisse die besten Zeiten zum Aktivieren und Deaktivieren des Adapters angeben. Eine Möglichkeit hierfür ist die Verwendung der Energiestatus MAXIMUM_CONNECTED_DEVICES in 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;
        }
    }
};

Bestimmen, wann eine Verbindung zu Geräten hergestellt werden soll

Wenn Sie die Ereignisse bestimmen, die Geräteverbindungen auslösen sollen, bietet CarBluetoothManager den connectDevices() API-Aufruf, mit dem Geräte basierend auf den für jedes Bluetooth-Profil definierten Prioritätslisten verbunden werden.

Ein Beispiel dafür, wann Sie dies tun möchten, ist immer dann, wenn der Bluetooth-Adapter aktiviert wird:

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();
            }
        }
    }
}

Verbindungsverwaltung für Autos überprüfen

Die einfachste Möglichkeit, das Verhalten Ihrer Verbindungsrichtlinie zu überprüfen, besteht darin, Bluetooth auf Ihrem IVI zu aktivieren und zu prüfen, ob automatisch eine Verbindung zu den richtigen Geräten in der richtigen Reihenfolge hergestellt wird. Sie können den Bluetooth-Adapter über die Einstellungen oder mit den folgenden adb-Befehlen ein- und ausschalten:

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

Außerdem kann die Ausgabe des folgenden Befehls verwendet werden, um Debug-Informationen zu Bluetooth-Verbindungen zu sehen:

adb shell dumpsys car_service

Wenn Sie eine eigene Richtlinie für Autos erstellt haben, müssen Sie die Ereignisse steuern, die Sie zum Auslösen von Geräteverbindungen ausgewählt haben, um das benutzerdefinierte Verbindungsverhalten zu überprüfen.

Bluetooth-Profile für Autos

In Android kann das IVI mehrere Geräte unterstützen, die gleichzeitig über Bluetooth verbunden sind. Mit Bluetooth-Telefondiensten für mehrere Geräte können Nutzer mehrere Geräte gleichzeitig verbinden, z. B. ein privates und ein geschäftliches Smartphone, und mit beiden Geräten freihändig telefonieren.

Verbindungslimits werden von jedem einzelnen Bluetooth-Profil erzwungen, in der Regel innerhalb der Implementierung des Profildienstes selbst. Standardmäßig CarBluetoothService trifft keine weitere Entscheidung über die maximal zulässige Anzahl verbundener Geräte.

Hands-Free Profile

Mit dem Bluetooth Hands-Free Profile (HFP) kann das Fahrzeug über ein verbundenes Remote-Gerät Anrufe tätigen und entgegennehmen. Bei jeder Geräteverbindung wird ein separates Telefon Konto bei TelecomManager registriert, der alle verfügbaren Telefonkonten für die IVI-Apps bewirbt.

Das IVI kann über HFP eine Verbindung zu mehreren Geräten herstellen. MAX_STATE_MACHINES_POSSIBLE MAXIMUM_CONNECTED_DEVICES in HeadsetClientService definiert die maximale Anzahl gleichzeitiger HFP Verbindungen.

Wenn ein Nutzer einen Anruf von einem Gerät aus tätigt oder entgegennimmt, erstellt das entsprechende Telefonkonto ein HfpClientConnection Objekt. Die Dialer-App interagiert mit dem HfpClientConnection Objekt, um Anruffunktionen wie das Annehmen oder Auflegen zu verwalten.

Die Standard-Dialer-App unterstützt keine mehreren gleichzeitig verbundenen HFP-Geräte. Um HFP für verschiedene Geräte zu implementieren, ist eine Anpassung erforderlich, damit Nutzer auswählen können, welches Gerätekonto beim Tätigen eines Anrufs verwendet werden soll. Die App ruft dann telecomManager.placeCall mit dem richtigen Konto auf. Sie müssen auch prüfen, ob andere Funktionen für mehrere Geräte wie vorgesehen funktionieren.

HFP für mehrere Geräte überprüfen

So prüfen Sie, ob die Konnektivität für verschiedene Geräte über Bluetooth ordnungsgemäß funktioniert:

  1. Verbinden Sie ein Gerät über Bluetooth mit dem IVI und streamen Sie Audio vom Gerät.
  2. Verbinden Sie zwei Smartphones über Bluetooth mit dem IVI.
  3. Wählen Sie ein Smartphone aus. Tätigen Sie einen ausgehenden Anruf direkt vom Smartphone aus, und tätigen Sie einen ausgehenden Anruf über das IVI.
    1. Prüfen Sie beide Male, ob die Audiowiedergabe pausiert und die Audioausgabe über die mit dem IVI verbundenen Lautsprecher erfolgt.
  4. Nehmen Sie mit demselben Smartphone einen eingehenden Anruf direkt auf dem Smartphone und einen eingehenden Anruf über das IVI entgegen.
    1. Prüfen Sie beide Male, ob die Audiowiedergabe pausiert und die Audioausgabe über die mit dem IVI verbundenen Lautsprecher erfolgt.
  5. Wiederholen Sie die Schritte 3 und 4 mit dem anderen verbundenen Smartphone.

Notrufe

Die Möglichkeit, Notrufe zu tätigen, ist ein wichtiger Aspekt der Telefonie- und Bluetooth-Funktionen im Auto. Es gibt mehrere Möglichkeiten, einen Notruf vom IVI aus zu initiieren, darunter:

  • Eigenständige eCall-Lösung
  • In das IVI integrierte eCall-Lösung
  • Verwenden eines verbundenen Bluetooth-Smartphones, wenn kein integriertes System verfügbar ist

Notruf verbinden

eCall-Geräte sind sicherheitskritisch, aber derzeit nicht in Android integriert. Es ist möglich, ConnectionService zu verwenden, um Notruffunktionen über Android verfügbar zu machen. Das hat auch den Vorteil, dass Optionen für die Barrierefreiheit für Notrufe eingeführt werden. Weitere Informationen finden Sie unter Erstellen einer Anruf-App.

Hier ein Beispiel für das Einrichten eines Notfall- 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);
    }
}

Bluetooth für Notrufe aktivieren

Vor Android 10 wurden Notrufe direkt von einem Smartphone aus getätigt und spezielle Geräte aufgerufen (z. B. automatische Auslösung bei Erkennung einer Gefahr oder durch eine Nutzeraktion). In Android 10 und höher kann der Dialer im Auto direkt eine Notrufnummer anrufen, sofern MAXIMUM_CONNECTED_DEVICES in 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>

Durch die Implementierung von Notrufen auf diese Weise können auch andere Apps, z. B. die Spracherkennung, eine Notrufnummer anrufen.

Phone Book Access Profile

Mit dem Bluetooth Phone Book Access Profile (PBAP) werden Kontakte und Anruflisten von einem verbundenen Remote-Gerät heruntergeladen. PBAP verwaltet eine aggregierte, durchsuchbare Liste von Kontakten, die von der PBAP-Client-Statusmaschine aktualisiert wird. Jedes verbundene Gerät interagiert mit einer separaten PBAP-Client-Statusmaschine, sodass Kontakte beim Tätigen eines Anrufs dem richtigen Gerät zugeordnet werden.

PBAP ist unidirektional und erfordert daher, dass das IVI Verbindungen zu allen MAXIMUM_CONNECTED_DEVICES in PbapClientService instanziiert. Hier wird die maximale Anzahl gleichzeitiger PBAP-Geräte Verbindungen definiert, die mit dem IVI zulässig sind. Der PBAP-Client speichert die Kontakte für jedes verbundene Gerät im Contacts Provider, auf den dann von einer App zugegriffen werden kann, um das Telefon buch für jedes Gerät abzuleiten.

Außerdem muss die Profilverbindung sowohl vom IVI als auch vom Mobilgerät autorisiert werden, damit eine Verbindung hergestellt werden kann. Wenn ein PBAP-Client die Verbindung trennt, werden in der internen Datenbank alle Kontakte und die Anrufliste entfernt, die mit dem zuvor verbundenen Gerät verknüpft sind.

Message Access Profile

Mit dem Bluetooth Message Access Profile (MAP) kann das Fahrzeug über ein verbundenes Remote-Gerät SMS Nachrichten senden und empfangen. Derzeit werden Nachrichten nicht lokal auf dem IVI gespeichert. Wenn das verbundene Remote-Gerät eine Nachricht empfängt, empfängt und parst das IVI die Nachricht und sendet ihren Inhalt in einer Intent-Instanz, die dann von einer App empfangen werden kann.

Um eine Verbindung zu einem Mobilgerät herzustellen, um Nachrichten zu senden und zu empfangen Nachrichten, muss das IVI die MAP-Verbindung initiieren. MAXIMUM_CONNECTED_DEVICES in MapClientService definiert die maximale Anzahl gleichzeitiger MAP-Geräteverbindungen, die mit dem IVI zulässig sind. Jede Verbindung muss vom IVI und vom Mobilgerät autorisiert werden, bevor Nachrichten übertragen werden können.

Advanced Audio Distribution Profile

Mit dem Bluetooth Advanced Audio Distribution Profile (A2DP) kann das Fahrzeug Audiostreams von einem verbundenen Remote-Gerät empfangen.

Im Gegensatz zu anderen Profilen wird die maximale Anzahl verbundener A2DP-Geräte im nativen Stack und nicht in Java erzwungen. Der Wert ist derzeit mit 1 unter Verwendung der kDefaultMaxConnectedAudioDevices Variablen in packages/modules/Bluetooth/system/btif/src/btif_av.cc fest codiert.

Audio/Video Remote Control Profile

Mit dem Bluetooth Audio/Video Remote Control Profile (AVRCP) kann das Fahrzeug Media-Player auf einem verbundenen Remote-Gerät steuern und durchsuchen. Da das IVI die Rolle eines AVRCP-Controllers spielt, basieren alle ausgelösten Steuerelemente, die die Audiowiedergabe beeinflussen, auf einer A2DP Verbindung zum Zielgerät.

Damit ein bestimmter Media-Player auf einem Android-Smartphone über AVRCP vom IVI durchsucht werden kann, muss die Media-App auf dem Smartphone einen MediaBrowserService bereitstellen und com.android.bluetooth Zugriff auf diesen Dienst gewähren. Unter Medienbrowser-Dienst erstellen wird ausführlich beschrieben, wie Sie das tun.