10

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

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

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

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):在 00:06:66:42:8E:01 连接到 ZYNO-700091 失败:读取失败,套接字可能关闭,读取 ret:-1

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

我查看了引发异常的源代码。问题似乎是底层证券InputStream没有数据。当然,这并不是真正的答案,只是朝着它迈出的一步。为什么流没有数据?

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

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

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

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

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

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

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

4

4 回答 4

10

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

于 2012-12-03T18:54:33.653 回答
2

我知道这是一个老问题。但由于我无法在网上找到任何解决方案,这是我最近创建的一种解决方法:IOException: read failed, socket might closed - Android 4.3 上的蓝牙

于 2013-09-13T12:48:46.750 回答
1

就我而言,这是由于createRfcommSocketToServiceRecord()功能中的 UUID 错误造成的。我想连接到树莓派 3 中的 SPP 串行配置文件,我使用了这个 UUID:

private static final UUID MY_UUID_SECURE =
            UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

我在 SPP 的 android 文档页面的某个地方找到了。

于 2019-07-27T07:13:21.983 回答
0

我在通过蓝牙模块连接到 arduino 时遇到了同样的问题。这个问题只在与 arduino 连接时出现,因为它与另一个安卓手机蓝牙连接顺畅。对我有用的是更改 UUID 字符串..

于 2018-06-06T07:35:01.063 回答