So verbinden Sie ein Android-Gerät über BLE (Bluetooth Low Energy) mit einem iOS-Gerät

82

Ich versuche eine Anwendung zu erstellen, die die neue Bluetooth Low Energy API von Android verwendet. Zu diesem Zweck habe ich mit dem BLE-Beispiel begonnen, das mit API-Level 18 geliefert wurde .

Als ich las, dass Android nicht als Peripheriegerät fungieren kann, versetzte ich das Android-Telefon in den zentralen Modus und suchte nach BLE-Geräten . Zu diesem Zweck habe ich einige Tests mit einer nordischen Plattform durchgeführt, die einen Herzsensor simuliert. Alles funktioniert perfekt!

Danach versuche ich, ein iPhone (iOS 7 Beta 4) auszuwählen , es peripher zu platzieren und einen Herzfrequenzsensor wie beim vorherigen Test zu simulieren . Die Android-App kann das Gerät sehen und eine Verbindung herstellen. Nachdem die Verbindung aktiv ist, trennen sich die beiden Geräte innerhalb von 3-4 Sekunden voneinander. Wenn ich auf Android-Seite removeServices () aufrufe, wird außerdem kein Rückruf ausgelöst! In einigen Fällen empfängt das Android-Gerät das Ereignis "Verbunden", auch wenn der iOS-Bluetooth-Chip ausgeschaltet ist. Das ist sehr seltsam. Um dies zu beweisen, habe ich das Nordic Board in den Zentralmodus versetzt und konnte problemlos eine Verbindung zum iOS-Gerät herstellen.

Was könnte es sein? Es gibt einige Einschränkungen für Android oder iOS, die keine Verbindung von Android zu iOS oder umgekehrt zulassen.

Vielen Dank.

EDIT: Nach einigen harten Tests habe ich ein Problem auf der AOSP-Seite angesprochen. Es kann hier überprüft werden

