2

I've tried all the suggestions in other comments without avail and I hope someone can help me. I've been struggling with this problem for three days now. I'm quite sure my UUIDs are correct and I know that the bluetooth access is enabled in the manifest.

I'm trying to connect my android application to a python server running in Fedora. It has worked intermittently and not at all right now. The android exceptions I'm receiving generally are along the lines of.. These are thrown when btSocket.connect(); is executed in the code attached below.

12-09 05:08:42.331: ERROR/BluetoothService(676): java.io.IOException: Service discovery failed 

or

12-09 05:27:00.757: ERROR/BluetoothService(729): java.io.IOException: Service discovery failed 

This is my android bluetooth class that is supposed to take care of everything. The thread is started when the main application class receives a message that the socket has been connected to. My bluetooth class is based on http://www.anddev.org/viewtopic.php?p=35487#35487.

package spin.halo; import java.io.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.UUID; import android.bluetooth.*; import android.os.Handler; import android.util.Log; public class BluetoothService extends Thread{ private static final String TAG = "BluetoothService"; private static final boolean D = true; private BluetoothAdapter mBluetoothAdapter = null; private BluetoothSocket btSocket = null; private OutputStream outStream = null; private InputStream inStream = null; private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); private static String address; private Handler appHandler; public BluetoothService(Handler h) { if (D) Log.e(TAG, "+++ ON CREATE +++"); appHandler = h; mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (mBluetoothAdapter == null) { Log.e(TAG, "NO BT ADAPTER!"); return; } if (!mBluetoothAdapter.isEnabled()) { Log.e(TAG, "Bluetooth is not enabled!"); return; } if (D) Log.e(TAG, "+++ DONE IN ON CREATE, GOT LOCAL BT ADAPTER +++"); } public void connectToServer() { connectToServer("60:33:4B:25:0D:37"); } public void connectToServer(String serverMacAddress) { address = serverMacAddress; // if (D) { Log.e(TAG, "+ ABOUT TO ATTEMPT CLIENT CONNECT +"); } BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); Log.v(TAG, "REMOTE DEVICE: " + device.toString()); try { btSocket = device.createRfcommSocketToServiceRecord(MY_UUID); Log.v(TAG, "SOCKET: " + btSocket.toString()); } catch (Exception e) { Log.e(TAG, "ON RESUME: Socket creation failed.", e); } /* Discovery may be going on, e.g., if you're running a 'scan for devices' search from your handset's Bluetooth settings, so we call cancelDiscovery(). It doesn't hurt to call it, but it might hurt not to... discovery is a heavyweight process; you don't want it in progress when a connection attempt is made.*/ mBluetoothAdapter.cancelDiscovery(); // Blocking connect, for a simple client nothing else can // happen until a successful connection is made, so we // don't care if it blocks. try { btSocket.connect(); Log.e(TAG, "ON RESUME: BT connection established, data transfer link open."); appHandler.sendMessage(appHandler.obtainMessage(ValidationApp.BT_CONNECTION_MADE, "")); } catch (IOException e) { try { Log.e(TAG, "ON RESUME: Could not connect", e); btSocket.close(); } catch (IOException e2) { Log.e(TAG, "ON RESUME: Unable to close socket during connection failure", e2); } } // Create output stream try { outStream = btSocket.getOutputStream(); } catch (IOException e) { Log.e(TAG, "ON RESUME: Output stream creation failed.", e); } // Create input stream try { inStream = btSocket.getInputStream(); } catch (IOException e) { Log.e(TAG, "Input stream creation failed.", e); } } public void write(String message) { if(message.length() > 0) { byte[] msgBuffer = message.getBytes(); try { outStream.write(msgBuffer); } catch (IOException e) { Log.e(TAG, "ON RESUME: Exception during write.", e); } } } public void run() { LineNumberReader mLineReader = new LineNumberReader(new InputStreamReader(inStream)); while(true) { try { String message = mLineReader.readLine(); if(D) {Log.v(TAG, "Bluetooth says: " + message);} Log.v(TAG, appHandler.obtainMessage(ValidationApp.BT_MESSAGE, message).toString()); appHandler.sendMessage(appHandler.obtainMessage(ValidationApp.BT_MESSAGE, message)); } catch (IOException e) { Log.e(TAG, "startListen: ", e); } } } } 

The key portions of my python code are below. I am quite confident about this code.

# pybluez library import bluetooth server_socket = bluetooth.BluetoothSocket( bluetooth.RFCOMM ) client_sockets = [] server_socket.bind(("",bluetooth.PORT_ANY)) port = server_socket.getsockname()[1] uuid = "00001101-0000-1000-8000-00805F9B34FB" print "Listening for devices..." # advertise service server_socket.listen(1) bluetooth.advertise_service( server_socket, "Validation Host", service_id = uuid, service_classes = [ uuid, bluetooth.SERIAL_PORT_CLASS ], profiles = [ bluetooth.SERIAL_PORT_PROFILE ], ) # accept incoming connections client_sock, client_info = server_socket.accept() client_sockets.append(client_sock) print "Accepted Connection from ", client_info 

Thanks for taking a look.

1 Answer 1

3

Your code looks generally good, I assume you just copy and paste it from some examples.

There is a bug in some Android phones such as HTC desire, which cause method device.createRfcommSocketToServiceRecord to fail. I would suggest following approach:

1) Trying to chat between two linux computer using pythong scripts provided at http://www.radekdostal.com (you know where) by that you verify that your Linux setup is working properly.

2) Trying to initiate connection from computer to Android (use android-bluetooth-chat-client-python) Be aware that default BluetoothChat demo is able to accept connection only on the first try.

3) Try connecting from Android phone to linux computer, but manually specify RFCOMM channel number using following code

// BUGBUG: Following code is not properly implemented on HTC DESIRE // mSocket = device.createRfcommSocketToServiceRecord(UUID.fromString("6a462dc0-703a-4bf3-a80e-a473a6332c64")); // WORKAROUND: Connecting directly to RFCOMM channel 1 Method m = device.getClass().getMethod("createRfcommSocket", new Class[] { int.class }); mSocket = (BluetoothSocket) m.invoke(device, Integer.valueOf(1)); // 1==RFCOMM channel code 

You will need to find out what is your RFCOMM channel number using

# sdptool browse local 
Sign up to request clarification or add additional context in comments.

1 Comment

if this is not working, try "createInsecureRfcommSocket" instead of "createRfcommSocket".

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.