I have a EVO (running Android 2.2) and a Sumsung Intercept (running 2.1). I'm trying create a simple chatting application (similar to the BluetoothChat example) but I cannot get the two handsets to connect. I am able to get them through the discovery process such that each handset is able to discover the other, but when I try to connect I always get a "Service discovery failed" error.
What makes this even more interesting is I'm never able to initiate the connection from the 2.2 -> 2.1 (EVO to the Intercept handsets). But, if the EVO attempts to connect first (which will always get the above referenced error), then I attempt to connect from the Intercept, I will at least get the PIN code / Accept Pairing dialogs on both handsets. But, if I attempt to send anything (the write() method) I will get an error stating the 2 handsets are not connected.
Any help would be greatly appreciated.
One of the handsets has to be a listener (waiting with a bluetooth socket) and the other has to make a connection to the one with the socket.
In other words, you appear to be trying to initiate a connection from both devices while neither one is in a state where it can receive an incoming connection (which is the function of a bluetooth socket).
Related
I am currently developing an application that will use Bluetooth Low Energy (testing on the Nexus 4). After getting started with the official BLE APIs in Android 4.3, I have noticed that after I connect a device for the first time I am rarely able to successfully connect to / communicate with that device or any other device again.
Following the guide here, I can successfully connect to a device, scan services and characteristics, and read/write/receive notifications without any issues. However, after disconnecting and re-connecting, I am often unable to either scan services/characteristics or unable to complete a read/write. I can't find anything in the logs to indicate why this is happening.
Once this happens I have to uninstall the application, disable Bluetooth, and restart the phone before it will start working again.
Whenever a device is disconnected I make sure to call close() on the BluetoothGatt object and set it to null. Any insights?
EDIT:
Log dumps: For these logs I rooted my phone and upped the trace levels of related items in /etc/bluetooth/bt_stack.conf
Successful connection - First attempt after rebooting the phone and installing the app. I am able to connect, discover all services/characteristics, and read/write.
Failed Attempt 1 - This is the next attempt after disconnecting from the successful connection above. It seems I was able to discover characteristics, but the first attempt to read returned a null value and disconnected soon thereafter.
Failed Attempt 2 - An example where I am not even able to discover services/characteristics.
EDIT 2:
The device to which I am trying to connect is based on TI's CC2541 chip. I obtained a TI SensorTag (also based on the CC2541) to play around with and discovered that TI released an android app for the SensorTag yesterday. However, this app has the same problem. I tested this on two other Nexus 4s with the same result: Connection to the SensorTag is successful the first or second time, but (according to the logs) fails to discover services thereafter, causing all sorts of crashes. I'm starting to wonder if it's an issue with this specific chip?
Important implementation hints
(Perhaps some of those hints aren't necessary anymore due to Android OS updates.)
Some devices like Nexus 4 with Android 4.3 take 45+ seconds to connect using an existing gatt instance. Work around: Always close gatt instances on disconnect and create a fresh instance of gatt on each connect.
Don't forget to call android.bluetooth.BluetoothGatt#close()
Start a new thread inside onLeScan(..) and then connect. Reason: BluetoothDevice#connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback) always fails, if called inside LeScanCallback() {...}.onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) in the same thread on Samsung Galaxy S3 with Android 4.3 (at least for build JSS15J.I9300XXUGMK6)
Most devices filter advertising
Better not use android.bluetooth.BluetoothAdapter#startLeScan(UUID[] serviceUuids, LeScanCallback callback) with the parameter to filter for certain service UUIDs because this is broken completely in Samsung Galaxy S3 with Android 4.3 and doesn't work for 128bit UUIDs in general.
Gatt always can process one command at a time. If several commands get called short after another, the first one gets cancelled due to the synchronous nature of the gatt implementation.
I often see even on modern devices with Android 5, that Wifi interferes withs bluetooth and vice versa. As a last resort, turn off wifi to stabilize bluetooth.
Tutorial for beginners
A pretty OK entry point for newcomers could be this video tutorial: Developing Bluetooth Smart Applications for Android http://youtu.be/x1y4tEHDwk0
The issue and work around described below is probably fixed now by OS updates
Work around: I could "stabilize" my app doing that...
I provide the user a setting "Restart Bluetooth". If that setting is enabled, I restart Bluetooth at some points that indicate the begin of BLE stack becoming unstable. E.g. if startScan returns false. A good point may also be if serviceDiscovery failes. I just turn Bluetooth off and on.
I provide another setting "Turn off WiFi". If that setting is enabled, my app turns off Wifi when the app is running (and turns it back on afterwards)
This work around is based on follwoing experiences...
Restarting Bluetooth helps to fix problems with BLE in most cases
If you turn off Wifi, the BLE stack gets much more stable. However, it also works fine on most devices with wifi turned on.
If you turn off Wifi, restarting Bluetooth fully recovers the BLE stack without the need to reboot the device in most cases.
Turning WIFI OFF:
I can confirm too, that turning WIFI OFF makes Bluetooth 4.0 more stable especially on Google Nexus (I have a Nexus 7).
The problem
is that the application I am developing needs both WIFI and continous Bluetooth LE scanning. So turning WIFI OFF was no option for me.
Moreover I have realised is that continous Bluetooth LE scanning can actually kill WIFI connection and make the WIFI adapter unable to re-connect to any WIFI network until BLE scan is ON. (I'm not sure about mobile networks and mobile internet).
This definitely happened on the following devices:
Nexus 7
Motorola Moto G
However BLE scanning with WIFI on seemed pretty stable on:
Samsung S4
HTC One
My workaround
I scan BLE for a short period of time 3-4 seconds then I turn scan OFF for 3-4 seconds. Then ON again.
Obviously I always turn BLE scan OFF when I'm connecting to a BLE device.
When I disconnect from a device I restart BLE (turn adapter OFF and then ON) to reset the stack before starting scan again.
I also reset BLE when discovering services or characteristics fails.
When I get advertisement data from a device that the app should connect to (lets say 500 times without being able to connect - thats about 5-10 seconds of advertising) I reset BLE again.
Make sure your Nexus is paired to the device. I can't verify whether or not the communication works properly, but you will be able to connect more than once without a reboot. It seems the first connect is not requiring pairing but all subsequent attempts do.
I will update this answer in a couple of days when I test service discovery and gatt read and write requests without a reboot.
EDIT:
It turns out I was testing on a development firmware version (our sensor) that was causing issues if not paired. Our latest production firmware build works fine on the 2540s and 2541s.
EDIT:
I did notice that on the Nexus 7 2013, connections are more stable when WiFi is turned off. I'd like to know if this helps anyone else.
EDIT:
I seem to have had it backwards with pairing. Everything works fine when not paired. After pairing, I am experiencing the exact same symptoms as the OP. It's just not known yet if this is related to our firmware or the Android BLE API. Be careful if testing this because once paired, you may not be able to unpair due to a bug explained in 3b of this post.
In some models there is a defect:
https://code.google.com/p/android/issues/detail?id=180440
On the other hand in my case the problem was, that my connection was not properly closed in onDestroy method. After correct closing, problem for me is not existing, not matter that wifi is turned on or off.
btGatt.disconnect();
btGatt.close();
I was facing a similar issue. My fix was
if (Build.VERSION.SDK_INT >= 23) {
mBluetoothGatt = device.connectGatt(this, false, mGattCallback, BluetoothDevice.TRANSPORT_LE);
} else {
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
}
& calling close after disconnect.
I'm attempting to adapt the BluetoothChat example that comes with the SDK to a single-server, multiple-client configuration. I'm having issues and hope someone can help.
I've created two distinct apps, a server and a client, rather than have a single app function as both server and client, as in the example. So the upon starting the app, the server creates a bluetooth service, which creates a new AcceptThread, which listens for incoming connections. I made a couple of modifications to the example code so that the AcceptThread continues to listen, even after the first connection is made (the example stops listening after the one connection is made, because it only needs to establish connections between two devices). I created an ArrayList to handle the multiple connections. Each time a new connection is attempted from a remote device, a new ConnectedThread is created and added to the list.
The first client connects just fine.
When the second client attempts to connect, the connection fails. The log output is:
D/BluetoothEventLoop( 140): Device property changed: <device address> property: Connected value: true
I/BluetoothService( 140): ACL connected, mAclLinkCount = 2
D/BluetoothEventLoop( 140): Device property changed: <device address> property: Connected value: false
I/BluetoothService( 140): ACL disconnected, mAclLinkCount = 1
So it looks like the second connection attempt is successful, but then it is immediately disconnected. This looks like it's happening at a low level, outside anything the code is handling. This happens with a number of different types of test devices, so I don't think it's due to a particular firmware or hardware issue.
Can anyone help with this?
Also, can anyone point to an example of a server->multiple client connection example using bluetooth with Android? I came across an Air Hockey example:
http://code.google.com/p/apps-for-android/source/browse/#svn%2Ftrunk%2FBTClickLinkCompete%2Fsrc%2Fnet%2Fclc%2Fbt
But this project is very glitchy on my test devices and the actual game won't display properly. Does anyone know if there is an example of BluetoothChat extended to handle multiple connections?
UPDATE:
In attempting to solve this issue, I believe I have successfully extended the official Android Bluetooth Chat example to work with a server connecting to multiple clients.
I've uploaded my modifications to github here.
One device acts as the server by selecting "Menu>Make discoverable". Each client then connects by selecting "Menu>Connect a device". I was successfully able to connect my Motorola Droid and HTC Eris as clients to my Samsung Galaxy Tab 10.1". Each message sent from a client displays only on the server. A message sent from the server displays on all clients.
This was a tedious process getting it to work at all. Connectivity with the HTC devices is sporadic, though. I've read elsewhere that bluetooth on HTC is buggy, so I'm chalking it up to that.
Hopefully someone else will find this example useful. If you have any questions, suggestions, or other feedback, please let me know.
I tested your code. As, you said connecting HTC as master was a problem. I made Samsung S3 as master and HTC as client. it worked. But i tried again with a Sony Ericsson phone. No other device could successfully act as master.
S3 has Blutooth version 4.0 other have earlier version. Do you think the problem is because of Bluetooth stack?
I need to use this concept in a project where the devices will be custom made. Trying to find out weather the problem is related to vendors ( HTC, Sony) or its related to bluetooth stack. and i don't know how to find out. This is not documented. :(
Has anyone faced this?
I am trying to implement file transfer through bluetooth and i am using the Bluetooth -chat example that comes with the android sdk.
When i try connecting two android phones, they seem to always say, the phones are paired but not connected. This is tedious as i have tried to connect with 3 different pairs of phones and all of them say the same thing.
Is it required for the devices to be rooted or something?? How can i connect two android phones through bluetooth.
(This isn't strictly an answer, but I am yet unable to post comments.)
I've personally had good success with the Bluetooth Chat example code, and I've used it to create an application that interfaces with a Bluetooth/RS232 dongle to obtain lots of measurement data from a remote hardware device. I do confess, however, that I've only ever used the host Bluetooth code to initiate a connection to the Bluetooth SPP dongle; I've not attempted to connect to the slave code on another phone.
For reference, the two devices I've used my app on with success are my HTC Desire (2.2) and my Archos 101 (2.2). They are not rooted.
One thing that I think is worth me mentioning is that the Bluetooth Chat example appears to have a bug in the code where it accepts an array of received bytes out of the socket and presents them into the ListActivity. If lots of characters are sent from the remote device at anything much faster than typing speed, what is shown in the ListActivity on the phone shows the occasional character being corrupted. It's because (I think) the ArrayAdapter is still consuming bytes from that array to print them on the screen when the connected thread starts to fill that same array with even newer bytes. So, I had to fix that before I could use the Bluetooth Chat example code to reliably receive relatively large volumes of data from the external device.
On either the HTC Desire or Archos 101 I don't seem to have any problems with connection. I can happily have the Bluetooth connection exist reliably even over poor signal conditions (e.g. the remote device is upstairs in the house while I'm downstairs with the Android device) while my app happily polls measurement data reliably at a rate of about 250bytes a second.
Generate UUID of your phone by using adb shell, sdptool browse command
I’m trying to develop an Android application for a medical device using Bluetooth (SPP). I’ve used the BluetoothChat as a starting point (also see earlier post). Now I think I’m facing a weird problem and I’m also having trouble describing it. Testing on a Nexus S.
Upon the completion of measurement the medical device checks its memory for the Bluetooth address and other information about the previously paired device. If found it will try to initiate a connection (while the application on the phone is listening for a connection) and then transfer data and otherwise it starts an inquiry procedure.
The first time it works fine: pairing procedure, establishing connection and transferring data. When the data is received the application replies with an ACK package and the connection is terminated.
The rest of the times it does not work: after a measurement I can see in the LogCat that the phone receives a signal (just like the first time) from the device, so I know the device saved the phones Bluetooth address. It seems like the system ignores the signal (or at least nothing happens), no connection is established and thus no data transferred even though I'm using accept-method of BluetoothServerSocket the same way as when it works. If I remove the pairing record from the phone this signal starts the pairing procedure and the devices get paired again, BUT they still won’t establish a connection nor transfer data. I guess the message about the signal represents a try to establish a connection but something is wrong. The message in the log is the same as when the connection is successful and can be seen in the LogCat:
03-22 14:21:55.335: ERROR/BluetoothEventLoop.cpp(114): event_filter: Received signal org.bluez.Device:PropertyChanged from /org/bluez/4123/hci0/dev_00_A0_96_2D_05_E8
It's rather confusing it's an ERROR message and present in the log when it works as well.
The weird thing is that it works the first time they are successfully paired, but never again afterwards. When the data is transferred and the device receives an ACK it saves the Bluetooth address "and other useful information". The only way I can reproduce the successful ‘first time’ is by pairing the medical device with another device and then afterwards pair it with the application on the phone again.
I’m confused about what is actually causing this problem. Does anyone out there have any clue?
I’m afraid my problem is a bit to specific to be familiar to others if case the problem is caused by the medical device and not the phone. I was thinking it might be related to the Link Key or Channel? But on the other hand, as I said, if I remove the pairing from the phone, I'll get a pairing request again.
The medical device is old, using Bluetooth 1.2. Now it strikes me that I should have a look at if there are any connection-related issues because of this. Could it be that a device using Bluetooth 1.2 have another policy of what information to store when it is paired?
For the moment I feel I'm struggling with a problem I don't fully understand, but if I'll understand later I'll of course get back with my conclusions. I hope I didn't forget important details.
Thanks in advance /F
Hi fredricus My problem is similar to yours i m running a bluetooth service which keeps on listening for data when the bluetooth is on.u have solved the problem of connecting android device to a medical device as u mentioned that u have used reflection.But in case if medical initiates connection will it be able to connect to android device.
Sounds like the problem is with the medical device, that it is not able to re-establish connection (i.e. re-authenticate) with already paired device.
I dont think that being being 1.2 should matter. The procedures are designed to be backward compatible so that all bluetooth versions work with each other.
You may have to get a bluetooth sniffer trace to check what might be going on over the air that will validate if the issue is on the medical device side.
Another option is to check if android has any way to turn on more detailed logging of the Bluetooth interactions and enable that. Default log of Android messages are very high level and does not provide much detail
I have a Bluetooth service that I programmed for .Net on a Windows machine and I would like my Android 2.1 phone to connect to it. The server is listening for the same UUID which the Android is using to connect. But the connection is failing.
When I try to connect to devices that are not listening for that UUID, I get an exception with the message "Service discovery failed", but when I try to connect to the server that is listening for the right UUID a message box pops up saying:
"There was a problem pairing with bluetooth device."
And I get an exception with the message "Connection timed out." So it looks like the server and the Android are communicating, but there is some sort of failure during handshaking. I know that the Android requires that the server is paired with the phone and also encrypts the communication channel. Does anyone know which specifications are used to do this? I would love to get my server to respond properly to the connection attempt.
Thanks!
I figured out what was going wrong. The problem is that you have to pair the remote device with the Android before you try to make the connection because the pairing dialog does not always work. I am not sure if the bug is on the Android side or on the other device's side, but I was never shown the dialog that asks for the authentication code or that displays the authentication code on either device. So it looks like there are some compatibility issues out there. But if you explictly pair the devices beforehand, then the connection works.
You're right. I'm having the same issue here while trying to connect to an RS232 device with BluetoothChat sample program.
1- If not bonded, I get two errors in a row :
03-03 13:38:20.020: ERROR/BluetoothService.cpp(2077): stopDiscoveryNative: D-Bus error in StopDiscovery: org.bluez.Error.Failed (Invalid discovery session) // Probably because we're calling cancelDiscovery() as a "security" (it's already been cancelled at some point beforehand)
03-03 13:38:20.040: ERROR/BluetoothEventLoop.cpp(2077): onCreateDeviceResult: D-Bus error: org.bluez.Error.AlreadyExists (Device already exists) // This I don't understand
2- Once bonded through Bluetooth Settings, no problem. The connection is made perfectly and the program works.
I tried to check out the Android Source by myself but, given that I'm a newbie, it's kind of tough. If some experienced guy could work it out, it'd be great.
To answer Tomas - The SPP (Serial Port Profile) profile is broken on several HTC Android models, even 2.1 versions, but it is not consistent among the models.
HTC Desire - Does not work.
HTC Legend - Bad, but works for a while?
HTC Hero with custom ROMs - Some work well, some not at all and some badly when doing sound at the same time.
All the previous answers are on the mark; essentially, pairing is required before connect.
However, I was getting the error even after pairing. (I had first tried to connect without pairing).
The workaround was to reboot the phone once. And now it is able to connect to the paired device fine. Sounds simple, but I spent quite some time debugging it. Hopefully useful to someone out there.