Flutter二维码扫描插件qrscan的使用

发布于 1周前 作者 yibo5220 来自 Flutter

Flutter二维码扫描插件qrscan的使用

简介

qrscan 是一个Flutter插件,用于扫描和生成二维码。它支持Android平台,并且可以解析条形码和二维码,同时具备闪光灯控制、权限申请等功能。

  • GitHub: github
  • License: MIT License License

权限配置

AndroidManifest.xml中添加以下权限:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

安装

pubspec.yaml文件中添加依赖:

dependencies:
  qrscan: ^0.3.3

使用示例

基本用法

扫描二维码或条形码

import 'package:qrscan/qrscan.dart' as scanner;

String cameraScanResult = await scanner.scan();

解析图片中的二维码或条形码

String photoScanResult = await scanner.scanPhoto();

根据指定路径解析图片中的二维码或条形码

String barcode = await scanner.scanPath(path);

根据字节数组解析二维码或条形码

Uint8List bytes = file.readAsBytesSync();
String barcode = await scanner.scanBytes(bytes);

生成二维码

Uint8List result = await scanner.generateBarCode('https://github.com/leyan95/qrcode_scanner');

完整示例Demo

下面是一个完整的Flutter应用程序,展示了如何使用qrscan插件进行二维码的扫描与生成。

