android.bluetooth.BluetoothSocket не может подключиться - PullRequest
2 голосов
/ 09 декабря 2010

Я попробовал все предложения в других комментариях безрезультатно, и я надеюсь, что кто-то может мне помочь. Я боролся с этой проблемой уже три дня. Я совершенно уверен, что мои UUID верны, и я знаю, что в манифесте включен доступ по Bluetooth.

Я пытаюсь подключить мое приложение для Android к серверу Python, работающему в Fedora. Это работало с перерывами и совсем не сейчас. Исключения для Android, которые я получаю, как правило, выглядят следующим образом: выполняется в коде, прикрепленном ниже.

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

или

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

Это мой класс Android andtooth, который должен обо всем позаботиться. Поток запускается, когда основной класс приложения получает сообщение, что сокет был подключен. Мой класс Bluetooth основан на 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);
            }
        }
    }
}

Ключевые части моего кода на Python приведены ниже. Я совершенно уверен в этом коде.

# 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

Спасибо, что заглянули.

1 Ответ

3 голосов
/ 14 января 2011

Ваш код в целом выглядит хорошо, я предполагаю, что вы просто скопировали и вставили его из некоторых примеров.

В некоторых телефонах Android, таких как HTC desire, есть ошибка, которая приводит к сбою метода device.createRfcommSocketToServiceRecord.Я бы предложил следующий подход:

1) Попытка общаться между двумя компьютерами Linux с помощью сценариев pythong, предоставленных в http://www.radekdostal.com (вы знаете, где), проверяя, что ваша установка Linux работает правильно.

2) Попытка установить соединение с компьютера на Android (используйте android-bluetooth-chat-client-python) Имейте в виду, что демонстрационная версия BluetoothChat по умолчанию может принимать соединение только с первой попытки.

3) Попробуйте подключиться с телефона Android к компьютеру linux, но вручную укажите номер канала RFCOMM, используя следующий код

// 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 

Вам нужно будет узнать, какой номер канала RFCOMM используется с помощью

# sdptool browse local
...