我有一个通过蓝牙连接到设备的项目。它曾经相当可靠地工作,但现在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 ============================
我发现取消配对和重新配对将允许设备连接。这是一种解决方法,但总比没有好。