反应原生蓝牙连接失败:java.io.IOException 读取失败,套接字可能关闭或超时,读取 ret:-1

问题描述

我在我的应用程序 (https://github.com/kenjdavidson/react-native-bluetooth-classic-apps/tree/main/BluetoothClassicExample) 中使用了这个库来连接蓝牙设备。

我在连接到设备时遇到了这个问题 - Connection Failed: java.io.IOException read Failed,socket might closed or timeout,read ret: -1

这是我用于 connect() 函数代码。 (从 https://kenjdavidson.com/react-native-bluetooth-classic/react-native/rn-bluetooth-device/ 引用此代码

async connect() {
    try {
      let connection = await this.props.device.isConnected();
      console.log("connection is......",connection);
      if (!connection) {

        console.log(this.state.connectionoptions);
        connection = await this.props.device.connect({
           CONNECTOR_TYPE: "rfcomm",DELIMITER: "\n",DEVICE_CHARSET: Platform.OS === "ios" ? 1536 : "utf-8",});

      } else {
        console.log("Connected to ",this.props.device.name)
      }

      this.setState({ connection });
      this.initializeRead();
    } catch (error) {
      console.log(error.message)
    }
  }

有人可以给我建议解决方

解决方法

正如在 Github 问题上讨论的那样,为了连接到另一台设备,您需要确保该设备是:

  • 配对
  • 打开了一个 BluetoothServerSocket

使用此库时,您需要:

设备 1

将库/设备设置为接受模式:

let device = await RNBluetoothClassic.accept();

设备 2

连接到设备 1,您的操作是正确的:

    connection = await this.props.device.connect({
           CONNECTOR_TYPE: "rfcomm",DELIMITER: "\n",DEVICE_CHARSET: Platform.OS === "ios" ? 1536 : "utf-8",});

但正如我们所讨论的,该库并不真正支持利用蓝牙配置文件的耳机和其他外围设备。

修改 2021 年 6 月 11 日

正如我们还讨论过的,库本身只提供非常基本的通信选项 (RFCOMM),由以下提供:

  • RfcommDeviceAcceptorImpl
  • RfcommDeviceConnectorImpl
  • DelimitedStringDeviceConnectionImpl

但该库已更改为允许用户覆盖/添加任意数量的他们自己开发的 AcceptorConnectorDeviceConnection 实现。

这里的限制因素是 React Native 不允许您来回发送字节数组,发送数据的最佳方法是使用字符串,在这种情况下,字符串是 Base64 编码的(大部分)。

因此,在非常高的层次上,您需要编写自己的版本:

  • LcappDeviceAcceptorImpl
  • LcappDeviceConnectorImpl

并获取在包/模块中配置的那些。然后,您必须编写自己的 ObexDeviceConnectionImpl 并在模块中进行配置。不过,查看 Obex 的规范,您肯定还会遇到将字符串作为字符串传输到 React Native 端的问题。

看起来 Obex(我的经验为零)只是一种用于传输数据的消息格式。这意味着这可以使用任何类型的通信通道来实现,只是碰巧说 Lcapp 是主要的,但是查看 WIKI 确实说 RFCOMM 可以用于“遗留应用程序”。

这看起来是一个有趣的项目,而且可能有很多定制工作。但是对于如此专业的东西(如果它是私有的),您可能需要考虑编写自己的内部模块或仅使用本机 java。