开发者

android.bluetooth.BluetoothSocket cannot connect

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.


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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