Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm trying to make an application which uses the new Bluetooth Low Energy API of Android. For this, I started with the BLE sample coming with API level 18.

As I read that Android can not act as a Peripheral, I put the Android phone in central mode, scanning for BLE devices around it. For this purpose, I made some testing with a Nordic Platform simulating a Heart Sensor. Everything works in a perfect way!

After this, I try to pick an iPhone (iOS 7 beta 4) and put it in a Peripheral way and simulating a Heart Rate sensor as the previous testing. The Android app is able to see the device and connect to it. But after the connection is active, the 2 devices disconnect from each other in 3-4 seconds. In addition to that, when I call discoverServices() on Android side, no callback is triggered! In some cases the Android device receives the "Connected" event even if iOS Bluetooth chip is Off. This is very strange. To prove that, I put the Nordic Board in Central mode and I was correctly able to connect to the iOS device with no problems.

What could it be? There are some limitations on Android or iOS that don't permit to connect from an Android to an iOS or viceversa?

Thanks.

EDIT: After some hard testing, I raised an issue on the AOSP page. It can be checked here

like image 693
edoardotognoni Avatar asked Aug 05 '13 07:08

edoardotognoni


People also ask

Is Bluetooth Low Energy compatible with Bluetooth?

It is independent of classic Bluetooth and has no compatibility, but Bluetooth Basic Rate/Enhanced Data Rate (BR/EDR) and LE can coexist.

What is Bluetooth Low Energy in iOS?

One of the main features of the Bluetooth 4 specification is Bluetooth Low Energy (BLE). Also called Bluetooth smart, this technology allows peripherals to communicate by consuming much less energy than regular Bluetooth.

How do I enable BLE on Android?

Once your app has permission to use Bluetooth, your app needs to access the BluetoothAdapter and determine if Bluetooth is available on the device. If Bluetooth is available, the device will scan for nearby BLE devices.


2 Answers

Adding a summary for reference:

What could it be? There are some limitations on Android or iOS that don't permit to connect from an Android to an iOS or viceversa?

When connecting to a GATT server that is advertised as dualmode (BLE and BR/EDR) device by calling connectGatt(...), the TRANSPORT_AUTO flag that is internally added makes Android to default to the BR/EDR mode (link).

Following workarounds are possible:

  1. Peripheral side: Stop advertising BR/EDR capabilities by adjusting the appropriate flags (link)
  2. Central side: Set the transport parameter explicitely 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 Arbel Israeli pointed out in the comment, Google introduced an overloaded version of connectGatt(...) which allows to specify the transport in Android M.

like image 174
Dominik Gebhart Avatar answered Oct 13 '22 05:10

Dominik Gebhart


I've written a simple working example, well relatively simple, and included it open-source on Github: https://github.com/GitGarage. So far it has only been tested with an Android Nexus 9 and an iPhone 5s, but I presume it would also work with a Nexus 6 and various iPhone types. So far it is set up explicitly to communicate between one Android and one iPhone, but I presume it is tweakable to do much more.

like image 21
omikes Avatar answered Oct 13 '22 04:10

omikes