zoukankan      html  css  js  c++  java
  • flutter_blue 蓝牙插件实战及那些坑

    项目场景: 地下车库无网路的情况下需要使用蓝牙对小区门禁进行开门 

    本人掘金文章

    坑一: 安卓端引入flutter_blue运行项目报错

    1. 原因: 安卓sdk版本需要28以上

    2. 解决: android/build.gradle 下修改 compileSdkVersion  targetSdkVersion 为 28;  minSdkVersion 修改为19

    android {
    .............
        compileSdkVersion 28
    .............
        defaultConfig {
            minSdkVersion 19
            targetSdkVersion 28
        }
    .............
    }

    坑二: ios引入flutter_blue运行项目报错

    1. 原因: windows 创建的 flutter swift 语言, 而ios要的是 objc

    2. 解决: 新建空目录使用 flutter create -i objc my-flutter-app 创建新项目, 在把原项目下lib文件夹下的所有文件替换新创建的lib文件夹, 这就可以了;Androidios 端都没问题

    附上实际项目的源码; 其他的坑暂时就没想起来了,反正坑蛮多,初期运行时也是控制台各种报错

    需求简介:
    1. 执行完一次蓝牙开门之后,就断开连接蓝牙,以降低手机耗能;
    2. 20s扫码一次蓝牙,扫描时长为10s,以便根据距离搜索新的及强度高的蓝牙设备
    3. 初始化项目即执行一次蓝牙扫描
    import 'package:flutter_blue/flutter_blue.dart';
    FlutterBlue flutterBlue = FlutterBlue.instance;
    # // 蓝牙开门
    void _blueOpenDoor (Map list) async {
    var isFirstScan = true;
    var isConnect = false;
    _delayed?.cancel();
    # // 自定义loading
    cancel = BotToast.showCustomLoading(
      ignoreContentClick: true,
      toastBuilder: (cancelFunc) {
        return Loading();
      }
    );
    blueList.forEach((scanResult) async {
      # // if (scanResult.device.name == '201901012212') {
      if (scanResult.device.name == list["macAddress"]) {
        print('蓝牙设备门禁正在连接~~~~~~~~~');
        await scanResult.device.disconnect();
        await scanResult.device.connect();
        isConnect = true;
        print('蓝牙设备门禁连接成功~~~~~~~~~');
        # // List<BluetoothDevice> connectedDevices = await flutterBlue.connectedDevices;
        // if(connectedDevices.contains(scanResult.device)) {
        //   // TO DO
        // }
        List<BluetoothService> services = await scanResult.device.discoverServices();
        # //遍历蓝牙设备对列表
        services.forEach((service) async {
          if (service.uuid.toString().toUpperCase().substring(4, 8) == 'FFF0') {
            var characteristics = service.characteristics;
            for(BluetoothCharacteristic c in characteristics) {
              if (c.uuid.toString().toUpperCase().substring(4, 8) == 'FFF1') {
                # // 开门指令
                print('蓝牙设备门禁服务匹配成功~~~~~~~~~');
                await c.write([0x30, 0x10, 0x02, 0x03 ...........]);
                print('蓝牙设备门禁指令发送成功~~~~~~~~~');
                # // 开门声音
                cancel();
                _delayed?.cancel();
                showOpenDoorDialog(1, list['doorControlName']);
                await _audioPlayer.play("https://qinlin-resource.oss-cn-zhangjiakou.aliyuncs.com/wechat/opendoor.mp3");
                await scanResult.device.disconnect();
              }
               # // 监听门禁返回 并断开连接
               if (c.uuid.toString().toUpperCase().substring(4, 8) == 'FFF2') {
                 # // List<int> value = await c.read();
                 # // print('88888888888888888888888$value');
                 await c.setNotifyValue(true);
                 notifySubscription = c.value.listen((value) async {
                   print('88888888888888888888888$value');
                   cancel();
                   await scanResult.device.disconnect();
                   notifySubscription.cancel();
                 });
               }
            }
          }
        });
        # // 获取设备连接状态
        stateSubscription = scanResult.device.state.listen((s) async {
          print('连接状态连接状态$s');
          switch (s) {
            # // 蓝牙连接成功
            case BluetoothDeviceState.connected:
              isFirstScan = true;
              break;
            case BluetoothDeviceState.disconnected:
              if (!isFirstScan){
                cancel();
                _delayed?.cancel();
                print('蓝牙设备门禁连接失败~~~~~~~~~');
                BotToast.showText(
                  text: '蓝牙设备连接失败,请稍后再试', 
                  align: Alignment(0, 0.1),
                  onlyOne: true, 
                  duration: Duration(milliseconds: 2000),
                  contentPadding: const EdgeInsets.all(15.0),
                ); 
              }
              break;
            default:
              cancel();
              _delayed?.cancel();
              print('蓝牙设备门禁连接失败~~~~~~~~~');
              BotToast.showText(
                text: '蓝牙设备连接失败,请稍后再试', 
                align: Alignment(0, 0.1),
                onlyOne: true, 
                duration: Duration(milliseconds: 2000),
                contentPadding: const EdgeInsets.all(15.0),
              ); 
              break;
          }
        });
      }
    });
    _delayed = Timer.periodic(new Duration(seconds: 15), (timer) {
      cancel();
      if (!isConnect) {
        BotToast.showText(
          text: '该门禁蓝牙信号较弱,请稍后再试', 
          align: Alignment(0, 0.1),
          onlyOne: true, 
          duration: Duration(milliseconds: 2000),
          contentPadding: const EdgeInsets.all(15.0),
        ); 
      }
      _delayed?.cancel();
    });
    
    }
    # // 15s 定时扫描蓝牙
    Future<dynamic> _scanBlue () async {
    flutterBlue.state.listen((s) {
      if (s == BluetoothState.on) {
        setState(() {
          _isOpenBlue = true;
        });
        FlutterBlue.instance.stopScan();
        # // 立即执行一次
        _initScan();
        _timer = Timer.periodic(new Duration(seconds: 20), (timer) {
          setState(() {
            blueList = [];
          });
          scanSubscription = flutterBlue.scan().listen((scanResult) async {
            if (!blueList.contains(scanResult)) {
              setState(() {
                blueList.add(scanResult);
              });
            }
          });
          Future.delayed(Duration(seconds: 10), () {
            FlutterBlue.instance.stopScan();
            scanSubscription?.cancel();
          });
        });
      } else {
        _timer?.cancel();
        if (!_isOpenBlue) {
          final snackBar = new SnackBar(
            content: new Text('如需要蓝牙开门,请先前往手机设置开启蓝牙'),
            backgroundColor: Colors.red,
            duration: Duration(seconds: 3),
            action: SnackBarAction(
              textColor: Colors.white,
              label: '关闭',
              onPressed: () {},
            ),
          );
          _scaffoldkey.currentState.showSnackBar(snackBar);
        }
      }
    });
    }
    # // 初始执行扫描
    void _initScan () {
    setState(() {
      blueList = [];
    });
    scanSubscription = flutterBlue.scan().listen((scanResult) async {
      if (!blueList.contains(scanResult)) {
        setState(() {
          blueList.add(scanResult);
        });
      }
    });
    Future.delayed(Duration(seconds: 10), () {
      FlutterBlue.instance.stopScan();
      scanSubscription?.cancel();
    });
    }
    有问题欢迎留言
  • 相关阅读:
    IDEA 2019.3 最新激活教程,有效期到 2089 年!
    【猫狗数据集】读取数据集的第二种方式
    【猫狗数据集】计算数据集的平均值和方差
    【colab pytorch】其它注意事项
    【colab pytorch】训练和测试常用模板代码
    【colab pytorch】数据预处理
    【colab pytorch】提取模型中的某一层
    【colab pytorch】模型权重初始化
    【猫狗数据集】使用预训练的resnet18模型
    【猫狗数据集】使用top1和top5准确率衡量模型
  • 原文地址:https://www.cnblogs.com/ljx20180807/p/12200503.html
Copyright © 2011-2022 走看看