How to connect an Android device to an iOS device via BLE (Bluetooth Low Energy)

I am trying to create an application using the new Bluetooth Low Energy API for Android. To do this, I started with a BLE sample coming with an API level of level 18 .

Since I read that Android cannot act as peripherals, I put the Android phone in central mode by browsing the BLE devices around it. For this purpose, I conducted several trials using the Nordic Platform, simulating a heart sensor. Everything works perfect!

After that, I try to select an iPhone (iOS 7 beta 4) and put it in the Peripheral way and simulate a heart rate sensor as the previous test. Android application can see the device and connect to it. But after the connection is activated, the two devices disconnect from each other after 3-4 seconds. In addition to this, when I call DiscoverServices () on the Android side, no callback fires! In some cases, the Android device receives the “Connected” event, even if the Bluetooth IOS chip is turned off. It is very strange. To prove this, I placed the Nordic Board in central mode and I was able to correctly connect to the iOS device without any problems.

What could it be? Are there some restrictions on Android or iOS that prevent you from connecting from Android to iOS or vice versa?

Thank.

EDIT: after some hard testing, I raised a question on the AOSP page. You can check it here.

+79
android ios android-4.3-jelly-bean bluetooth-lowenergy core-bluetooth
Aug 05 '13 at 7:21
source share
3 answers

Adding a summary for reference:

What could it be? Are there some restrictions on Android or iOS that prevent you from connecting from Android to iOS or vice versa?

When connected to a GATT server that is advertised as a dual-link device (BLE and BR / EDR) by calling connectGatt (...), the TRANSPORT_AUTO flag, which is added domestically, makes Android the default BR / EDR mode ( link ).

The following workarounds are possible:

  • Peripheral side: stop advertising BR / EDR features by setting the appropriate flags ( link )
  • Center side: set the transport parameter to TRANSPORT_LE by calling the hidden version of connectGatt () using reflection

Example:

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

Edit 4/2016

As noted by Arbel Israel , Google introduced an overloaded version of connectGatt (...) , which allows you to specify transport in Android M.

+6
Jul 12 '15 at 14:27
source share

I wrote a simple working example, quite simple, and included it in open source on Github: https://github.com/GitGarage . So far it has been tested only with Android Nexus 9 and iPhone 5, but I believe that it will also work with Nexus 6 and various types of iPhone. So far, it is explicitly configured for communication between one Android and one iPhone, but I believe that it is capable of doing much more.

+2
Jul 01 '15 at 20:47
source share

Maybe a little delay, but maybe your pain can be a little relieved;)

We experimented a lot with cross-platform BLE connections (iOS ↔ Android) and found out that there are still a lot of incompatibilities and connectivity issues. In addition to the instability of Android, you should also bear in mind that to date, not many Android devices actually support BLE peripheral mode.

Therefore, if your use case is related to a function, and you need only basic data exchange, I would suggest looking at Frameworks and libraries that can provide interaction between platforms for you, without the need to create it from scratch.

For example: http://p2pkit.io or google nearby

Disclaimer: I work for Uepaa, developing p2pkit.io for Android and iOS.

+2
May 3 '16 at 16:22
source share



All Articles