flutter_ttc_ble

A BLE(Bluetooth Low Energy) Flutter plugin for Android and iOS.
flutter_ttc_ble_example

Getting Started

准备

  • Android版本高于5.0(包含),Android扫描蓝牙需要用到位置权限并打开位置服务,位置权限可借助其他库,如 permission_handler
  • iOS版本高于10.0,在ios的Info.plist增加 Privacy - Bluetooth Always Usage Description

扫描设备

  • 插件初始化(使用0.0.5新增的 bleProxy 可以不用显式初始化)
    FlutterTtcBle.init();
  • 扫描设备
    //开启扫描
    FlutterTtcBle.startLeScan((device) {
      //处理数据
    });
    
    //停止扫描
    FlutterTtcBle.stopLeScan();
  • 连接设备 / 断开连接
    //连接设备
    FlutterTtcBle.connect(deviceId: device.deviceId);

    //断开连接
    FlutterTtcBle.disconnect(device.deviceId);
  • 发送数据
    //与蓝牙设备通信的UUID
    const UUID_SERVICE = '00001000-0000-1000-8000-00805f9b34fb';
    const UUID_WRITE = '00001001-0000-1000-8000-00805f9b34fb';
    const UUID_NOTIFY = '00001002-0000-1000-8000-00805f9b34fb';

    FlutterTtcBle.writeCharacteristic(
        deviceId: deviceId,
        serviceUuid: UUID_SERVICE,
        characteristicUuid: UUID_WRITE,
        value: data,
        writeType: CharacteristicWriteType.writeNoResponse);
  • 接收数据
    //通知事件中获取数据
    BleCallback bleCallback = (message) {
      if (message is Map<dynamic, dynamic>) {
        if (message.containsKey('event')) {
          switch (message['event']) {
            case BLEEvent.CONNECTED: //与设备建立连接
              //开启数据通知,这样才能实时接收设备端的数据
              FlutterTtcBle.setCharacteristicNotification(
                deviceId: message['deviceId'],
                serviceUuid: UUID_SERVICE,
                characteristicUuid: UUID_NOTIFY,
                enable: true);
              break;

            case BLEEvent.DATA_AVAILABLE: //收到数据
              Uint8List data = (message['value'] as Uint8List);
              break;
          }
        }
      }
    };
  • 从0.0.5开始,可以使用 bleProxy 和 BleCallback2,无需再通过判断运行时的动态消息类型来区分蓝牙事件
  • bleProxy 用于调用蓝牙相关的方法,BleCallback2 用于接收蓝牙异步事件通知
class _CommPageState extends State<CommPage> with BleCallback2 {

  @override
  void initState() {
    super.initState();
    print('CommPage initState()');
    _deviceId = widget.device.deviceId;
    //连接设备
    bleProxy.connect(deviceId: _deviceId);

    //监听蓝牙异步事件通知
    bleProxy.addBleCallback(this);
  }
  
  @override
  void dispose() {
    print('CommPage -> dispose()');
    //取消监听蓝牙异步事件通知
    bleProxy.removeBleCallback(this);
    bleProxy.disconnect(deviceId: _deviceId); //断开连接
    super.dispose();
  }

  @override
  void onDataReceived(String deviceId, String serviceUuid, String characteristicUuid, Uint8List data) {
    //收到数据
    String utf8String = "";
    try {
      utf8String = utf8.decode(data);
    } on Exception catch (e) {
      print(e);
    }

    String hexString = data.toHex();

    print('<- utf8String=$utf8String, hexString=$hexString');
  }
  
  //可以按需实现 BleCallback2 的其它方法
  ...
}
  • 0.0.5版本新增一个内置的扫描页面,用于编写测试APP比较方便
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: ScanScreen(
        title: 'TTC Flutter BLE Demo',
        onDeviceClick: (BuildContext context, BLEDevice device) {
          Navigator.push(
              context,
              MaterialPageRoute(
                  builder: (context) => CommPage(device: device)));
        },
      ),
    );
  }
}