开发Android Auto 无线连接时,RFCOMM 负责跟手机做认证和 Wi-Fi 凭证协商,简单记录一下相关内容,方便自己查阅。
正文
什么是 RFCOMM?
RFCOMM(Radio Frequency Communication)是经典蓝牙协议栈中位于 L2CAP 层之上的传输协议,本质是蓝牙上的虚拟串口,完整模拟 RS-232 的流控和字节流特性。
Android 侧通过 BluetoothSocket 暴露成标准 IO 流。
它干什么用?
车载场景里,RFCOMM 是控制信令通道 + 通用数据管道,是 SPP / HFP / DUN / MAP / PBAP 等 Profile 的底层载体:
| 通道 | 承载内容 |
|---|---|
| RFCOMM | AT 命令、Wi-Fi 凭证等控制信令 |
| HFP | 通话语音(SCO/eSCO) |
| A2DP | 音乐流媒体 |
记住一条铁律:RFCOMM 不传实时音视频。
Demo
public class SimpleRfcomm { // SPP 标准 UUID,车载通用 private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); private BluetoothSocket socket; private InputStream in; private OutputStream out; /** 连接设备(必须在子线程调用) */ public void connect(String mac) throws IOException { BluetoothDevice device = BluetoothAdapter.getDefaultAdapter() .getRemoteDevice(mac); socket = device.createRfcommSocketToServiceRecord(SPP_UUID); socket.connect(); in = socket.getInputStream(); out = socket.getOutputStream(); } /** 发送数据 */ public void send(String data) throws IOException { out.write(data.getBytes(StandardCharsets.UTF_8)); out.flush(); } /** 读取数据(简化版,实际建议循环读) */ public String receive() throws IOException { byte[] buf = new byte[1024]; int len = in.read(buf); return new String(buf, 0, len, StandardCharsets.UTF_8); } /** 释放资源 */ public void disconnect() { closeQuietly(in); closeQuietly(out); closeQuietly(socket); } private void closeQuietly(Closeable c) { if (c != null) try { c.close(); } catch (IOException ignored) {} } }
避坑清单:
:Android 12+ 需动态申请
BLUETOOTH_SCAN/BLUETOOTH_CONNECT线程:
connect()/read()阻塞,严禁主线程调用UUID:两端必须一致,否则直接拒连
资源:Socket 泄漏会导致后续连接全部失败
编码:车载设备基本都是 UTF-8,收发保持一致
Android Auto 场景
无线 Android Auto / HiCar 的建链流程:
BLE 广播发现 → RFCOMM 控制通道 → 交换 Wi-Fi 凭证 → Wi-Fi TCP 投屏 → [可选] RFCOMM 保活关键注意点:
RFCOMM 只传凭证和信令,视频走 Wi-Fi,别把 RFCOMM 当数据通道用
严格时序:先 RFCOMM 协商完,再建 Wi-Fi,反了必超时
安全性:确保
BOND_BONDED状态后再传密码,蓝牙链路本身是加密的超时:RFCOMM 建连 + 凭证交换建议 10–15s,超时就断线重试
状态监听:监听
ACTION_BOND_STATE_CHANGED,没配对就别急着连
参考文章
Android 官方 Bluetooth 文档
- AI

