Flutter蓝牙通信插件h_ble的使用

Flutter蓝牙通信插件h_ble的使用

本包适用于特定项目。

开始使用

该项目是一个用于Flutter的插件包,包含针对Android和/或iOS平台的特定实现代码。

示例代码

以下是使用h_ble插件的一个完整示例Demo:

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:h_ble/h_ble.dart';
import 'package:h_ble/h_ble_device.dart';
import 'package:h_ble/h_ble_device_services.dart';
import 'package:h_ble/h_ble_device_services_characteristics.dart';

import 'h_permission.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  final _hBlePlugin = HBle();
  HBleDeviceServicesCharacteristics? sentCharacteristics;

  [@override](/user/override)
  void initState() {
    super.initState();

    HPermission.checkBluetooth(context, end: (){});
    _hBlePlugin.addScanListen(scanListen);
    _hBlePlugin.addNotificationListen(notification);
  }

  Map<String, HBleDevice> deviceMap = {};

  void scanListen(HBleDevice device){
    if(device.name?.contains("YX") == true){
      debugPrint("scanListen $device");
      deviceMap[device.identifier] = device;
      if(mounted){
        setState(() {});
      }
    }
  }

  void notification(String serviceUuid, String characteristicsUuid, Uint8List bytes){
    debugPrint("notification main : ${bytes.toString()}");
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Column(
          children: [
            Row(
              children: [
                GestureDetector(
                  child: Container(color: Color(0xffff0000), width: 100, height: 100, child: Text("扫描")),
                  onTap: (){
                    deviceMap = {};
                    _hBlePlugin.scan();
                    setState(() {});
                  },
                ),
                GestureDetector(
                  child: Container(color: Color(0xff00ff00), width: 100, height: 100, child: Text("停止扫描")),
                  onTap: (){
                    _hBlePlugin.stopScan();
                  },
                ),
                GestureDetector(
                  child: Container(color: Color(0xff0000ff), width: 60, height: 100, child: Text("发送测试")),
                  onTap: (){
                    debugPrint("发送测试");
                    String str = _appToMcuSentBase(
                      dataType: '5',
                      data: "0123456789",
                    );
                    if(sentCharacteristics != null){
                      _hBlePlugin.writeCharacteristics(
                          characteristics: sentCharacteristics!,
                          value: Uint8List.fromList(str.codeUnits),
                          withResponse: true,
                          writeResult: (b){
                            debugPrint("发送结果 : $b");
                          }
                      );
                    }
                  },
                ),
                GestureDetector(
                  child: Container(color: Color(0xff44824c), width: 60, height: 100, child: Text("测试")),
                  onTap: (){
                    final str = "1234";
                    _hBlePlugin.secureWriteCharacteristics(
                      characteristics: HBleDeviceServicesCharacteristics.fromMap({}),
                      value: Uint8List.fromList(str.codeUnits),
                    );
                  },
                ),
              ],
            ),
            Expanded(child: listView()),
          ],
        )
      ),
    );
  }

  void historyScanListen(List<HBleDevice> devices){
    debugPrint("历史记录 ; ${devices.length}");
  }

  String _appToMcuSentBase({
    required String dataType,
    String? data,
  }){
    const String headStr = "T";
    String dataTypeLength = intToHexTwoStr(data?.length ?? 0);
    const String tail = "W";
    if(data != null){
      return headStr + dataTypeLength + dataType + data + tail;
    } else {
      return headStr + dataTypeLength + dataType + tail;
    }
  }

  static final List _hexStringList = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
  static String intToHexOneStr(int i){
    if(i < 0){ i = -i; }
    if(i < _hexStringList.length){
      return _hexStringList[i];
    } else {
      return _hexStringList[15];
    }
  }

  static String intToHexTwoStr(int i){
    return intToHexOneStr((i & 0xf0) >> 4) + intToHexOneStr(i & 0x0f);
  }

  Widget listView(){
    List<HBleDevice> deviceList = [];
    deviceMap.forEach((key, value) {
      deviceList.add(value);
    });

    return ListView(
      children: List<Widget>.generate(deviceMap.length, (index) {
        HBleDevice oneDevice = deviceList[index];
        return GestureDetector(
          child: Container(
            margin: const EdgeInsets.all(10),
            width: 300,
            height: 60,
            color: const Color(0xffaff36a),
            child: Text("${oneDevice.name}  ${oneDevice.rssi}  ${oneDevice.advertisementData.toString()}"),
          ),
          onTap: (){
            _hBlePlugin.connect(device: oneDevice, deviceStatus: (ConnectionStatus status) {
              debugPrint("连接状态 : $status");

              if(status == ConnectionStatus.STATE_CONNECTED){
                _hBlePlugin.discoverService(device: oneDevice, deviceServices: (HBleDeviceServices services) {
                  debugPrint("发现服务 : $services");

                  if(services.uuid.toLowerCase().contains("af80")){
                    _hBlePlugin.getCharacteristics(services: services, deviceServicesCharacteristics: (HBleDeviceServicesCharacteristics characteristics) {
                      debugPrint("发现特征 : $characteristics");

                      if(characteristics.characteristicsUuid.toLowerCase().contains("af83")){ // 写

                        Future.delayed(Duration(milliseconds: 500),(){
                          debugPrint("characteristics 写1");
                          String str = "T041AABBW";
                          _hBlePlugin.writeCharacteristics(characteristics: characteristics, value: Uint8List.fromList(str.codeUnits));
                        });

                        sentCharacteristics = characteristics;

                      } else {
                        debugPrint("${characteristics.characteristicsUuid.toString()} 非写");
                      }

                    });
                  }
                });
              }
            });
          },
        );
      }),
    );
  }
}

