7

我正在与蓝牙设备建立蓝牙套接字连接,并想从设备中读取字节。

我已正确建立连接:

 try {
         Method m = mmDevice.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
          temp = (BluetoothSocket) m.invoke(mmDevice, 1);
 } catch (Exception e) {
 }

我正在从蓝牙设备正确读取字节。

我得到了例外:

java.io.IOException:读取失败,套接字可能关闭或超时,读取 ret:-1

因此,连接中断,我的设备和蓝牙设备之间的通信也结束了。

这个问题尤其出现在 Android 5.0.1 Lollipop 上

任何人都可以有解决方法吗?

4

4 回答 4

6

使用createRfcommSocketToServiceRecord代替 createRfcommSocket

createRfcommSocketToServiceRecord获取您传递的 UUID 并使用 SDP 来决定用于连接的无线电频道。它还检查以确保服务器正在使用相同的 UUID 侦听远程端点。这样,获得连接是最可靠的方式:它将始终使用正确的通道,并且如果打开连接成功,您知道另一端的某些内容可以理解您的协议。

相反,createRfcommSocket只需连接到您告诉它的频道。没有办法知道远程端点上是否有任何东西在监听:你只知道设备在那里。此外,您选择的无线电频道可能完全不合适。这就是为什么这个函数没有在API中发布,而另一个函数是首选的。

createRfcommSocket一开始可能看起来更可靠,但这是因为它没有检查另一个端点是否存在侦听器:它忽略了一些错误情况。这对于实验来说可能没问题,但对于生产系统来说没有用,因为用户经常忘记在另一个端点上启动服务器,并且您的应用程序会以令人困惑的方式失败。

当然,由于createRfcommSocket未在 API 中发布,因此您无法保证它在未来的 Android 版本中会继续工作。

于 2015-05-04T11:07:53.760 回答
2

我在 6.0.1 上遇到过同样的问题,在阅读了各种线程/论坛/博客上的相关内容后,我了解到这是因为缺少后备。您可以通过捕获异常并创建所需的回退来处理它。

更具体地说,BluetoothManager返回默认值 -1,这是不可接受的状态,因此会出现错误。这将引发一个异常,可以通过替换-1的错误来创建一个回退来解决问题。

这是帮助我的链接:

https://github.com/don/BluetoothSerial/issues/89

参考: IOException:读取失败,套接字可能关闭 - Android 4.3 上的蓝牙

于 2017-04-27T12:30:43.793 回答
1

我只在 Lollipop 上遇到了类似的问题(正在使用以前的版本),并且将“ createRfcommSocket”替换为“ createInsecureRfcommSocket”解决了这个问题。

如果您选择官方 API,您可以尝试createInsecureRfcommSocketToServiceRecord,因为createRfcommSocketToServiceRecord 它也不适合我。

于 2015-05-26T19:18:20.697 回答
-1

我对 Lollipop 有类似的问题(在本例中为 5.0.2)。运行 Kitkat 时我没有看到任何问题。我一直在使用 createInsecureRfcommSocketToServiceRecord。我尝试了一些使用反射的建议方法,但似乎没有帮助(我认为该解决方案与旧版本的 Android 有关)。不过需要明确的是,当我连接到多个 SPP 设备(条形码阅读器和带有流动网络蓝牙无线电的 I/O 板)时,我看到的通常会发生。我正在努力寻找解决方案,并认为可能没有解决方案,因为如果您连接到具有相同 UUID 的两台设备(在本例中为通用 SPP 设备),Lollipop 中可能存在问题。

于 2016-08-02T20:32:49.537 回答