I've got a working app using CoreBluetooth to communicate between an iPad (central) and iPhone (peripheral). I have one service that has two characteristics. I have a Nexus 7 running the latest Android 4.3 with BTLE support. Android is a bit late to jump on the BTLE bandwagon but it appears they are approaching it similarly to how iOS did, where initially they only support acting as a central with the peripheral mode coming in a later version. I can load the sample Android BTLE app and browse for nearby peripherals. With my iPhone advertising as a peripheral I can see the value from CBAdvertisementDataLocalNameKey in the list of nearby peripherals on the Android side. I can connect to the iPhone and the Bluetooth symbol turns from light gray to black when the connection is made. The connection always lasts exactly 10 seconds and then disconnects. On the Android side I'm supposed to see a list of available services and characteristics appear immediately upon connection. I've proved the Android code is setup correctly because I can connnect it to the TI CC2541DK-SENSOR hardware that I have and all services and characteristics are listed upon connecting to it.
I've spent the last few days troubleshooting the issue with no success. The problem is I can't determine which device is experiencing an error and thus causing the disconnection. There are no callbacks from CBPeripheralManagerDelegate during the connection phase or service discovery phase so I have no idea at what point an error occurs (if the error is on the iOS side). On the Android side a method is called to initiate service discovery however their callback "onServicesDiscovered" is never called which is perplexing. Is there any way I can dig into the guts of the BTLE communication on the iOS side to see what's going on and determine what error is taking place?
I've already gone through this for at least one week having this same issue. I've already asked a question here and I've already answered on my own. The main problem is an Android BUG issue. It's sending a non permitted command on a fixed L2CAP channnel.
But when Android is communicating with normal peripheral BLE devices, it works pretty well. In fact, the BLE sample works like a charm. The problem is when is comunicating with an iOS device for example: Just after the connection is made, they start negotiating their connection parameters (this phase doesn't happen with normal BLE peripheral), and this is when the problem comes up. Android sends a bad command to iOS, iOS drops the connection. That's basically how it works
Some issues have been already reported to Google, and one of them have been already accepted and I hope they will start working on it soon.
Unfortunately, what you can do, is to wait until next Android release. Anyway, I highly suggest you to have a look at my issue report with all my test documents if you want to make some light on this problem.
Here's the link: https://code.google.com/p/android/issues/detail?id=58725
I just wanted to share my knowledge on that as I dealt with it some time ago and I quit as there is no support by google. The aforementioned code, what I thank a lot, does not work. You can code in a reasonable time an iOS to iOS or android to android bluetooth le application but the problem comes when you try to communicate between iOS and android. There is a well documented google issue (https://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&groupby=&sort=&id=58725) I collaborated but google didnt pronounce at all and it seems they closed the issue and nothing has changed in android M as Ive been looking into the code and can´t see no further differences. The problem comes when Android tries to connect and specifically in a "if else" sentence; this code basically rejects the transmission and cuts the communication so it doesn´t work. At the moment, there is no solution for that. You can do a WiFi direct solution, but it´s a limitation and there are further problems doing that. The problem doesn´t exist if you want to implement BLE with external hardware (raspberry, sensors, etc.,) but it doesn´t work between iOS and android. The technology is quite the same in both platforms but it´s not well implemented in Android or is purpose inserted pitfall by google to not open the spectre to communicate between both platforms.
I am doing something similar with an Android central and an iOS peripheral. I found that they would disconnect if nothing subscribed to any of the peripheral's services.
Don't forget to update the descriptor when subscribing else it doesn't actually do anything (i.e. call the delegate method on the iOS side).
It might also be of note that I couldn't even see the iOS device doing an normal BLE scan on the Android device (startLeScan), but starting a BT Classic scan with a broadcast receiver solved the problem (startDiscovery).
I would like to add few information to this thread as a part of our RnD on BLE topic between cross platform.
Peripheral mode is working without any issues with Xiomi Mi A1 (OS version Oreo, Android 8.0).
Here are few observation on throughput that we found during our RnD on iPhone 8 and Xiomi Mi A1 but it still has to get matured with other custom Android OS used in latest Samsung S8. The below data is based on write_with_response.
iPhone 8 (BLE 5.0) as Central and Linux desktop (Ubuntu 16.04 with BLE dongle 4.0): MTU = 2048 : Throughput - 2.5 KiloBytes per sec.
iPhone 8 (BLE 5.0) as Central and Android OS with BLE version 4.2 as Peripheral(Xiomi Mi A1): MTU = 180 : Throughput - 2.5 KiloBytes per sec.
iPhone 8 (BLE 5.0) as Central and iPhone 7 plus (BLE 4.2) as Peripheral : MTU = 512 : Throughput - 7.1 KiloBytes per sec.
iPhone 8 (BLE 5.0) as Central and Samsung S8 (BLE 5.0) as Peripheral : Samsung S8 failed to work as peripheral
iPhone 8 (BLE 5.0) as Central and iPhone 8 plus (BLE 5.0) as Peripheral : MTU = 512 : Throughput - 15.5 KiloBytes per sec.
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.
Here are the key methods...
DROID SIDE - Sending to iOS:
DROID SIDE - Receiving from iOS:
iOS SIDE - Sending to Android:
iOS SIDE - Receiving from Android:
Maybe a bit delayed, but perhaps your pain can be relieved slightly ;)
We have been experimenting a lot with cross platform BLE connections (iOS<-> Android) and learned that there are still many incompatibilities and connection issues.
If your use case is feature driven and you only need basic data exchange I would suggest to look at Frameworks and Libraries that can achieve cross platform communication for you, without you needing to build it up from scratch.
For example: http://p2pkit.io or google nearby
Disclaimer: I work for Uepaa, developing p2pkit.io for Android and iOS.