我有一个通过蓝牙连接到设备的项目。它以前工作得相当可靠,但现在每次都无法通过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/蓝牙聊天服务(2870):连接到
zyno-700091 00:06:66:42:8e:01失败:读取失败,套接字可能
关闭,读取ret:-1
这个错误过去常常出现一次。我有一个积极的重新连接系统-它基本上是一次又一次地敲打连接,直到它连接起来,如果它曾经断开,它又开始敲打它。所以,它会杀死连接线程并不断从头开始。我曾考虑过可能存在一个问题——可能是多线程问题,或者是在处理套接字清理/初始化时。但是,如果是这样的话,我仍然希望第一次连接尝试能够成功,因为在连接尝试失败之前,系统不会启动。
我查看了抛出异常的source code。问题似乎是底层的InputStream没有数据。当然,这并不是一个真正的答案,只是朝着这个方向迈出的一步。为什么流没有数据?
我试图对潜在的问题保持开放的态度。我是不是得到了正确的BluetoothSocket?它曾经是一个间歇性问题,现在几乎是恒定的,让我怀疑多线程,但这是一个相对简单的Java主题,与C++相比,如果你知道自己在做什么,就很难拧紧。另外,大部分代码(特别是处理线程同步的部分)都是直接从示例代码中提取出来的。
另一端的设备是一个嵌入式蓝牙设备,因此从这一端调试问题的希望不大。
更新===========================
我突然想到这可能是由于操作系统升级(我在galaxy nexus手机上运行——我有几个要测试)。所以我打开了一个4.0.4版本的新手机,它成功了!然后回去测试了两个原始的测试手机,都运行4.2,期待着我一直看到的失败。奇怪的是,现在它也能在那些手机上工作。我想说我做了一些事情让这件事再次奏效,但我没有。我仍然感到困惑,现在也怀疑这件事会在我真正需要它的时候奏效。
我想知道是否有可能以某种方式使用4.0.4连接可以正确设置服务器模块的状态,使其能够接受4.2设备?我想,只是在黑暗中打一枪…
更新2===========================
我发现不配对和重新配对将允许设备连接。这是权宜之计,但总比什么都没有好。

最佳答案

Jellybean有一个完全不同的蓝牙协议栈,所以版本差异肯定会触发某些东西,但这本身并不能解释为什么它在连接到旧设备后仍然工作或不工作。可能和配对有关吗?如果再次发生,请尝试从设备取消配对并再次配对。

08-18 13:50