首页 > 解决方案 > 停止收听流

问题描述

该程序在第一次构建时运行良好。当我断开设备并重新连接时,它显示状态不佳:流已被监听,可能是由监听蓝牙特性的流产生错误。解决方法是什么?

    import 'dart:async';
    import 'dart:convert';
    import 'package:flutter/material.dart';
    import 'package:flutter_blue/flutter_blue.dart';
    import 'package:vibration/vibration.dart';

    StreamSubscription _scanSubscription;
    StreamSubscription _deviceConnection;

    Stream<List<int>> stream;
    List<double> traceDust = List();

    const String CHAR_UUID = "AA:48:F8:CC:07:12";
    const String Device_Name = "myDevice";
    const String CHARACTERISTIC_UUID = "00000000-0111-1000-4000-000000000000";

    BluetoothDeviceState _state;
    Map<DeviceIdentifier, ScanResult> scanResults = new Map();
    List<BluetoothService> services = new List();
    BluetoothCharacteristic characteristic;

    FlutterBlue flutterBlue = FlutterBlue.instance;

    BluetoothDevice device;

    class SearchScreen extends StatefulWidget {
      @override
      _SearchScreenState createState() => _SearchScreenState();
    }

    class _SearchScreenState extends State<SearchScreen> {
      @override
      void initState() {
        super.initState();
        _startScan();
      }

      @override
      void dispose() {
        super.dispose();
        _stopScan();
        _deviceConnection?.cancel();
        _deviceConnection = null;
        device.disconnect();
      }

      _startScan() {
        _scanSubscription =
            flutterBlue.scan(timeout: Duration(seconds: 4)).listen((scanResult) {
          if (CHAR_UUID == scanResult.device.id.toString()) {
            _stopScan();
            _connect(scanResult.device);
            print('connected');
          }
        }, onDone: _stopScan());
      }

      _stopScan() {
        _scanSubscription?.cancel();
        _scanSubscription = null;
      }

      _connect(BluetoothDevice d) async {
        device = d;
        await device.connect(autoConnect: true);
        await device.discoverServices().then((value) {
          setState(() {
            services = value;
          });
        });
        _turnOnCharacterService(services);
      }

      _turnOnCharacterService(List<BluetoothService> ser) async {
        ser.forEach((service) {
          service.characteristics.forEach((character) {
            if (character.uuid.toString() == CHARACTERISTIC_UUID) {
              character.setNotifyValue(!character.isNotifying);
              setState(() {
                stream = character.value;
              });
            }
          });
        });
      }

      String _dataParser(List<int> dataFromDevice) {
        return utf8.decode(dataFromDevice);
      }

      vibrateOnAlert() async {
        if (await Vibration.hasVibrator()) {
          Vibration.vibrate(duration: 1000);
        }
      }



     @override
      Widget build(BuildContext context) {
        return Container(
            child: StreamBuilder<BluetoothDeviceState>(
          stream: device.state,
          initialData: BluetoothDeviceState.connecting,
          builder: (context, snapshot) {
            if (snapshot.data == BluetoothDeviceState.connected) {
              return StreamBuilder<List<int>>(
                  stream: stream,
                  builder: (context, snapshot) {
                    var currentValue;
                    if (snapshot.hasError) {
                      return Text('Error');
                    }
                    if (snapshot.connectionState == ConnectionState.active) {
                      currentValue = _dataParser(snapshot.data);
                      traceDust.add(double.tryParse(currentValue) ?? 0);
                      if (currentValue.toString().compareTo('vibrate') == 0) {
                        vibrateOnAlert();
                      }
                    } else {
                      return Text('disconnected');
                    }
                    print('$currentValue');

                    return Text('connected');
                  });
            }
            return FlatButton(
              color: Colors.white,
              child: Text('reconnecct'),
              onPressed: () {
                setState(() {
                  flutterBlue.startScan(timeout: Duration(seconds: 2));
                });
              },
            );
          },
        ));
      }
    }

PS:这里的平面按钮什么都不做。由于连接状态是一个流构建器,它会自动重新连接并显示错误。

标签: flutterbluetoothstream-builder

解决方案


推荐阅读