You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python RFCOMM服务器与Android蓝牙连接适配问题求助

问题描述

使用Python 3的socket模块搭建蓝牙RFCOMM服务器,与Android设备连接时遇到两个问题:

  1. Android的BluetoothDevice.createL2capChannel方法无法正常工作
  2. Android的BluetoothDevice.createRfcommSocketToServiceRecord仅支持通过UUID连接,但Python的socket仅支持通过信道绑定

环境信息

  • Python版本:3.11
  • RFCOMM服务器系统:树莓派(Debian 12)
  • Android版本:11

现有代码

Python服务器代码

from socket import *
from threading import Thread


class BluetoothService(Thread):

    def run(self) -> None:
        print("starting Bluetooth service...")
        s_sock = None

        try:
            s_sock = socket(family=AF_BLUETOOTH, type=SOCK_STREAM, proto=BTPROTO_RFCOMM)
            s_sock.bind(("D8:3A:DD:56:AF:08", 29))
            s_sock.listen(1)
            c_sock, addr = s_sock.accept()
            print("client address:", addr)
            data = c_sock.recv(1)
            print(data)
            c_sock.close()
        finally:
            if s_sock is not None:
                s_sock.close()
        pass

Android端代码

val bthManger = getSystemService(BLUETOOTH_SERVICE) as BluetoothManager
val adapter = bthManger.adapter
val device = adapter.getRemoteDevice("D8:3A:DD:56:AF:08")
Log.i("Bluetooth", device.toString())
// checkPermission...
val sock = device.createL2capChannel(29)
sock.connect()
sock.outputStream.write(100)
解决方案

方案1:Python服务器注册UUID服务(推荐)

Android的createRfcommSocketToServiceRecord是标准RFCOMM连接方式,需要服务器端注册对应的UUID服务,让Android设备能通过UUID发现并匹配到绑定的信道。

首先安装pybluez依赖:pip install pybluez,然后修改Python服务器代码:

from socket import *
from threading import Thread
import bluetooth


class BluetoothService(Thread):
    # 通用串口服务UUID,也可以自定义唯一UUID
    SERVICE_UUID = "00001101-0000-1000-8000-00805F9B34FB"

    def run(self) -> None:
        print("starting Bluetooth service...")
        s_sock = None
        port = 29

        try:
            # 注册SDP服务,关联UUID与信道
            service_record = bluetooth.SDP_RECORD_CLASSIC_PORT(port, "Python RFCOMM Server")
            bluetooth.sdp_record_register(service_record, self.SERVICE_UUID)

            # 创建并绑定RFCOMM socket
            s_sock = socket(family=AF_BLUETOOTH, type=SOCK_STREAM, proto=BTPROTO_RFCOMM)
            s_sock.bind(("D8:3A:DD:56:AF:08", port))
            s_sock.listen(1)
            print(f"Listening on RFCOMM channel {port} with UUID {self.SERVICE_UUID}")

            c_sock, addr = s_sock.accept()
            print("client address:", addr)
            data = c_sock.recv(1)
            print(data)
            c_sock.close()
        finally:
            # 注销SDP服务
            bluetooth.sdp_record_unregister(self.SERVICE_UUID)
            if s_sock is not None:
                s_sock.close()

对应的Android端修改为UUID连接:

val bthManger = getSystemService(BLUETOOTH_SERVICE) as BluetoothManager
val adapter = bthManger.adapter
val device = adapter.getRemoteDevice("D8:3A:DD:56:AF:08")
Log.i("Bluetooth", device.toString())
// 检查BLUETOOTH_CONNECT等权限
val serviceUuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB") // 与Python端UUID一致
val sock = device.createRfcommSocketToServiceRecord(serviceUuid)
sock.connect()
sock.outputStream.write(100)

方案2:Android端通过反射指定RFCOMM信道

若不想修改Python服务器,可通过Android反射调用底层API,直接指定RFCOMM信道连接:

val bthManger = getSystemService(BLUETOOTH_SERVICE) as BluetoothManager
val adapter = bthManger.adapter
val device = adapter.getRemoteDevice("D8:3A:DD:56:AF:08")
Log.i("Bluetooth", device.toString())
// 检查权限
val channel = 29 // 与Python服务器绑定的信道一致
var sock: BluetoothSocket? = null
try {
    // 反射调用底层createRfcommSocket方法
    val method = device.javaClass.getMethod("createRfcommSocket", Int::class.java)
    sock = method.invoke(device, channel) as BluetoothSocket
    sock.connect()
    sock.outputStream.write(100)
} catch (e: Exception) {
    e.printStackTrace()
} finally {
    sock?.close()
}

注意:反射方法依赖Android系统底层实现,不同版本可能存在兼容性问题,Android 11下可正常使用。

补充说明

createL2capChannel无法工作是因为协议不匹配:你的Python服务器使用的是RFCOMM协议,而L2CAP是另一种独立的蓝牙协议,两者无法互通,并非方法本身失效。

内容的提问来源于stack exchange,提问作者朽木不可雕也

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 22:50:56