All though there are still plenty of work to be done, I did manage to put together first release, and with it you could have the discovery and data-channel establishment fully automated, and then have your application to implement the logic for data exchange.
Source codes for the project can be found from thaliproject/BTConApp. I’ll be updating it time to time, and likely will make other libraries as well.
This library is using mixing technologies, the reasoning was to find technologies that would enable us to get the discovery & data exchange to work without pairing, human interaction as well as with minimal interruptions to other communications happening from the device. Also we required the library to be able to work on both Lollipop & Kitkat versions of Android.
The technologies used are:
- Wifi-Direct for Peer & service discovery. The Bluetooth address is also delivered through the local service advertising
- Unsecure-Bluetooth sockets for data exchange.
The delivery also includes a sample application which is also doubling as a end-to-end test application. Basically you would open the app in two separate devices, and let it run.
While running the app, it does the following:
- It tries to find other instances of it running in other devices,
- If it finds one, it tries to make connection to it.
- If the connection is successful, then it sends short message to the device.
- After the short message is received, the device which was connected to (i.e. not the one that started the communication process) sends 1 Mb data chunk to the other device.
- After receiving the 1 Mb data chunk, the connection is closed, and the discovery process is started again.
With the app, there is 1 minute timer, which after it will display summary of the steps executed, and later on automated test report sending could be added in this view.
If you want to add the library in your own app, at its current stage, you would need to add it as a module to your project. Then create instance of the BTConnector class. For it you need to give the main apps Context, and a callback.
The Callback is really simply, it requires two functions to be implemented:
- Connected(BluetoothSocket socket, boolean incoming) function will be called by the library when connection is established to remote device
- void StateChanged(State newState) function is called by the library when internal state of the library changes. possible values are:
- Idle: The Library is ready, but not actively doing anything. (dark Gray)
- NotInitialized: Library has not been initialized (light Gray)
- WaitingStateChange: Bluetooth or Wifi is disabled, thus the library is waiting for them to be enabled before doing anything. (pink)
- FindingPeers: Library is currently discovering peers. (Cyan)
- FindingServices: Library has detected peer devices, and is now checking whether they are advertising the service we use. (Yellow)
- Connecting: Library has discovered a device having our service, and is attempting to establish connection to it. (Green)
- Connected: Library has established connection. (Blue)
The (Color) marked in the end of the state values is the color used in the example application to make the apps current state more visible while playing around with the app. Following video shows simple demo on how the app can be used:
During testing we also have found out that, the Bluetooth connections can be rather unreliable when it comes to the data speed, and as the library simply gives the socket to the application handling the communications, the data channel monitoring must be handled in the application level separately.
As an example here’s video of old version of the test app
This app version only had a timeout timer for 60 seconds, and its reset only if the data channel is completely idle for full 60 seconds. This approach is bad, since there might be data coming, but its coming really slow. With this video the normal time it takes to send/receive the 1 Mb data chunk, is bout 5-10 seconds, there are loads of times it takes more, but generally more than 90 % is handled in less than 30 seconds. The longest time to receive the 1 Mb that ended successfully can be found from 11:50, and it lasted 496 seconds.
The recommendation for approaching this issue, would be to measure bigger chunks and have timer to verify that the amount of data received is above the threshold limit. And if it is not, then disconnect the socket and start the discovery process again.
I will be writing some suggestions for the values later, after I have done some measurements on the timings in general.