Android经典蓝牙RFCOMM连接失败,getUUIDs()未返回SPP UUID问题咨询
问题原因说明
首先可以肯定两台设备都原生支持SPP/RFCOMM协议,安卓从1.5版本开始就默认支持RFCOMM通信能力,你遇到的连接失败问题和硬件/系统底层支持无关,核心原因如下:
- 你调用
BluetoothDevice#getUUIDs()返回的是对端设备已经主动注册并对外广播的蓝牙服务UUID列表,找不到SPP默认UUID00001101-0000-1000-8000-00805f9b34fb,是因为你没有先在任意一台设备上注册SPP服务端监听。只有当其中一台设备调用服务端监听接口注册了对应UUID的服务后,对端设备扫描UUID时才会返回该值,未注册的情况下直接发起连接自然会触发socket不存在的报错。 - 你用
0000112f-0000-1000-8000-00805f9b34fb这类UUID能建立连接,是因为这些是系统内置蓝牙Profile(比如112f对应PBAP电话本访问服务)的UUID,系统本身就会持续监听这些服务端口,但这些服务有严格的私有通信协议,你直接传输自定义数据会被系统判定为无效数据包直接丢弃,所以不会报错也没有数据返回。 - 反射端口绕过方案不生效的原因是该方案仅针对安卓4.3版本的UUID映射bug,你的问题本质是未启动服务端,自然无法通过反射解决。
修复步骤
你可以按照如下流程调整代码即可正常通信:
- 选定任意一台设备作为服务端,先启动SPP服务监听,核心代码示例:
// 安卓Java示例 BluetoothServerSocket serverSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord( "CustomSPPService", UUID.fromString("00001101-0000-1000-8000-00805f9b34fb") ); // 启动子线程等待连接 new Thread(() -> { try { BluetoothSocket socket = serverSocket.accept(); // 连接成功后获取输入输出流传输数据 } catch (IOException e) { e.printStackTrace(); } }).start();
- 服务端启动监听后,再在另一台客户端设备上发起连接,使用同一个1101 UUID创建socket即可,不要提前发起连接。
- 权限校验:
- 安卓10设备需要确保已经申请
BLUETOOTH、BLUETOOTH_ADMIN、ACCESS_FINE_LOCATION权限 - 安卓11设备需要额外校验蓝牙相关权限是否被Calyx OS的隐私管控限制,确保应用的蓝牙连接权限为允许状态
- 华为EMUI设备需要在系统设置的应用权限管理中,确认「位置信息」或「附近设备」权限已经授予,EMUI对蓝牙扫描权限的管控比原生安卓更严格
- 安卓10设备需要确保已经申请
内容的提问来源于stack exchange,提问作者Aura Lee
相关产品推荐
相关产品推荐

