Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Flutter中侦听流并只向DB写入一次_Flutter_Dart_Qr Code_Sqflite - Fatal编程技术网

在Flutter中侦听流并只向DB写入一次

在Flutter中侦听流并只向DB写入一次,flutter,dart,qr-code,sqflite,Flutter,Dart,Qr Code,Sqflite,我正在开发一个二维码阅读器应用程序,我使用一个外部二维码阅读器软件包()。 它侦听流并返回QR数据。但当我将数据写入sqlite数据库时,它会多次写入相同的数据,因为它不会停止侦听流。我不认为从流中取消订阅是个好主意,因为我从url启动或关闭对话框返回后仍然需要流来侦听。如果我错了,请纠正我,并提出解决方案,谢谢 void _onQRViewCreated(QRViewController controller) { this.controller = controller; c

我正在开发一个二维码阅读器应用程序,我使用一个外部二维码阅读器软件包()。 它侦听流并返回QR数据。但当我将数据写入sqlite数据库时,它会多次写入相同的数据,因为它不会停止侦听流。我不认为从流中取消订阅是个好主意,因为我从url启动或关闭对话框返回后仍然需要流来侦听。如果我错了,请纠正我,并提出解决方案,谢谢

void _onQRViewCreated(QRViewController controller) {
    this.controller = controller;
    controller.scannedDataStream.listen((scanData) async {
      
      setState(() {
        qrData = scanData;
      });
  
      if (await canLaunch(qrData)) {
        var status = await launch(qrData);

        if(status){
          final data = QrModel(
            content: scanData,
            date: DateFormat.yMMMd().add_jm().format(DateTime.now()),
          );
          await dbProvider.addData(data);
        }

      } else {

        if (!alertBoxOpen) {

          final data = QrModel(
            content: scanData,
            date: DateFormat.yMMMd().add_jm().format(DateTime.now()),
          );
          await dbProvider.addData(data);

          setState(() => alertBoxOpen = true);
          
          showDialog(
              context: context,
              builder: (context) {
                return AlertDialog(
                  content: Text(qrData),
                  actions: [
                    MaterialButton(
                        child: Text('OK',
                            style: TextStyle(
                                fontSize: 18.0, fontWeight: FontWeight.bold)),
                        onPressed: () {
                          setState(() => alertBoxOpen = false);
                          Navigator.of(context).pop();
                        }),
                  ],
                );
              });
        }
      }
    });
    
  }

您在流上有一个订阅,还是流发出多个相同的值?如果是后者,我建议你试试包装。它是用于Dart的ReactiveX的一个实现。我在反应式编程方面没有太多经验,但根据我的经验,当我使用rxdart中的
BehaviorSubject
时,它不会在向订阅方添加相同的值时通知订阅方。因此,您可以做的一件事是将QR流中的每个值添加到
行为主体
,然后订阅(侦听)行为主体以查询数据库。

我为此实现了一种解决方法。我将流返回的值
scanda
分配给变量
qrData
,如果
qrData!=斯堪的纳维亚半岛

void _onQRViewCreated(QRViewController controller) {
    this.controller = controller;

    controller.scannedDataStream.listen((scanData) async {
      if (await canLaunch(scanData)) {
        await launch(scanData);

        if (qrData != scanData) {
          setState(() {
            qrData = scanData;
          });
          final data = QrModel(
            content: scanData,
            date: DateFormat.yMMMd().add_jm().format(DateTime.now()),
          );
          await dbProvider.addData(data);
        }
      } else {
        if (!alertBoxOpen) {
          if (qrData != scanData) {
            setState(() {
              qrData = scanData;
            });
            final data = QrModel(
              content: scanData,
              date: DateFormat.yMMMd().add_jm().format(DateTime.now()),
            );
            await dbProvider.addData(data);
          }

          setState(() => alertBoxOpen = true);

          showDialog(
              context: context,
              builder: (context) {
                return AlertDialog(
                  content: Text(qrData),
                  actions: [
                    MaterialButton(
                        child: Text('OK',
                            style: TextStyle(
                                fontSize: 18.0, fontWeight: FontWeight.bold)),
                        onPressed: () {
                          setState(() => alertBoxOpen = false);
                          Navigator.of(context).pop();
                        }),
                  ],
                );
              });
        }
      }
    });
  }

由于我不熟悉rxdart,您能详细介绍一下如何实现这个解决方案吗?@Dulanka在阅读rxdart文档后,我找到了
distinct
方法。它的实现使用了Dart流的
distinct
方法。所以,您可能不需要rxdart。只需在流上调用
.distinct()
,然后再收听它。但只有当流发出多个相同的值时,这才有效。如果有多个订阅,则不会。谢谢您的努力!这个功能非常有用。但是用户不能再次扫描同一个QR,因为流不允许相等的值。@Dulanka用户应该能够在扫描不同的QR码后扫描相同的QR码。毕竟,你说过你不希望同一事件连续发生两次或两次以上。您确定只订阅一次吗?