Cómo conectar el dispositivo Android a un dispositivo iOS a través de BLE (Bluetooth de bajo consumo)

Estoy intentando hacer una aplicación que use la nueva API Bluetooth Low Energy de Android. Para esto, comencé con la muestra BLE que viene con el nivel 18 de la API .

Cuando leí que Android no puede funcionar como un periférico, puse el teléfono Android en modo central, buscando dispositivos BLE a su alnetworkingedor. Para este propósito, hice algunas testings con una plataforma nórdica que simula un sensor cardíaco. ¡Todo funciona de manera perfecta!

Después de esto, trato de elegir un iPhone (iOS 7 beta 4) y ponerlo de manera Periférica y simular un sensor de frecuencia cardíaca como las testings anteriores. La aplicación de Android puede ver el dispositivo y conectarse a él. Pero después de que la connection está activa, los 2 dispositivos se desconectan entre sí en 3-4 segundos. Además de eso, cuando llamo a discoverServices () en el lado de Android, ¡no se activa ninguna callback! En algunos casos, el dispositivo Android recibe el evento "Conectado" incluso si el chip Bluetooth iOS está Desactivado. Esto es muy extraño. Para demostrarlo, puse el Tablero nórdico en modo central y pude conectarme correctamente al dispositivo iOS sin problemas.

¿Qué podría ser? ¿Hay algunas limitaciones en Android o iOS que no permiten conectarse desde un Android a un iOS o viceversa?

Gracias.

EDITAR: Después de algunas testings difíciles, planteé un problema en la página AOSP. Se puede verificar aquí.

Agregando un resumen para reference:

¿Qué podría ser? ¿Hay algunas limitaciones en Android o iOS que no permiten conectarse desde un Android a un iOS o viceversa?

Cuando se conecta a un server GATT que se anuncia como dispositivo de modo dual (BLE y BR / EDR) llamando a connectGatt (…), el indicador TRANSPORT_AUTO que se agrega internamente convierte a Android en pnetworkingeterminado en el modo BR / EDR ( enlace ).

Las posibles soluciones son posibles:

  1. Lado periférico: deje de anunciar las capacidades de BR / EDR ajustando las banderas apropiadas ( enlace )
  2. Lado central: configura el parámetro de transporte explícitamente en TRANSPORT_LE llamando a la versión oculta de connectGatt () usando la reflexión

Ejemplo:

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

Edición 4/2016

Como señaló Arbel Israel en el comentario, Google introdujo una versión sobrecargada de connectGatt (…) que permite especificar el transporte en Android M.

He escrito un simple ejemplo de trabajo, bien relativamente simple, y lo he incluido de código abierto en Github: https://github.com/GitGarage . Hasta ahora solo se ha probado con un Android Nexus 9 y un iPhone 5s, pero supongo que también funcionaría con un Nexus 6 y varios types de iPhone. Hasta ahora se configuró explícitamente para comunicarse entre un Android y un iPhone, pero presumo que es posible hacerlo mucho más.

Tal vez un poco retrasado, pero tal vez su dolor puede aliviarse un poco;)

Hemos estado experimentando mucho con conexiones multiplataforma BLE (iOS <-> Android) y hemos aprendido que todavía hay muchas incompatibilidades y problemas de connection. Aparte de la inestabilidad de Android, también debería considerar que, a día de hoy, no muchos dispositivos Android son compatibles con el modo BLE Periférico.

Por lo tanto, si su caso de uso está basado en funciones y solo necesita un intercambio de datos básico, sugiero que busque Frameworks and Libraries que puedan lograr comunicación multiplataforma sin necesidad de buildlo desde cero.

Por ejemplo: http://p2pkit.io o google cerca

Descargo de responsabilidad: trabajo para Uepaa, desarrollando p2pkit.io para Android e iOS.