-
一个小时搞定蓝牙调试助手!!!
2026-01-18 16:39:56 避难所建设
一个小时搞定蓝牙调试助手!!!项目介绍 蓝牙调试助手是一个用于蓝牙低功耗(BLE)设备开发和调试的移动应用程序,旨在帮助开发者更高效地进行蓝牙相关项目的调试和分析。
主要功能包括:
蓝牙数据捕获:实时捕获蓝牙设备之间的通信数据,包括连接状态、传输数据等。数据包分析:解析蓝牙数据包,显示详细信息如信号强度、设备地址、数据内容等。设备管理:支持对蓝牙设备的扫描、连接、数据收发和断开操作。实时监控:提供实时的蓝牙设备状态监控,帮助开发者快速定位问题。配置管理:支持对蓝牙设备的配置参数进行调整和管理。该工具以图形化界面呈现,操作简单,适用于需要进行蓝牙通信测试和调试的场景。
平台支持AndroidiOSAiFlutter市场链接:蓝牙调试助手App
平台实现步骤1. 注册登录打开 低代码平台登录网页 ,使用微信快捷登录或者扫描二维码登录。
2. 创建项目点击【新增项目】->【手动添加】,在平台内部创建项目在跳出的弹窗中输入项目名称、项目描述,建议结合项目功能描述命名,便于检索输入完成后点击确定
3. 创建页面(1)点击已经创建好的项目进入到操作界面,默认会存在一个HomePage页面,操作界面相关详情可查看教程 操作界面
(2)创建三个页面 AddBleDevice、SetBleName、DeviceNetWork
点击【添加页面】 -> 【创建页面】在跳出的弹窗中输入 页面名称、页面描述最后点击确定即可
(4)删除HomePage页面,在【页面管理】中右击要删除的页面,并点击【删除】
(5)设置AddBleDevice为主页面,在【页面管理】中单击要删除的页面,并在右侧的属性编辑器中设置页面路由为/
4. 页面设计AddBleDevice页面设计页面描述
在页面初始化时,会依次执行以下操作 监听蓝牙扫描状态,接收到状态变化后重新构建页面蓝牙扫描结果监听,接收到扫描结果后进行存储并重新构建页面开始蓝牙扫描,扫描时长8秒连接设备,在设备列表中选择设备进行连接,连接成功后跳转到数据收发页面重新扫描,蓝牙扫描结束后,点击【重新扫描】开始扫描,此时会断开已连接的蓝牙设备效果图
实现流程
(1)在【页面管理】中单击AddBleDevice页面,在右侧的属性编辑器中添加页面变量
需要定义的变量如下
变量名称变量类型是否为数组默认值变量描述devicesMap是设备原始数据列表,用来去重scaningBool否false蓝牙扫描状态 true 正在扫描 false 未扫描deviceListMap是页面显示的设备列表
操作成功如下
(2)添加页面初始化动作,在右侧的属性编辑器中点击【动作】-> 【打开】
在操作流程编辑器中,页面初始化 事件下点击+号添加事件,再点击+号添加动作,信息如下
动作类型 --【自定义代码块】,添加customCode1自定义代码块并选择操作成功如下
(3)开启顶部导航栏,点击页面编辑窗口右上角的【顶部导航栏】并开启,配置顶部导航栏背景色为 #FF006FFF
从【小部件面板】-> 【常用元素】中选择文本小部件拖入到顶部导航栏中间位置中,然后在右侧的属性编辑器中配置属性,属性信息如下: 文本内容蓝牙连接文本颜色#FFFFFFFF文本大小18从【小部件面板】-> 【常用元素】中选择按钮小部件拖入到顶部导航栏右侧位置中,然后在右侧的属性编辑器中配置属性,属性信息如下: 按钮宽 40 高40按钮背景颜色#00C8C8C8按钮阴影大小0按钮打开动作流程编辑器,单击 事件下点击+号添加事件,再点击+号添加动作,信息如下 动作类型 --【导航】,设置导航到SetBleName页面从【小部件面板】-> 【基本元素】中选择图标小部件拖入到按钮小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下: 图标选择 setting图标大小 24图标颜色 #FFFFFFFF(4)页面内容设计
从【小部件面板】-> 【常用元素】中选择容器小部件拖入到页面编辑窗口内的上下布局中,然后在右侧的属性编辑器中配置属性,属性信息如下:
宽 80 高20
背景颜色#00C8C8C8
从【小部件面板】-> 【基本元素】中选择雷达小部件拖入到页面编辑窗口内的上下布局中,然后在右侧的属性编辑器中配置属性,属性信息如下:
绑定变量 deviceList
宽320 高320
雷达指针
开启true指针颜色#FF00478D背景渐变
开启 true渐变类型 放射性渐变过渡点 颜色:#7740FAB0, 过渡点:0 颜色:#FFFFFFFF, 过渡点:1渐变中心 0,0渐变半径0.5水波纹属性
水波纹个数3水波纹颜色#1CE6ECEC是否填充 true扫描目标属性
点的大小 15点的颜色 #FF3B35B7操作成功如下
再次从【小部件面板】-> 【常用元素】中选择容器小部件 拖入到页面编辑窗口内的上下布局中,然后在右侧的属性编辑器中配置属性,属性信息如下:
宽 无限大 高40
背景颜色#00C8C8C8
从【小部件面板】-> 【基本元素】中选择 条件生成器小部件 拖入到容器小部件中,然后在右侧的属性编辑器中选择变量scaning,属性信息如下:
条件 scaning = false,勾选展示此界面,从【小部件面板】-> 【常用元素】中选择按钮小部件拖入到条件生成器小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下:
按钮宽 120 高40按钮背景颜色#00C8C8C8按钮阴影大小0按钮动作面板中打开动作流程编辑器,单击 事件下点击+号添加事件,再点击+号添加动作,信息如下 动作类型 --【自定义代码块】,添加customCode2自定义代码块并选择从【小部件面板】-> 【常用元素】中选择文本小部件拖入到按钮小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下: 文本内容 重新扫描
字体颜色 #FF006FFF
字体大小 18
字体粗细 500
条件 scaning = true,勾选展示此界面,从【小部件面板】-> 【常用元素】中选择文本小部件拖入到条件生成器小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下:
文本内容 正在扫描文本大小 18字体粗细 500操作成功如下
从【小部件面板】-> 【基本元素】中选择滚动条小部件拖入到页面编辑窗口内的上下布局中
从【小部件面板】-> 【布局元素】中选择列表布局小部件拖入到滚动条小部件中
绑定变量 deviceList
宽340 高350
操作成功如下
从【小部件面板】-> 【常用元素】中选择容器小部件拖入到列表布局小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下:
宽无限大 高80
背景颜色 #FFFFFFFF
圆角10
内边距10
外边距 上:10 下:10
从【小部件面板】-> 【常用元素】中选择左右布局小部件拖入到容器小部件中
从【小部件面板】-> 【常用元素】中选择上下布局小部件拖入到左右布局小部件中
拖入容器+文本到上下布局小部件中,并设置 文本内容 ${deviceList[index]["name"] == '' ? '未知' : deviceList[index]["name"]}字体大小 16字体粗细 700容器宽 120 高20容器背景颜色#00C8C8C8拖入容器+文本到上下布局小部件中,并设置 文本内容 Mac: ${deviceList[index]['mac']} RSSI: ${deviceList[index]["rssi"]}字体颜色 #FF999999字体大小 14字体粗细 500容器宽 260 高20容器背景颜色#00C8C8C8从【小部件面板】-> 【常用元素】中选择按钮小部件拖入到左右布局小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下:
宽 60 高40背景颜色#00C8C8C8阴影大小0
按钮动作面板中打开动作流程编辑器,单击 事件下点击+号添加事件,再点击+号添加动作,信息如下
动作类型 --【自定义代码块】,添加customCode3自定义代码块并选择
从【小部件面板】-> 【常用元素】中选择文本小部件拖入到按钮小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下:
文本内容 连接
字体颜色 #FF006FFF
字体大小 14
字体粗细 500
操作成功如下
customCode1内容如下
void function() {
// 控制雷达扫描的动画
waterRippleController = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
);
radarViewController = AnimationController(
vsync: this,
duration: const Duration(seconds: 5),
);
// 蓝牙扫描结果处理
ble.onScanResults(callbackLast: (event) {
String name = event.advertisementData.advName;
// 设备名称过滤
String DEVICE_NAME = StorageUtil().read('DEVICE_NAME') ?? '';
if ((DEVICE_NAME.isNotEmpty &&
(name == '' || !name.contains(DEVICE_NAME))) ||
devices.contains(event)) {
return;
}
// 去重操作,防止重复设备添加
devices.add(event);
if (mounted) {
setState(() {
// 添加至设备列表
deviceList.add({
"name": event.device.platformName,
"rssi": event.rssi,
"mac": "mac",
"raw": event
});
});
}
});
// 扫描状态处理
ble.isScaning((event) {
if (mounted) {
setState(() {
scaning = event;
});
if (event) {
waterRippleController?.repeat();
radarViewController?.repeat();
} else {
waterRippleController?.stop();
radarViewController?.stop();
}
}
});
// 开始扫描
ble.status(timeout: const Duration(seconds: 8));
}customCode2内容如下
function() async {
EasyLoading.dismiss();
if (mounted) {
// 断开蓝牙
await ble.disconnect();
setState(() {
// 清空设备列表
devices.clear();
});
// 重新扫描设备
ble.status(timeout: const Duration(seconds: 8));
}
}customCode3内容如下
void function(index) {
if (scaning) {
ble.stopScan();
}
EasyLoading.show();
// 连接蓝牙
ble.connect(deviceList[index]['raw'].device,
serviceUUID: StorageUtil().read("serviceUUID") ?? '',
readCharacteristicUUID:
StorageUtil().read("readCharacteristicUUID") ?? '',
writeCharacteristicUUID:
StorageUtil().read("writeCharacteristicUUID") ?? '',
notifyCallBcak: () async {
Map
json = { "name": deviceList[index]['name'],
"id": deviceList[index]['mac']
};
await Get.toNamed('/DeviceNetWork', arguments: json);
EasyLoading.dismiss();
});
}SetBleName页面设计页面描述
蓝牙名称过滤,设置BLE名称后蓝牙只搜索该名称的设备读写UUID,如果不设置蓝牙的读写UUID,则默认向所有的读写UUID发送数据和接收数据效果图
实现流程
(1)在【页面管理】中单击SetBleName页面,在右侧的属性编辑器中添加页面变量
需要定义的变量如下
变量名称变量类型是否为数组默认值变量描述DEVICE_NAMEString否${StorageUtil().read("DEVICE_NAME") ?? ''}设备名称serviceUUIDString否服务UUIDreadCharacteristicUUIDString否读特征UUIDwriteCharacteristicUUIDString否写特征UUID操作成功如下
(2)开启顶部导航栏,点击页面编辑窗口右上角的【顶部导航栏】并开启,配置顶部导航栏背景色为 #FF006FFF
从【小部件面板】-> 【常用元素】中选择文本小部件拖入到顶部导航栏中间位置中,然后在右侧的属性编辑器中配置属性,属性信息如下: 文本内容设置文本颜色#FFFFFFFF文本大小18(3)页面内容设计
从【小部件面板】-> 【常用元素】中选择容器小部件拖入到页面编辑窗口内的上下布局中,然后在右侧的属性编辑器中配置属性,属性信息如下:
宽 无限大 高600
背景颜色#00C8C8C8
内边距10
从【小部件面板】-> 【常用元素】中选择上下布局小部件拖入到容器小部件中
从【小部件面板】-> 【常用元素】中选择上下布局小部件拖入到上下布局小部件中
从【小部件面板】-> 【常用元素】中选择文本小部件拖入到上下布局小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下: 文本内容BLE名称从【小部件面板】-> 【常用元素】中选择容器小部件拖入到上下布局小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下: 宽 无限大 高50背景颜色#00C8C8C8下边框 宽度 1 颜色 #FF999999 样式 一从【小部件面板】-> 【表单元素】中选择文本输入框小部件拖入到容器小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下: 数据绑定变量 DEVICE_NAME光标颜色#FF006FFF操作成功如下复制上述上下布局小部件及其子小部件的内容,并粘贴,修改内容如下
文本内容 服务UUID 、读特征UUID 、写特征UUID绑定变量 serviceUUID 、readCharacteristicUUID 、writeCharacteristicUUID操作成功如下
从【小部件面板】-> 【常用元素】中选择按钮小部件拖入到上下布局小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下:
从【小部件面板】-> 【常用元素】中选择文本小部件拖入到按钮小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下:
文本内容 确认
字体颜色 #FFFFFFFF
字体大小 14
字体粗细 500
宽 无限大 高40
背景颜色#FF006FFF
阴影大小4
圆角大小10
按钮动作面板中打开动作流程编辑器,单击 事件下点击+号添加事件,再点击+号添加动作,信息如下
动作类型 --【自定义代码块】,添加customCode1自定义代码块并选择customCode1内容如下
void function(){
StorageUtil().write("DEVICE_NAME", DEVICE_NAME);
StorageUtil().write("serviceUUID", serviceUUID);
StorageUtil().write("readCharacteristicUUID", readCharacteristicUUID);
StorageUtil().write("writeCharacteristicUUID", writeCharacteristicUUID);
EasyLoading.showSuccess("设置成功");
Get.back();
}DeviceNetWork页面设计页面描述
在页面初始化时,会依次执行以下操作 蓝牙接收数据监听,接收到数据后进行存储并重新构建页面蓝牙连接状态监听,如果蓝牙断开连接,则在400ms后回到上一个页面发送数据,用户在输入框中输入16进制数据后点击发送即可效果图
实现流程
(1)在【页面管理】中单击DeviceNetWork页面,在右侧的属性编辑器中添加页面变量
需要定义的变量如下
变量名称变量类型是否是列表默认值变量描述passwordMap是接收的数据内容isConnectedBool否false连接状态wifinameString否发送数据内容_getDataVar否数据接收流_connectionSubscriptionVar否连接状态流disconnectTimerVar否断开连接定时器(2)添加页面初始化动作,在右侧的属性编辑器中点击【动作】-> 【打开】
在操作流程编辑器中,页面初始化 事件下点击+号添加事件,再点击+号添加动作,信息如下
动作类型 --【自定义代码块】,添加customCode1自定义代码块并选择customCode1内容如下
void function(){
_connectionSubscription?.cancel();
_connectionSubscription = ble.connectController.stream.listen((event) {
if (event is BluetoothConnectionState) {
if (mounted) {
setState(() {
switch (event) {
case BluetoothConnectionState.connected:
isConnected = true;
break;
case BluetoothConnectionState.disconnected:
disconnectTimer?.cancel();
disconnectTimer = Timer(const Duration(milliseconds: 400), () {
if (connectStatus == BluetoothConnectionState.disconnected) {
//400毫秒后还是未连接才代表断开了连接,回到以前的界面
print("400毫秒后还是未连接才代表断开了连接,回到以前的界面");
EasyLoading.showError("设备断开了连接");
Get.offNamed('/');
}
});
break;
default:
}
});
}
}
});
_getData?.cancel();
_getData = ble.getBleDateController.stream.listen((event) {
if (event is List
&& event.length != 0) { List
newArr = event; print("蓝牙发送过来的数据_netWork:$newArr");
List
dataArr = []; for (var i = 0; i < newArr.length; i++) {
var element = newArr[i];
String str = '';
str = element.toRadixString(16);
str = str.length == 1 ? "0$str" : str;
dataArr.add(str);
}
password.add({
"type": "接收",
"data": dataArr.join(),
"time": DateFormat("HH:mm:ss").format(DateTime.now()),
});
setState(() {});
}
});
}(3)开启顶部导航栏,点击页面编辑窗口右上角的【顶部导航栏】并开启,配置顶部导航栏背景色为 #FF006FFF
从【小部件面板】-> 【常用元素】中选择文本小部件拖入到顶部导航栏中间位置中,然后在右侧的属性编辑器中配置属性,属性信息如下: 文本内容数据收发文本颜色#FFFFFFFF文本大小18(4)页面内容设计
从【小部件面板】-> 【常用元素】中选择容器小部件拖入到页面编辑窗口内的上下布局中,然后在右侧的属性编辑器中配置属性,属性信息如下:
宽 无限大 高700
背景颜色#C8C8C800
内边距10
从【小部件面板】-> 【常用元素】中选择上下布局小部件拖入到容器小部件中
拖入 容器+文本 到上下布局小部件中,并设置
文本内容 连接状态: ${isConnected?'已连接': '未连接' }宽 无限大 高30背景颜色#00C8C8C8拖入 容器+文本 到上下布局小部件中,并设置
文本内容 数据收发内容宽 无限大 高40背景颜色#00C8C8C8从【小部件面板】-> 【常用元素】中选择容器小部件拖入到上下布局小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下:
宽 无限大 高300背景颜色#00C8C8C8从【小部件面板】-> 【布局元素】中选择列表布局小部件拖入到容器小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下: 数据变量绑定 password从【小部件面板】-> 【常用元素】中选择文本小部件拖入到列表布局小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下: 文本内容 ${password[index]['type']}: ${password[index]['data']}拖入 容器+文本 到上下布局小部件中,并设置
文本内容 发送数据内容宽 无限大 高40背景颜色#00C8C8C8从【小部件面板】-> 【常用元素】中选择容器小部件拖入到上下布局小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下:
宽 无限大 高50背景颜色#00C8C8C8下边框 颜色 #FF999999 宽度 1 样式 一从【小部件面板】-> 【表单元素】中选择文本输入框小部件拖入到容器小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下: 输入框数据变量绑定 wifiname输入框光标颜色 #006FFFFF从【小部件面板】-> 【常用元素】中选择按钮小部件拖入到上下布局小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下:
从【小部件面板】-> 【常用元素】中选择文本小部件拖入到按钮小部件中,然后在右侧的属性编辑器中配置属性,属性信息如下: 文本内容 发送数据
字体颜色 #FFFFFFFF
宽 200 高40背景颜色 #FF006FFF圆角 10按钮动作面板中打开动作流程编辑器,单击 事件下点击+号添加事件,再点击+号添加动作,信息如下 动作类型 --【自定义代码块】,添加customCode2自定义代码块并选择customCode2内容如下
void function() async {
if (wifiname == null) {
EasyLoading.showError("请输入数据".tr);
return;
}
List
intArray = []; for (int i = 0; i < wifiname.length; i += 2) {
String hexPair = wifiname.substring(i, i + 2);
intArray.add(int.parse(hexPair, radix: 16));
}
password.add({"type": "发送", "data": wifiname});
setState(() {});
await ble.writeWithOut(intArray);
}