android - BluetoothSocket.connect() 抛出异常 "read failed"

标签 android bluetooth

我有一个通过蓝牙连接到设备的项目。它曾经相当可靠地工作,但现在它每次都无法调用 BluetoothSocket.connect()。 (好吧,我在 4 小时内进行了数千次尝试,让它连接了一次。)大部分代码都取自 API 中的标准示例聊天代码,除了在获取 BluetoothSocket 设备本身:

Method m = device.getClass().getMethod(
              "createRfcommSocket", new Class[] { int.class });
tmp = (BluetoothSocket) m.invoke(device, Integer.valueOf(1));

这是感兴趣的方法,一旦获得 BluetoothSocket 就会运行:

public void run() {
  setName("ConnectThread" + mSocketType);

  // Always cancel discovery because it will slow down a connection
  mAdapter.cancelDiscovery();

  // Make a connection to the BluetoothSocket
  try {
    mmSocket.connect();
  } catch (Exception e) {
    Log.e(TAG, "Connection to " + mmDevice.getName() + " at "
                + mmDevice.getAddress() + " failed:" + e.getMessage());
    // Close the socket
    try {
        mmSocket.close();
    } catch (Exception e2) {
        Log.e(TAG, "unable to close() " + mSocketType
                + " socket during connection failure", e2);
    }
    connectionFailed(e.getMessage());
    return;
  }

  // Reset the ConnectThread because we're done
  synchronized (BluetoothChatService.this) {
    mConnectThread = null;
  }

      // Start the connected thread
  connected(mmSocket, mmDevice, mSocketType);
}

相关日志条目(调用connect()时捕获到异常时打印)是这样的:

11-30 10:23:51.685: E/BluetoothChatService(2870): Connection to ZYNO-700091 at 00:06:66:42:8E:01 failed:read failed, socket might closed, read ret: -1

这个错误曾经偶尔出现。我有一个积极的重新连接系统 - 它基本上一遍又一遍地锤击连接直到它连接,如果它曾经断开连接,它会再次开始锤击它。因此,它会终止连接线程并不断从头开始。我曾考虑过那里可能存在问题 - 可能是多线程问题,或者可能是在处理套接字清理/初始化方面。但是,如果是这种情况,我仍然希望第一次连接尝试成功,因为该系统在连接尝试失败之前不会启动。

我查看了 source code抛出异常。问题似乎是底层 InputStream 没有数据。当然,这不是真正的答案,只是朝着它迈出的一步。为什么流中没有数据?

我试图对潜在问题保持开放的态度。我是否正确获取了 BluetoothSocket?它曾经是一个间歇性的问题,现在几乎是不变的,这一事实让我怀疑多线程,但与 C++ 相比,这是 Java 中一个相对简单的主题——如果你知道自己在做什么,就很难搞砸。此外,此代码的大部分(特别是处理线程同步的部分)直接来自示例代码。

另一端的设备是嵌入式蓝牙设备,因此从那端调试问题的希望不大。

更新 ===========================

我想到这可能是由于操作系统升级(我在 Galaxy Nexus 手机上运行 - 我有几个要测试)。所以我用 4.0.4 打开了一部新手机,它工作了!然后返回并在两个运行 4.2 的原始测试手机上进行测试,期待我一直看到的失败。奇怪的是,现在它也适用于那些手机。我想说我做了一些事情让这个作品再次成功,但我没有。我仍然很困惑,现在也怀疑这个东西在我真正需要它的时候会起作用。

我想知道是否有可能以某种方式使用 4.0.4 连接可以正确设置服务器模块的状态,使其能够接受 4.2 设备?我想这只是在黑暗中的一枪......

更新 2 ===========================

我发现取消配对和重新配对将允许设备连接。这是一种解决方法,但总比没有好。

最佳答案

Jellybean 有一个完全不同的蓝牙堆栈,因此版本差异肯定会触发某些事情,但这本身并不能解释为什么它在连接到旧设备后仍然工作或不工作。会不会跟配对有关?如果再次发生,请尝试取消与设备的配对并重新配对。

关于android - BluetoothSocket.connect() 抛出异常 "read failed",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13648373/

相关文章:

android - 从 Kotlin android 中的 json 字符串中删除换行符\n

iphone - iPhone sdk 支持 l2cap 蓝牙 socket 吗?

android - 从移动蓝牙打印机 (ESC/POS) 请求电池状态

android - 更新 Android 4.2.2 后蓝牙流停止。至 4.4.2

java - 蓝牙连接失败 : read failed, socket might closed or timeout, read ret: -1

java - Android: R.java: 错误 <identifier> 预期

android - java.lang.RuntimeException : Unable to instantiate activity 错误

Android Espresso 如何从自定义 View 中获取 EditText 然后键入文本

android - SIP API SipManeger 返回 null

ios - iOS 应用程序与 Atmega 1284 微处理器之间通过蓝牙进行应用程序间通信