java.io.IOException:读取失败,socket可能关闭或超时,在Android 5.0.1 Lollipop版本上读取ret:-1

时间:2015-03-19 11:43:39

标签: android bluetooth android-5.0-lollipop bluetooth-socket

我正在与蓝牙设备进行蓝牙套接字连接,并希望从设备读取字节。

我已正确建立连接:

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

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

我得到了例外:

  

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

由于这个原因,连接断开,我的设备和蓝牙设备之间的通信也结束了。

Android 5.0.1 Lollipop上出现此问题,尤其是

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

4 个答案:

答案 0 :(得分:6)

使用createRfcommSocketToServiceRecord代替createRfcommSocket

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

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

createRfcommSocket最初可能看起来更可靠,但这是因为它没有检查另一个端点是否存在监听器:它忽略了一些错误情况。这对于实验来说可能没什么用,但它对生产系统没用,因为用户通常会忘记在另一个端点上启动服务器,并且您的应用程序会以混乱的方式失​​败。

当然,由于createRfcommSocket未在API中发布,因此您无法保证它将在以后的Android版本中继续发挥作用。

答案 1 :(得分:2)

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

更具体地说, BluetoothManager 返回默认值-1 ,这不是可接受的状态,因此也就是错误。这将引发异常,可以通过替换错误-1来处理创建后备以解决问题的异常。

这是帮助我的链接:

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

参考: IOException: read failed, socket might closed - Bluetooth on Android 4.3

答案 2 :(得分:0)

我在Lollipop上遇到了类似的问题(正在使用以前的版本)并替换了#34; createRfcommSocket" by" createInsecureRfcommSocket"解决了这个问题。

如果您选择官方API,则可以createInsecureRfcommSocketToServiceRecord作为createRfcommSocketToServiceRecord  也不适合我。

答案 3 :(得分:-1)

我和Lollipop有类似的问题(在本例中为5.0.2)。运行Kitkat时我没有发现任何问题。我一直在使用createInsecureRfcommSocketToServiceRecord。我尝试了一些使用反射的建议方法,但它似乎没有帮助(我认为该解决方案与旧版Android相关)。但要清楚的是,当我连接到多个SPP设备(条形码阅读器和带有漫游网络蓝牙无线电的I / O板)时,我经常会看到这种情况。我很难找到一个解决方案,并认为可能没有,因为如果你连接到具有相同UUID的两个设备(在这种情况下是通用的SPP),Lollipop可能存在问题。