import 'dart:async';
import 'dart:io';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:qrscan/qrscan.dart' as scanner;

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Uint8List bytes = Uint8List(0);
  TextEditingController _inputController;
  TextEditingController _outputController;

  @override
  initState() {
    super.initState();
    this._inputController = new TextEditingController();
    this._outputController = new TextEditingController();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.grey[300],
        body: Builder(
          builder: (BuildContext context) {
            return ListView(
              children: <Widget>[
                _qrCodeWidget(this.bytes, context),
                Container(
                  color: Colors.white,
                  child: Column(
                    children: <Widget>[
                      TextField(
                        controller: this._inputController,
                        keyboardType: TextInputType.url,
                        textInputAction: TextInputAction.go,
                        onSubmitted: (value) => _generateBarCode(value),
                        decoration: InputDecoration(
                          prefixIcon: Icon(Icons.text_fields),
                          helperText:
                              'Please input your code to generate qrcode image.',
                          hintText: 'Please Input Your Code',
                          hintStyle: TextStyle(fontSize: 15),
                          contentPadding:
                              EdgeInsets.symmetric(horizontal: 7, vertical: 15),
                        ),
                      ),
                      SizedBox(height: 20),
                      TextField(
                        controller: this._outputController,
                        maxLines: 2,
                        decoration: InputDecoration(
                          prefixIcon: Icon(Icons.wrap_text),
                          helperText:
                              'The barcode or qrcode you scan will be displayed in this area.',
                          hintText:
                              'The barcode or qrcode you scan will be displayed in this area.',
                          hintStyle: TextStyle(fontSize: 15),
                          contentPadding:
                              EdgeInsets.symmetric(horizontal: 7, vertical: 15),
                        ),
                      ),
                      SizedBox(height: 20),
                      this._buttonGroup(),
                      SizedBox(height: 70),
                    ],
                  ),
                ),
              ],
            );
          },
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () => _scanBytes(),
          tooltip: 'Take a Photo',
          child: const Icon(Icons.camera_alt),
        ),
      ),
    );
  }

  Widget _qrCodeWidget(Uint8List bytes, BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(20),
      child: Card(
        elevation: 6,
        child: Column(
          children: <Widget>[
            Container(
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.end,
                children: <Widget>[
                  Icon(Icons.verified_user, size: 18, color: Colors.green),
                  Text('  Generate Qrcode', style: TextStyle(fontSize: 15)),
                  Spacer(),
                  Icon(Icons.more_vert, size: 18, color: Colors.black54),
                ],
              ),
              padding: EdgeInsets.symmetric(horizontal: 10, vertical: 9),
              decoration: BoxDecoration(
                color: Colors.black12,
                borderRadius: BorderRadius.only(
                    topLeft: Radius.circular(4), topRight: Radius.circular(4)),
              ),
            ),
            Padding(
              padding:
                  EdgeInsets.only(left: 40, right: 40, top: 30, bottom: 10),
              child: Column(
                children: <Widget>[
                  SizedBox(
                    height: 190,
                    child: bytes.isEmpty
                        ? Center(
                            child: Text('Empty code ... ',
                                style: TextStyle(color: Colors.black38)),
                          )
                        : Image.memory(bytes),
                  ),
                  Padding(
                    padding: EdgeInsets.only(top: 7, left: 25, right: 25),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: <Widget>[
                        Expanded(
                          flex: 5,
                          child: GestureDetector(
                            child: Text(
                              'remove',
                              style:
                                  TextStyle(fontSize: 15, color: Colors.blue),
                              textAlign: TextAlign.left,
                            ),
                            onTap: () =>
                                this.setState(() => this.bytes = Uint8List(0)),
                          ),
                        ),
                        Text('|',
                            style:
                                TextStyle(fontSize: 15, color: Colors.black26)),
                        Expanded(
                          flex: 5,
                          child: GestureDetector(
                            onTap: () async {
                              final success =
                                  await ImageGallerySaver.saveImage(this.bytes);
                              SnackBar snackBar;
                              if (success) {
                                snackBar = new SnackBar(
                                    content: new Text('Successful Preservation!'));
                                Scaffold.of(context).showSnackBar(snackBar);
                              } else {
                                snackBar = new SnackBar(
                                    content: new Text('Save failed!'));
                              }
                            },
                            child: Text(
                              'save',
                              style:
                                  TextStyle(fontSize: 15, color: Colors.blue),
                              textAlign: TextAlign.right,
                            ),
                          ),
                        ),
                      ],
                    ),
                  )
                ],
              ),
            ),
            Divider(height: 2, color: Colors.black26),
            Container(
              child: Row(
                children: <Widget>[
                  Icon(Icons.history, size: 16, color: Colors.black38),
                  Text('  Generate History',
                      style: TextStyle(fontSize: 14, color: Colors.black38)),
                  Spacer(),
                  Icon(Icons.chevron_right, size: 16, color: Colors.black38),
                ],
              ),
              padding: EdgeInsets.symmetric(horizontal: 10, vertical: 9),
            )
          ],
        ),
      ),
    );
  }

  Widget _buttonGroup() {
    return Row(
      children: <Widget>[
        Expanded(
          flex: 1,
          child: SizedBox(
            height: 120,
            child: InkWell(
              onTap: () => _generateBarCode(this._inputController.text),
              child: Card(
                child: Column(
                  children: <Widget>[
                    Expanded(
                      flex: 2,
                      child: Image.asset('images/generate_qrcode.png'),
                    ),
                    Divider(height: 20),
                    Expanded(flex: 1, child: Text("Generate")),
                  ],
                ),
              ),
            ),
          ),
        ),
        Expanded(
          flex: 1,
          child: SizedBox(
            height: 120,
            child: InkWell(
              onTap: _scan,
              child: Card(
                child: Column(
                  children: <Widget>[
                    Expanded(
                      flex: 2,
                      child: Image.asset('images/scanner.png'),
                    ),
                    Divider(height: 20),
                    Expanded(flex: 1, child: Text("Scan")),
                  ],
                ),
              ),
            ),
          ),
        ),
        Expanded(
          flex: 1,
          child: SizedBox(
            height: 120,
            child: InkWell(
              onTap: _scanPhoto,
              child: Card(
                child: Column(
                  children: <Widget>[
                    Expanded(
                      flex: 2,
                      child: Image.asset('images/albums.png'),
                    ),
                    Divider(height: 20),
                    Expanded(flex: 1, child: Text("Scan Photo")),
                  ],
                ),
              ),
            ),
          ),
        ),
      ],
    );
  }

  Future _scan() async {
    await Permission.camera.request();
    String barcode = await scanner.scan();
    if (barcode == null) {
      print('nothing return.');
    } else {
      this._outputController.text = barcode;
    }
  }

  Future _scanPhoto() async {
    await Permission.storage.request();
    String barcode = await scanner.scanPhoto();
    this._outputController.text = barcode;
  }

  Future _scanPath(String path) async {
    await Permission.storage.request();
    String barcode = await scanner.scanPath(path);
    this._outputController.text = barcode;
  }

  Future _scanBytes() async {
    File file = await ImagePicker().getImage(source: ImageSource.camera).then((picked) {
      if (picked == null) return null;
      return File(picked.path);
    });
    if (file == null) return;
    Uint8List bytes = file.readAsBytesSync();
    String barcode = await scanner.scanBytes(bytes);
    this._outputController.text = barcode;
  }

  Future _generateBarCode(String inputCode) async {
    Uint8List result = await scanner.generateBarCode(inputCode);
    this.setState(() => this.bytes = result);
  }
}

