Android BluetoothSocket 无法连接

Android BluetoothSocket can't connect

我正在 android 上用蓝牙做一些事情,我想连接到其中一个已发现的设备并为它打开套接字连接。

我已经授予了所有需要的权限:蓝牙、Bluetooth_Admin、Access_Fine_Location 和 Access_Coarse_Location,并在我对蓝牙进行任何操作之前请求它们。

现在,我发现了一些带有 adapter.startDiscovery();activity.registerReceiver(receiver, filter);

的设备

在接收器中找到一个特定名称的设备,我尝试像这样连接它:

            adapter.cancelDiscovery();
            Log.d(TAG, "Create Bond");
            device.createBond();
            try {
                socket = device.createRfcommSocketToServiceRecord(uuid);
                Log.d(TAG, "Sleep 10");
                sleep(10000);
                Log.d(TAG, "Create Socket");
                //socket = device.createInsecureRfcommSocketToServiceRecord(uuid);
                Log.d(TAG, "Connect socket");
                socket.connect();
                Log.d(TAG, "Connecting Done");
            } catch (Exception e) {
                Log.d(TAG, "Failed to connect to device", e);
                try {
                    socket.close();
                } catch (Exception e2) {
                    Log.d(TAG, "Failed to close socket", e2);
                }
            }

这是一个测试代码,我试图用它来创建一个套接字并打开一个连接。

我在 .connect() 上得到以下异常:

java.io.IOException: read failed, socket might closed or timeout, read ret: -1 at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:684) at android.bluetooth.BluetoothSocket.readInt(BluetoothSocket.java:696) at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:373)

我哪里做错了。

我连接的蓝牙设备是Android移动设备,但我打算在成功连接后使用其他设备。

更新1: Android 版本为 7.0

使用 fetchUuidsWithSdp()getUuids() 查找所有已发布的服务及其关联的 UUID 值。

您无需调用 device.createBond(); 即可连接到蓝牙设备。

尝试删除此行。另请检查您的 phone 是否尚未与您尝试连接的设备配对。 您可以在蓝牙设置屏幕上查看(长按智能设备上的蓝牙图标打开它phone。

这是启动蓝牙连接的示例代码:

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;

        try {
            // Get a BluetoothSocket to connect with the given BluetoothDevice.
            // MY_UUID is the app's UUID string, also used in the server code.
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) {
            Log.e(TAG, "Socket's create() method failed", e);
        }
        mmSocket = tmp;
    }

    public void run() {
        // Cancel discovery because it otherwise slows down the connection.
        bluetoothAdapter.cancelDiscovery();

        try {
            // Connect to the remote device through the socket. This call blocks
            // until it succeeds or throws an exception.
            mmSocket.connect();
        } catch (IOException connectException) {
            // Unable to connect; close the socket and return.
            try {
                mmSocket.close();
            } catch (IOException closeException) {
                Log.e(TAG, "Could not close the client socket", closeException);
            }
            return;
        }

        // The connection attempt succeeded. Perform work associated with
        // the connection in a separate thread.
        manageMyConnectedSocket(mmSocket);
    }

    // Closes the client socket and causes the thread to finish.
    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) {
            Log.e(TAG, "Could not close the client socket", e);
        }
    }
}

此代码来自Android官方文档: https://developer.android.com/guide/topics/connectivity/bluetooth#ConnectAsAClient

我写了另一个代码而不是我在服务器端使用的代码。

            Log.d(TAG,"Start server");
            BluetoothServerSocket serverSocket = null;
            try {
                serverSocket = adapter.listenUsingRfcommWithServiceRecord("ime", uuid);
            } catch (Exception e) {
                e.printStackTrace();
            }

            while (true) {
                try {
                    serverSocket.accept();
                } catch (Exception e) {
                    e.printStackTrace();

                }
            }

我在一个开始的线程中使用了这段代码,而不是从问题中调用代码。

在一个应用程序上安装带有服务器代码的应用程序并在套接字上调用 "connect" 就成功了。 我使用了相同的 UUID(之前的是随机生成的,新的是来自字符串的静态)。