Android BluetoothSocket连接失败:read failed,socket可能关闭或超时
Android 连接Allflex LPR RFID Reader蓝牙设备失败问题
按照Android官方蓝牙设备连接指引,尝试连接Allflex LPR RFID Reader(型号"LPR_64980"),已完成设备发现并获取到BluetoothDevice对象存储在this.rfidreader中,使用官方示例的ConnectThread发起连接:
public void tappedConnectLPR() { new ConnectThread(rfidreader).start(); }
可正常创建BluetoothSocket,但调用mmSocket.connect()时,阻塞约20秒后抛出IOException,错误信息:
exception: read failed, socket might closed or timeout, read ret: -1
Logcat相关日志:
13:38:12.789 D close() this: android.bluetooth.BluetoothSocket@7eb866e, channel: -1, mSocketIS: android.net.LocalSocketImpl$SocketInputStream@951f10f, mSocketOS: android.net.LocalSocketImpl$SocketOutputStream@ff0659c, mSocket: android.net.LocalSocket@af8fba5 impl:android.net.LocalSocketImpl@f4d9b7a fd:java.io.FileDescriptor@3c68f2b, mSocketState: INIT
补充说明:iPhone可正常连接该设备,已断开iPhone与设备的连接并让iPhone忽略该设备,排除干扰。
ConnectThread完整代码:
private class ConnectThread extends Thread { private static final UUID bluetoothServiceUUID = UUID.fromString("5cb6b8e2-b944-44b3-b806-a92d4587123c"); private final BluetoothSocket mmSocket; private final BluetoothDevice mmDevice; @SuppressLint("MissingPermission") public ConnectThread(BluetoothDevice device) { BluetoothSocket tmp = null; mmDevice = device; try { Log.d("MA", "about to create rfcomm socket..."); tmp = device.createRfcommSocketToServiceRecord(bluetoothServiceUUID); } catch (IOException e) { Log.e("MA", "Socket's create() method failed", e); } mmSocket = tmp; Log.d("MA", "got rfcomm socket..."); } @SuppressLint("MissingPermission") public void run() { Log.d("MA", "stopping discovery, just in case"); bluetoothAdapter.cancelDiscovery(); try { Log.d("MA", "trying to connect"); mmSocket.connect(); Log.d("MA", "connected?"); } catch (IOException connectException) { Log.d("MA", "exception: "+connectException.getMessage()); try { mmSocket.close(); } catch (IOException closeException) { Log.e("MA", "Could not close the client socket", closeException); } return; } manageMyConnectedSocket(mmSocket); } public void cancel() { try { mmSocket.close(); } catch (IOException e) { Log.e("MA", "Could not close the client socket", e); } } }
解决方案
1. 验证UUID正确性
当前使用的UUID可能与设备实际服务UUID不匹配,可通过以下方式获取设备广播的UUID:
@SuppressLint("MissingPermission") UUID[] uuids = rfidreader.getUuids(); if (uuids != null) { for (UUID uuid : uuids) { Log.d("MA", "设备服务UUID: " + uuid.toString()); } }
若设备未广播UUID,可尝试通用SPP协议UUID:00001101-0000-1000-8000-00805F9B34FB
2. 尝试反射指定RFCOMM通道连接
部分设备不支持通过Service Record创建Socket,可直接指定RFCOMM通道(常用通道为1,可尝试1-30范围):
// 替换原createRfcommSocketToServiceRecord的调用 try { Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class}); tmp = (BluetoothSocket) m.invoke(device, 1); } catch (Exception e) { Log.e("MA", "反射创建Socket失败", e); }
3. 检查蓝牙权限
确保已申请对应Android版本的蓝牙权限:
- Android 12+:
BLUETOOTH_SCAN、BLUETOOTH_CONNECT - Android 11及以下:
BLUETOOTH、BLUETOOTH_ADMIN、ACCESS_FINE_LOCATION
4. 重置蓝牙状态
重启Android设备和RFID阅读器的蓝牙模块,清除双方配对记录后重新尝试配对连接。
5. 避免扫描时连接
确保设备发现完成后再发起连接,避免扫描过程中资源冲突导致连接超时。
内容的提问来源于stack exchange,提问作者Kenny Wyland
相关产品推荐
相关产品推荐

