🚀 手把手教你从 0 到 1 完成 Flutter 蓝牙通信(无硬件实战)
适合人群
- Flutter 开发者,想入门 BLE
- 手上没有任何蓝牙硬件
- 经常遇到「设备能连上,但怎么都通信不了」
本教程将带你 从 0 到 1 跑通一套完整的 BLE 通信流程:
- Android 手机 + nRF Connect 👉 模拟蓝牙服务端
- iOS + Flutter 👉 作为蓝牙客户端
- 完成 Write + Notify 的双向通信
🧠 一、先建立一个正确的 BLE 心智模型(很重要)
BLE 并不是「连上设备就能发数据」。
它的真实结构是:
设备(Device)
└── 服务(Service,UUID)
└── 特征(Characteristic,UUID + 属性)
这意味着什么?
- 通信不是对设备,而是对 Characteristic
- 写数据,必须写到“支持 Write 的 Characteristic”
- 收数据,必须监听“支持 Notify 的 Characteristic”
👉 Service / Characteristic 选错一个,通信必失败
📦 二、准备工作:安装 nRF Connect(模拟服务端)
我们使用 Nordic 官方工具 nRF Connect 来模拟一个 BLE 外设(Server)。
1️⃣ 下载地址(APK)
安装到 Android 真机 后打开。
🧩 三、配置 GATT Server(创建服务端能力)
3.1 进入 GATT Server 配置
首页点击:
Configure GATT Server
3.2 使用 Sample configuration(推荐新手)
选择系统内置:
Sample configuration
然后找到 Test Service,复制它的 Service UUID
📌 这个 UUID 后面会反复用到:
- 客户端扫描设备
- 发现服务
- 选择特征通信
📡 四、配置广播(让客户端能扫描到)
回到首页,点击 ADVERTISE,新建一个广播。
关键配置点
- 将 Service UUID 添加到 Scan Response Data
- 这样客户端在扫描时,才能识别你这个设备提供了什么服务
服务端完成标志 ✅
当你在设备列表看到该设备:
说明:
- ✅ GATT Server 已启动
- ✅ 服务 UUID 已广播
📱 五、Flutter 客户端完整流程(新手最关键部分)
5.1 扫描设备(Scan)
Flutter 启动后扫描 BLE 设备:
📌 此时只是 看到设备,还不能通信。
5.2 点击设备,建立连接(Connect)
点击设备后:
scan → connect
连接成功,才有后续步骤。
5.3 发现服务(Discover Services)
连接完成后,客户端会向服务端请求:
你这个设备,提供了哪些 Service?
❗5.4 进入你创建的 Service(UUID 必须一致)
在服务列表中:
- 找到 UUID 与 Test Service 完全一致的 Service
- 点击进入
👉 Service 点错,后面全部白做
5.5 查看 Characteristic(真正的通信入口)
进入 Service 后,会看到多个 Characteristic:
- 有的支持 Read
- 有的支持 Write
- 有的支持 Notify
❗❗5.6 客户端必须选对 Characteristic
写数据(客户端 → 服务端)
- 选择 支持 Write / Write Without Response 的 Characteristic
- 使用它发送数据
收数据(服务端 → 客户端)
- 选择 支持 Notify 的 Characteristic
- 开启监听(subscribe)
📌 对不支持 Write 的 Characteristic 写数据:
不报错,但一定没反应
🔁 六、双向通信验证
6.1 客户端写入数据
6.2 服务端 Notify 客户端
⚠️ 七、一个 nRF Connect 的 UI 坑
服务端数据不会自动刷新:
- 切换页面
- 再切回 SERVER
- 才能看到最新数据
❗不是通信失败,是 UI 问题。
📎 示例代码
✅ 总结一句话
BLE 通信 = 连设备 + 找对 Service + 用对 Characteristic