支持的功能

  • ✅ 扫描条形码
  • ✅ 扫描二维码
  • ✅ 控制闪光灯
  • ✅ 申请相机权限
  • ✅ 从相册中选择条形码或二维码图片进行解析
  • ✅ 根据字节数组解析二维码或条形码
  • ✅ 根据指定路径解析图片中的二维码或条形码
  • ✅ 根据光线强度显示闪光灯开关按钮
  • ✅ 生成二维码

待办事项

  • [] 支持iOS (example builds, but invoking scanner does not return)
  • [] 提供iOS设置文档(如果需要)

许可证

分布式许可为MIT许可证。详情参见LICENSE

关于

创建者:Shusheng

致谢

特别感谢JetBrains提供的开源免费许可证!


更多关于Flutter二维码扫描插件qrscan的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter二维码扫描插件qrscan的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用qrscan插件进行二维码扫描的一个示例。请注意,qrscan插件可能不是Flutter社区中最常用或最新的二维码扫描插件,因此我会使用更广泛认可的qr_code_scanner插件作为替代,因为它具有更好的支持和功能。不过,如果你特别需要qrscan插件的代码,请告知,但基于其文档和社区支持情况,我建议使用qr_code_scanner

使用 qr_code_scanner 插件进行二维码扫描

  1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  qr_code_scanner: ^0.5.4  # 请检查最新版本号

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

  1. 创建扫描页面

接下来,创建一个新的Flutter页面来处理二维码扫描。这里是一个简单的示例:

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

class QRScannerPage extends StatefulWidget {
  @override
  _QRScannerPageState createState() => _QRScannerPageState();
}

class _QRScannerPageState extends State<QRScannerPage> {
  final BarcodeDetector? barcodeDetector = FlutterBarcodeScanner.barcodeDetector;
  final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
  QRViewController? controller;

  // 在这里处理扫描结果
  void _onQRViewCreated(QRViewController qrViewController) {
    this.controller = qrViewController;
    qrViewController.scannedDataStream.listen((scanResult) {
      // 处理扫描到的二维码数据
      setState(() {
        print("Scanned Data: ${scanResult.code}");
      });
      // 你可以在这里添加导航逻辑,比如跳转到另一个页面
      // Navigator.pushNamed(context, '/result', arguments: scanResult.code);
    });
  }

  @override
  Widget build(BuildContext context) {
    // 创建一个QRView
    return Scaffold(
      appBar: AppBar(
        title: Text('二维码扫描'),
      ),
      body: Column(
        children: <Widget>[
          Expanded(
            flex: 4,
            child: QRView(
              key: qrKey,
              onQRViewCreated: _onQRViewCreated,
              reader: barcodeDetector,
            ),
          ),
          Expanded(
            flex: 1,
            child: Center(
              child: Text(
                '扫描二维码...',
                style: TextStyle(fontSize: 24),
              ),
            ),
          ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    controller?.dispose();
    super.dispose();
  }
}
  1. 导航到扫描页面

在你的主应用页面或其他地方添加导航逻辑,以便用户可以访问这个扫描页面:

import 'package:flutter/material.dart';
import 'qr_scanner_page.dart';  // 假设你的文件名是qr_scanner_page.dart

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter二维码扫描示例'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => QRScannerPage()),
              );
            },
            child: Text('扫描二维码'),
          ),
        ),
      ),
    );
  }
}

这个示例展示了如何使用qr_code_scanner插件在Flutter应用中实现二维码扫描功能。请确保你已经在AndroidManifest.xmlInfo.plist中添加了必要的相机权限。如果你确实需要使用qrscan插件,并且需要具体的代码示例,请告知,但通常建议使用更广泛支持的插件。

回到顶部