更多关于Flutter蓝牙通信插件h_ble的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter蓝牙通信插件h_ble的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


h_ble 是一个用于 Flutter 的蓝牙通信插件,它可以帮助开发者轻松地在 Flutter 应用中实现蓝牙设备的扫描、连接、数据读写等操作。以下是如何使用 h_ble 插件的基本步骤:

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 h_ble 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  h_ble: ^1.0.0  # 请根据实际情况使用最新版本

然后运行 flutter pub get 来安装依赖。

2. 初始化插件

在你的 Dart 文件中,导入 h_ble 插件并初始化它:

import 'package:h_ble/h_ble.dart';

HBle hBle = HBle();

3. 检查蓝牙状态

在开始扫描或连接之前,检查设备的蓝牙是否已开启:

bool isEnabled = await hBle.isEnabled();
if (!isEnabled) {
  // 提示用户开启蓝牙
}

4. 扫描设备

使用 startScan 方法扫描附近的蓝牙设备:

hBle.startScan().listen((device) {
  print('Found device: ${device.name} - ${device.id}');
});

5. 停止扫描

当你找到目标设备后,可以停止扫描:

hBle.stopScan();

6. 连接设备

使用 connect 方法连接到目标设备:

await hBle.connect(deviceId);

7. 断开连接

使用 disconnect 方法断开与设备的连接:

await hBle.disconnect(deviceId);

8. 读写数据

在连接成功后,你可以使用 writeread 方法与设备进行数据交互:

// 写入数据
await hBle.write(deviceId, serviceUuid, characteristicUuid, value);

// 读取数据
List<int> data = await hBle.read(deviceId, serviceUuid, characteristicUuid);

9. 监听数据

你也可以监听设备发送的数据:

hBle.setNotification(deviceId, serviceUuid, characteristicUuid, true).listen((data) {
  print('Received data: $data');
});

10. 处理权限

在 Android 上,需要处理蓝牙和定位权限。确保在 AndroidManifest.xml 中添加以下权限:

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

并在运行时请求这些权限:

import 'package:permission_handler/permission_handler.dart';

await Permission.location.request();

11. 错误处理

在蓝牙通信过程中,可能会遇到各种错误,建议在代码中加入错误处理逻辑:

try {
  await hBle.connect(deviceId);
} catch (e) {
  print('Failed to connect: $e');
}

12. 清理资源

在应用退出或不再需要蓝牙功能时,记得释放资源:

await hBle.dispose();
回到顶部