Android RFCOMM connect() faild 记录(未解决)

本文探讨了Android蓝牙RFCOMM连接时遇到的java.io.IOException:readfailed,socketmightclosedortimeout,readret:-1问题。分析了当手机蓝牙开启并尝试自动连接已配对设备时,应用尝试连接服务可能会导致此错误或连接缓慢的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android Bluetooth RFCOMM 连接出现:java.io.IOException: read failed, socket might closed or timeout, read ret: -1


本人尝试过网络普遍出现的解决方案(线程分离、UUID更改、反射方法)都未果。


但原因是出现在手机蓝牙刚打开(adapter.enable())时,如果手机之前配对过其他蓝牙耳机设备,会自动先去尝试连接。

app再同时去尝试连接RFCOMM服务会出现此错误或者连接缓慢。


如果等待系统蓝牙自动连接尝试完毕后app再去连接服务时会很快就连接成功


目前还未找到规避或解决此问题的方法,如app在连接时取消系统正在尝试连接的设备或者关闭系统自动连接功能等。

如有解决此问题的同学,还请提出宝贵意见,谢谢!

### Android 平台下 RFCOMM 协议的使用 在 Android 中实现基于 RFCOMM 的蓝牙通信涉及多个方面,包括初始化 BluetoothAdapter、建立连接以及数据传输等操作。下面具体说明这些过程。 #### 创建 BluetoothSocket 进行连接 为了通过 RFCOMM 发起连接请求,应用程序通常会创建 `BluetoothSocket` 对象并指定 UUID 来匹配服务端的服务记录。UUID 是用于唯一识别特定应用层协议的一个标识符,在客户端和服务端之间必须一致[^2]。 ```java // 获取默认适配器实例 BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // 使用已知设备地址获取远程设备对象 BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address); // 采用预定义的UUID来创建socket通道 BluetoothSocket socket = device.createRfcommSocketToServiceRecord(MY_UUID); ``` #### 处理线程与异步任务 由于网络操作不应阻塞主线程,因此建议在一个单独的工作线程中执行上述代码片段中的连接逻辑。这可以通过继承 Thread 类或者利用 AsyncTask 实现。当成功建立了到目标设备的安全或不安全链接之后,则可以准备发送接收消息了[^3]。 ```java public class ConnectThread extends Thread { private final BluetoothSocket mmSocket; public ConnectThread(BluetoothDevice device) { // Use a temporary object that is later assigned to mmSocket, // because mmSocket is final. BluetoothSocket tmp = null; try { // Get a BluetoothSocket to connect with the given BluetoothDevice. tmp = device.createRfcommSocketToServiceRecord(MY_UUID); } catch (IOException e) { } mmSocket = tmp; } @Override public void run() { // Cancel discovery as it will slow down connection process. bluetoothAdapter.cancelDiscovery(); try { // Connect to the remote device through the socket. This call blocks until success or exception occurs. mmSocket.connect(); } catch (IOException connectException) { // Unable to connect; close the socket and get out. try { mmSocket.close(); } catch (IOException closeException) {} return; } // Do work to manage the connection (in a separate thread). manageConnectedSocket(mmSocket); } /** Will cancel an in-progress connection, and close the socket */ public void cancel() { try { mmSocket.close(); } catch (IOException e) {} } } ``` #### 数据流管理 一旦连接被确立下来以后就可以读写来自对方的数据包了。一般情况下我们会把输入输出流封装成更高级别的类以便于处理字节序列化等问题。对于简单的应用场景可以直接调用 InputStream 和 OutputStream 方法来进行基本的操作。 ```java private ConnectedThread connectedThread; private class ConnectedThread extends Thread { private final BluetoothSocket mmSocket; private final InputStream mmInStream; private final OutputStream mmOutStream; public ConnectedThread(BluetoothSocket socket) { mmSocket = socket; InputStream tmpIn = null; OutputStream tmpOut = null; // Get the input and output streams; using temp objects because member fields are final. try { tmpIn = socket.getInputStream(); tmpOut = socket.getOutputStream(); } catch (IOException e) {} mmInStream = tmpIn; mmOutStream = tmpOut; } public void run() { byte[] buffer = new byte[1024]; // Buffer store for the stream int bytes; // Bytes returned from read() // Keep listening to the InputStream while connected. while (true) { try { // Read from the InputStream. bytes = mmInStream.read(buffer); // Send the obtained bytes to the UI Activity. mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget(); } catch (IOException e) { break; } } } /* Call this method from the main activity to send data to the remote device. */ public void write(byte[] bytes) { try { mmOutStream.write(bytes); } catch (IOException e) {} } /* Call this method from the main activity to shutdown the connection. */ public void cancel() { try { mmSocket.close(); } catch (IOException e) {} } } // Start the thread to manage the connection and perform transmissions. connectedThread = new ConnectedThread(socket); connectedThread.start(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值