I have written an application that regularly tries to connect to paired devices and, if the connection succeeds, performs an action. I have a registered bluetooth broadcastReceiver that handles ACTION_ACL_CONNECTED and ACTION_ACL_DISCONNECTED. In a service, in the run loop, I get the list of paired devices and attempt a connection to each. When the connection succeeds, I get the ACTION_ACL_CONNECTED notification and when the device disconnects (or goes out of range) I get the ACTION_ACL_DISCONNECTED. All works well.
For headsets, the BluetoothHeadset class raises ACTION_ACL_CONNECTED and ACTION_ACL_DISCONNECTED so I don't need to connect to a device whose primary UUID is 00001108.
I have a bluetooth speaker that has a single UUID of 0000110B. It can go in and out of range all day long and I get the ACTION_ACL_CONNECTED and ACTION_ACL_DISCONNECTED signals each time I connect to it and each time the disconnect happens because it goes out of range.
If I try to connect to another phone, using 00001105, the first connect succeeds and ACTION_ACL_CONNECTED is raised. If I take the phone out of range (or just turn off its bluetooth), I get ACTION_ACL_DISCONNECTED. However, any further connect attempt results in "Service discovery failed" even if the phone is in range and its bluetooth is on. This continues until i toggle the bluetooth adapter on my phone either manually or in code. Then I can do one connect/disconnect and then the Service discovery failure happens again. obviously, toggling the adapter is not a satisfactory solution.
So, my question is, what makes 00001105 different than 00001108 in that I cannot do multiple connect/disconnects with 00001105?
The code is relatively complex, but here it is (please excuse the indentation. Cut and paste didn't work very well):
public class BluetoothListenerService extends Service {
// The BroadcastReceiver that listens for Connected and disconnected blue tooth devices (HSP,HFP and SPP)
public final BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String devices[]=null;
Intent service_intent;
String action = intent.getAction();
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
// Get the BluetoothDevice object from the Intent
String testUUID=null;
try {
Method method = device.getClass().getMethod("getUuids", (Class<?>[]) null);
ParcelUuid[] phoneUuids = (ParcelUuid[]) method.invoke(device, (Object[]) null);
UUID myUUID=phoneUuids[0].getUuid();
testUUID=myUUID.toString().toLowerCase();
Log.i(TAG,"connected to "+device.getName()+ "using "+ testUUID);
} catch (Exception e) {}
return;
} // end ACTION_ACL_CONNECTED
if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
Log.i(TAG, "disconnected from "+device.getName());
return;
} // end ACTION_ACL_DISCONNECTED
} // end OnReceive
}; // end broadcast receiver definition
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
#Override
public void onStart(final Intent intent, final int startId) {
super.onStart(intent, startId);
if (mBluetoothAdapter == null) {
Toast.makeText(this," Bluetooth is not available on this device", Toast.LENGTH_LONG).show();
return;
}
Thread t = new Thread("MyService(" + startId + ")") {
#Override
public void run() {
_onStart(intent, startId);
stopSelf();
}
};
t.start();
return;
}
public void _onStart(Intent intent, int startId) {
String devices[]=null;
Log.i(TAG,"Bluetooth Listener Service started on thread "+ Integer.toString(android.os.Process.myTid()));
// Register the Bluetooth BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
try {
this.unregisterReceiver(mBluetoothReceiver);
} catch(IllegalArgumentException ignorable) {}
registerReceiver(mBluetoothReceiver, filter);
// the loop
bRun=true;
while(bRun) {
Set <BluetoothDevice> mySet=mBluetoothAdapter.getBondedDevices();
Iterator <BluetoothDevice> iterator=mySet.iterator();
while(iterator.hasNext()) {
BluetoothDevice setElement=iterator.next();
String testUUID=null;
try { // Get UUID for device
Method method = setElement.getClass().getMethod("getUuids", (Class<?>[]) null);
ParcelUuid[] phoneUuids = (ParcelUuid[]) method.invoke(setElement, (Object[]) null);
UUID myUUID=phoneUuids[0].getUuid();
testUUID=myUUID.toString().toUpperCase();
Log.i(TAG, "device UUID is "+testUUID);
if (testUUID.compareTo(headsetUUID)!=0 && testUUID.compareTo(a2dpUUID)!=0) {
try { // create a socket
BluetoothSocket tmp=null;
tmp=setElement.createInsecureRfcommSocketToServiceRecord(UUID.fromString(testUUID));
mmSocket=tmp;
Log.i(TAG,"connecting using socket "+mmSocket.toString());
Log.i(TAG,"connecting to "+setElement.getName());
try {
if (mBluetoothAdapter.isDiscovering()==true) mBluetoothAdapter.cancelDiscovery();
mmSocket.connect();
Log.i(TAG,"connection to "+setElement.getName()+" was sucessful");
// the connection will be handled by the receiver in ACL_CONNECTED
} catch (Exception e) { // connection failed
String sTest=e.getMessage();
Log.e(TAG,"connection to "+setElement.getName()+" returned "+sTest);
if (sTest!=null) {
try { // closing the socket
Log.i(TAG,"closing socket due to error: "+sTest);
Log.i(TAG,"closing socket "+mmSocket.toString());
if (!mmSocket.equals(null)) {
mmSocket.close();
mmSocket=null;
tmp=null;
}
else {
Log.e(TAG, "socket is null");
}
} catch (Exception e1) { // socket close failed
Log.e(TAG,"closing socket failed");
break;
}
if (sTest.compareTo("Unable to start Service Discovery")==0) {
mBluetoothAdapter.disable();
SystemClock.sleep(3000);
mBluetoothAdapter.enable();
SystemClock.sleep(1000);
}
}
} // end catch connection failed
} catch (Exception e1) {
Log.e(TAG, "socket create failed.");
}
} // end test if headset or not
} catch (Exception e1) {
Log.e(TAG, "find UUID failed.");
} // end find UUID
} // end while iterator.hasnext()
} // end of run loop
}
}
Related
I have two devices connected through Bluetooth now. After that, I disconnected the Bluetooth connection on the Client device, and the broadcast receiver in this Client device can detect the disconnection, and then switch it back to previous activity. Something like this:
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Message msg = Message.obtain();
String action = intent.getAction();
if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
try {
Log.i("Disconnecting3", "Disconectinggg....");
Intent intent1 = new Intent(Main3Activity.this, MainActivity.class);
startActivity(intent1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
Anyhow, on my other device which is the Server device, this device CAN NOT detect the disconnection despite the Bluetooth socket is closed! The broadcast receiver in the Server device cannot detect the disconnection. FYI, below code will show how I close the Bluetooth socket on the Server device when the Client device is disconnected.
private boolean CONTINUE_READ_WRITE;
CONTINUE_READ_WRITE = true;
public void run() {
try {
while (CONTINUE_READ_WRITE) {
try {
// Read from the InputStream.
numBytes = mmInStream.read(mmBuffer);
// Send the obtained bytes to the UI activity.
Message readMsg = handleSeacrh.obtainMessage(MessageConstants.MESSAGE_READ, numBytes, -1, mmBuffer);
readMsg.sendToTarget();
} catch (IOException e) {
//nothing();
CloseConnection closeConnection = new CloseConnection();
closeConnection.start();
break;
}
}
} catch (Exception e) {
// Log.d(TAG, "Input stream was disconnected", e);
}
}
public void cancel() {
try {
Log.i("TAG", "Trying to close the socket");
CONTINUE_READ_WRITE = false;
mBluetoothSocket.close();
mmBluetoothSocket.close();
Log.i("TAG", "I thinked its still closing");
} catch (IOException e) {
Log.e("TAG", "Could not close the connect socket", e);
}
}
So when there is a disconnection happened on the Client device, the while(CONTINUE_READ_WRITE)..loop will break the loop and start a new Thread. Something like this :
private class CloseConnection extends Thread {
public void run(){
Log.i("Running","Runinnggggg");
try {
mmInStream.close();
mmOutStream.close();
bluetoothDataTransmission.cancel();
Log.i("Interrupted","InteruppteDDDD");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Alright, I found a solution , just need to add this line of code
intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
I managed to create a ListView, search for devices and show them, on click connect to the selected device, but now I want to know how to send from one phone to the other one just an int or a boolean or something like this.
It's a little game, there is a winner and a loser - so I want to compare two variables and check who won, then display it.
My code so far:
Searching
bluetooth.startDiscovery();
textview.setText("Searching, Make sure other device is available");
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
Displaying in a ListView
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mDeviceList.add(device.getName() + "\n" + device.getAddress());
Log.i("BT", device.getName() + "\n" + device.getAddress());
listView.setAdapter(new ArrayAdapter<String>(context,
android.R.layout.simple_list_item_1, mDeviceList));
}
}
};
#Override
protected void onDestroy() {
unregisterReceiver(mReceiver);
super.onDestroy();
}
Pairing the devices
private void pairDevice(BluetoothDevice device) {
try {
Log.d("pairDevice()", "Start Pairing...");
Method m = device.getClass().getMethod("createBond", (Class[]) null);
m.invoke(device, (Object[]) null);
Log.d("pairDevice()", "Pairing finished.");
} catch (Exception e) {
Log.e("pairDevice()", e.getMessage());
}
}
It works pretty well, both devices are paired.
Do I need a client and a server to transfer ints?
Here is some sample code from the android SDK: BluetoothChat
The key is to use a Service on both sides of the connection that both listens for incoming messages and sends outgoing messages. Then all your Activity has to worry about is interacting with the user, and telling the service to send the appropriate messages.
//METHOD FROM ACTIVITY
private void sendMessage(String message) {
// Check that we're actually connected before trying anything
if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
// Check that there's actually something to send
if (message.length() > 0) {
// Get the message bytes and tell the BluetoothChatService to write
byte[] send = message.getBytes();
mChatService.write(send);
// Reset out string buffer to zero and clear the edit text field
mOutStringBuffer.setLength(0);
mOutEditText.setText(mOutStringBuffer);
}
}
//METHOD FROM SERVICE
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (mState != STATE_CONNECTED) return;
r = mConnectedThread;
}
// Perform the write unsynchronized
r.write(out);
}
Hello Everyone I am working on Bluetooth and I want to pair my device with the finded bluetooth and connect with the paired bluetooth.
I want to know how to do this. And I have also read about client server approach in which we use bluetoothserver socket and bluetooth socket and listenUsingRfcommWithServiceRecord and createRfcommSocketToServiceRecord methods in which we pass mac and uuid.
I want to know where we use this approach and how to find the remote device UUId. Thanks in advance.
You don't need to use the mentioned methods, at least for pairing the devices.
Try using Intents to pair. This code might let you get more familiar with Bluetooth.
public void pairDevice(BluetoothDevice device)
{
String ACTION_PAIRING_REQUEST = "android.bluetooth.device.action.PAIRING_REQUEST";
Intent intent = new Intent(ACTION_PAIRING_REQUEST);
String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE";
intent.putExtra(EXTRA_DEVICE, device);
String EXTRA_PAIRING_VARIANT = "android.bluetooth.device.extra.PAIRING_VARIANT";
int PAIRING_VARIANT_PIN = 0;
intent.putExtra(EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PIN);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
intent.putExtra(EXTRA_DEVICE, device);
int PAIRING_VARIANT_PIN = 272;
intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PIN);
sendBroadcast(intent);
Intent intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
startActivityForResult(intent, REQUEST_PAIR_DEVICE);
If you want a better approach on how to connect these paired devices, take a look at Bluetooth on AndroidDevelopers:
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
mBluetoothAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
// Do work to manage the connection (in a separate thread)
manageConnectedSocket(mmSocket);
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
Link resources:
http://pastebin.com/N8dR4Aa1
http://developer.android.com/guide/topics/connectivity/bluetooth.html#ConnectingAsAClient
I am using Bluetooth API of android. I am here creating client-server connection using BluetoothServerSocket & BluetoothSocket but my program stuck at the certain point.
// Create a BroadcastReceiver for ACTION_FOUND
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery find a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// get the BluetoothDevice object from the Intent
BluetoothDevice mBluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.i("MainActivity", "Device Name: " + mBluetoothDevice.getName() + " Address: " + mBluetoothDevice.getAddress());
new AcceptThread().start();
}
}
};
private class AcceptThread extends Thread {
private BluetoothServerSocket mBluetoothServerSocket ;
public AcceptThread() {
try {
mBluetoothServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("BT_SERVER", UUID.fromString("a60f35f0-b93a-11de-8a39-08002009c666"));
} catch (IOException e) {
Log.e("MainActivity", e.getMessage());
}
}
#Override
public void run() {
BluetoothSocket mBluetoothSocket;
// Keep listening until exception occurs or a socket is returned
while(true) {
try {
mBluetoothSocket = mBluetoothServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if(mBluetoothSocket != null) {
// transfer the data here
Toast.makeText(MainActivity.this, "Socket is created", Toast.LENGTH_LONG).show();;
try {
// close the connection to stop to listen any connection now
mBluetoothSocket.close();
} catch(IOException e) { }
}
}
}
}
Here my program stuck
mBluetoothServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("BT_SERVER", UUID.fromString("a60f35f0-b93a-11de-8a39-08002009c666"));
I could not catch why it getting stuck at this point, Any idea to you for this ?
From your question it is unclear whether your application is a client or server or both. For writing bluetooth client-server applications, android phone at any instance plays a single role of server or a client. If your phone is server, then you need to listen for connections from other bluetooth devices using method listenUsingRfcommWithServiceRecord(). Then use accept() to complete the connection.
In case android phone acts as client, it will initiate a bluetooth connection to other devices. For such scenario, your broadcast receiver is needed. We need to scan for available bluetooth devices with startDiscovery() method. Your broadcast receiver's onReceive() is called when a new bluetooth device is found. To connect to this found device, call createRfcommSocketToServiceRecord() with desired UUID.
Hope this helps.
This may be obvious but did you instantiate your BluetoothAdapter? Accept Thread uses the adapter without intializing it.
myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
While listening, set the discovery name to a specific value then used listenUsingRfcommWithServiceRecord method in broadcast receiver.
private class AcceptTask extends AsyncTask<UUID,Void,BluetoothSocket> {
#Override
protected BluetoothSocket doInBackground(UUID... params) {
String name = mBtAdapter.getName();
try {
//While listening, set the discovery name to a specific value
mBtAdapter.setName(SEARCH_NAME);
BluetoothServerSocket socket = mBtAdapter.listenUsingRfcommWithServiceRecord("BluetoothRecipe", params[0]);
BluetoothSocket connected = socket.accept();
//Reset the BT adapter name
mBtAdapter.setName(name);
return connected;
} catch (IOException e) {
e.printStackTrace();
mBtAdapter.setName(name);
return null;
}
}
#Override
protected void onPostExecute(BluetoothSocket socket) {
if(socket == null) {
return;
}
mBtSocket = socket;
ConnectedTask task = new ConnectedTask();
task.execute(mBtSocket);
}
}
// End
I've been having this problem for a while and haven't been able to figure it out.
I have a android application that puts all paired devices in a listview. When you click one of the list items, it will initiate a request to connect to that bluetooth device.
I can get the list of devices with their addresses no problem.
The problem is that once I try to connect I get an IOException on socket.connect();
The error message is as follows:
"connect read failed, socket might closed or timeout, read ret: -1"
Here is my code. ANY suggestions would be appreciated. I'm pretty stuck on this.
fyi: the "onEvent" methods is a library that simplifies callbacks...that part works.
When the user clicks on a list items this method is called "public void onEvent(EventMessage.DeviceSelected event)"
public class EcoDashActivity extends BaseActivity {
public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private BluetoothAdapter mBluetoothAdapter;
private int REQUEST_ENABLE_BT = 100;
private ArrayList<BluetoothDevice> mDevicesList;
private BluetoothDeviceDialog mDialog;
private ProgressDialog progressBar;
private int progressBarStatus = 0;
private Handler progressBarHandler = new Handler();
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
mDevicesList = new ArrayList<BluetoothDevice>();
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
setupBluetooth();
}
private void setupBluetooth() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
Toast.makeText(this, "Device does not support Bluetooth", Toast.LENGTH_SHORT).show();
}
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
} else {
searchForPairedDevices();
mDialog = new BluetoothDeviceDialog(this, mDevicesList);
mDialog.show(getFragmentManager(), "");
}
}
private void searchForPairedDevices() {
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0) {
// Loop through paired devices
for (BluetoothDevice device : pairedDevices) {
// Add the name and address to an array adapter to show in a ListView
mDevices.add(device.getName() + "\n" + device.getAddress());
mDevicesList.add(device);
}
}
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
mDevicesList.add(device);
}
}
};
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_ENABLE_BT) {
if (resultCode == RESULT_OK) {
Toast.makeText(this, "BT turned on!", Toast.LENGTH_SHORT).show();
searchForPairedDevices();
mDialog = new BluetoothDeviceDialog(this, mDevicesList);
mDialog.show(getFragmentManager(), "");
}
}
super.onActivityResult(requestCode, resultCode, data);
}
public void onEvent(EventMessage.DeviceSelected event) {
mDialog.dismiss();
BluetoothDevice device = event.getDevice();
ConnectThread connectThread = new ConnectThread(device);
connectThread.start();
}
public class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
setName("ConnectThread");
// Cancel discovery because it will slow down the connection
mBluetoothAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
Log.d("kent", "trying to connect to device");
mmSocket.connect();
Log.d("kent", "Connected!");
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
Log.d("kent", "failed to connect");
mmSocket.close();
} catch (IOException closeException) { }
return;
}
Log.d("kent", "Connected!");
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
Here is my logcat. Pretty short.
07-22 10:37:05.129: DEBUG/kent(17512): trying to connect to device
07-22 10:37:05.129: WARN/BluetoothAdapter(17512): getBluetoothService() called with no BluetoothManagerCallback
07-22 10:37:05.129: DEBUG/BluetoothSocket(17512): connect(), SocketState: INIT, mPfd: {ParcelFileDescriptor: FileDescriptor[98]}
07-22 10:37:40.757: DEBUG/dalvikvm(17512): GC_CONCURRENT freed 6157K, 9% free 62793K/68972K, paused 7ms+7ms, total 72ms
07-22 10:38:06.975: DEBUG/kent(17512): failed to connect
07-22 10:38:06.975: DEBUG/kent(17512): read failed, socket might closed or timeout, read ret: -1
That last line is in the "Catch" section of a try/catch...I'm just logging the error message.
Please note, there is about a 20 second gap between "trying to connect to device" and "failed to connect"
The jelly bean bluetooth stack is markedly different from the other versions.
This might help: http://wiresareobsolete.com/wordpress/2010/11/android-bluetooth-rfcomm/
In gist:
The UUID is a value that must point to a published service on your embedded device, it is not just randomly generated. The RFCOMM SPP connection you want to access has a specific UUID that it publishes to identify that service, and when you create a socket it must match the same UUID.
If you are targeting 4.0.3 device and above , use fetchUuidsWithSdp() and getUuids() to find all the published services and their associated UUID values. For backward compatibility read the article
I got the same error message after connecting the socket a second time. I simply checked if the socket is already connected.
if(!mmSocket.isConnected())
mmSocket.connect();
I was testing on Android 4.4.2 (Moto G).