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:
- Peripheral side: Stop advertising BR/EDR capabilities by adjusting
the appropriate flags (link) - 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.