edoardotognoni
quelle
2
Laut Dokumentation unterstützt Android DOES die Ausführung als Server (z. B. als Herzfrequenzmesser), obwohl die generierten Werte gefälscht sind. Auf der anderen Seite gibt es keine Beispiele, die Dokumentation fordert Sie auf, falsche Dinge zu tun, und es gibt keine Möglichkeit, Werbung zu starten (obwohl die Dokumentation besagt, dass Sie dies können).
Brian Reinhold
Du hast recht. Ich habe bereits den Dokumentfehler über BluetoothGattServer gefunden. Sie können die GattServer-Instanz nicht mit der Methode getProfileProxy haben (wie im Dokument angegeben), aber Sie können dies über BluetoothManager.openGattServer () tun. Es wurde bereits als Problem an Google gemeldet. Auf jeden Fall kann Android als GattServer fungieren, aber keine Werbung schalten. Wenn Sie interessiert sein könnten, habe ich bereits getestet und nach der Verbindung der 2 Geräte kann die Fernbedienung die Gatt-Server sehen, die von Android verfügbar gemacht wurden. Überprüfen Sie die Kommentare der ersten Antwort, um meinen Problembericht zu dieser Frage zu sehen.
Edoardotognoni
Ja, ich bin auch darauf gestoßen und habe meine zwei Cent zu diesem Thema hinzugefügt. Jetzt habe ich einen Thermometer-Server, der keine Werbung machen kann, sodass ich ihn nicht verwenden kann.
Brian Reinhold
Ich habe einen Thread geöffnet, der fast mit Ihrem identisch ist: stackoverflow.com/questions/18410081/… Ich werde diesen Thread nach Lösungen durchsuchen, die Sie finden.
Afrederick
Lesen Sie die Android-Ausgabe, die ich im Abschnitt BEARBEITEN der Frage gepostet habe. Es ist klar zu erklären, warum dieser Prozess fehlschlägt. Wir denken, es ist ein Android-Fehler. Hauptsächlich wird eine nicht zulässige Nachricht über einen festen BLE-Kanal gesendet. Ich denke, das einzige, was wir tun können, ist auf eine neue Android-Version zu warten :(
edoardotognoni

Antworten:

7

Hinzufügen einer Zusammenfassung als Referenz:

Was könnte es sein? Es gibt einige Einschränkungen für Android oder iOS, die keine Verbindung von Android zu iOS oder umgekehrt zulassen.

Wenn Sie eine Verbindung zu einem GATT-Server herstellen, der durch Aufrufen von connectGatt (...) als Dualmode-Gerät (BLE und BR / EDR) angekündigt wird, wird Android durch das intern hinzugefügte TRANSPORT_AUTO-Flag standardmäßig auf den BR / EDR-Modus ( Link ) zurückgesetzt.

Folgende Problemumgehungen sind möglich:

  1. Periphere Seite: Stoppen Sie die Werbung für BR / EDR-Funktionen, indem Sie die entsprechenden Flags anpassen ( Link ).
  2. Zentrale Seite: Setzen Sie den Transportparameter explizit auf TRANSPORT_LE, indem Sie die versteckte Version von connectGatt () mithilfe von Reflection aufrufen

Beispiel:

public void connectToGatt(BluetoothDevice device) {    
   ...    
   Method m = device.getClass().getDeclaredMethod("connectGatt", Context.class, boolean.class, BluetoothGattCallback.class, int.class);    
   int transport = device.getClass().getDeclaredField("TRANSPORT_LE").getInt(null);     // LE = 2, BREDR = 1, AUTO = 0    
   BluetoothGatt mGatt = (BluetoothGatt) m.invoke(device, this, false, gattCallback, transport);    
   ... 
}

Bearbeiten 4/2016

Wie Arbel Israeli in dem Kommentar betonte, führte Google eine überladene Version von connectGatt (...) ein , mit der der Transport in Android M angegeben werden kann .

Dominik Gebhart
quelle
Vielen Dank, das funktioniert bei mir. Beachten Sie, dass Google in Android M eine Überladung für die connectGatt-Methode hinzugefügt hat, die eine Transportvariable verwendet: connectGatt (Kontextkontext, boolesches autoConnect, BluetoothGattCallback-Rückruf, int transport)
arbel03
1
Oh, danke für diesen Hinweis, also haben sie ihn endlich verfügbar gemacht.
Dominik Gebhart
2

Ich habe ein einfaches Arbeitsbeispiel geschrieben, das relativ einfach ist, und es Open Source in Github aufgenommen: https://github.com/GitGarage . Bisher wurde es nur mit einem Android Nexus 9 und einem iPhone 5s getestet, aber ich gehe davon aus, dass es auch mit einem Nexus 6 und verschiedenen iPhone-Typen funktionieren würde. Bisher ist es explizit für die Kommunikation zwischen einem Android und einem iPhone eingerichtet, aber ich gehe davon aus, dass es optimierbar ist, viel mehr zu tun.

Omikes
quelle
2

Vielleicht etwas verspätet, aber vielleicht können deine Schmerzen etwas gelindert werden;)

Wir haben viel mit plattformübergreifenden BLE-Verbindungen (iOS <-> Android) experimentiert und festgestellt, dass es immer noch viele Inkompatibilitäten und Verbindungsprobleme gibt. Abgesehen von der Instabilität von Android sollten Sie auch berücksichtigen, dass bis heute nicht viele Android-Geräte den BLE-Peripheriemodus unterstützen.

Wenn Ihr Anwendungsfall funktionsgesteuert ist und Sie nur einen grundlegenden Datenaustausch benötigen, würde ich empfehlen, sich Frameworks und Bibliotheken anzuschauen, die eine plattformübergreifende Kommunikation für Sie ermöglichen, ohne dass Sie diese von Grund auf neu aufbauen müssen.

Zum Beispiel: http://p2pkit.io oder Google in der Nähe

Haftungsausschluss: Ich arbeite für Uepaa und entwickle p2pkit.io für Android und iOS.

p2pkit
quelle
1

Sie können jetzt TRANSPORT_LEüber BluetoothDevice.connectGattab API 23 übergeben.

Bitte beachten Sie die folgenden Hinweise zur Android-Dokumentation:

Kevin Crain
quelle
0

iOS-Geräte sind immer Peripheriegeräte oder Zentralgeräte, Android-Geräte jedoch nicht selten. In diesem Fall muss Ihr iOS-Gerät ein Peripheriegerät und Android ein Zentralgerät sein. Wir können uns vorstellen, dass Peripheriegeräte ein Server und Zentralgeräte ein Client sind. Dies ist einfach.

Mustafa Demir
quelle