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

gmschurch_qr_mobile_vision 插件简介

pub package

说明: 使用 Firebase 的 MLKit 进行二维码和其他条形码的读取。

该插件通过 Android 和 iOS 原生 API 从设备的相机获取图像,并将这些图像传递给 MLKit Vision 条形码 API,用于检测条形码/二维码等。同时,它还会输出一个预览图像到 Flutter 的纹理中。

插件包含了一个小部件,该小部件对相机输出执行所有必要的转换,以便在定义的区域内显示。


Android 模型

在新的 MLKit 版本中,有两种不同的模型可以用于条形码扫描。目前,该插件选择使用内置模型。这会增加大约 2.2 MB 的代码大小,但会提高扫描性能,并且不需要后台下载额外的包来正确运行条形码扫描功能。

你也可以使用 Google Play 服务并告诉你的应用在安装时从 Play 商店下载它。以下是 Android 的 MLKit 条形码扫描文档页面的说明链接:

configurations.all {
    exclude group: "com.google.mlkit", module:"barcode-scanning"
}
// ...
dependencies {
  // ...
  // 使用此依赖项以使用 Google Play 服务动态下载的模型
  implementation 'com.google.android.gms:play-services-mlkit-barcode-scanning:16.1.4'
}

注意:如果你这样做,请确保按照上述文档中的说明告诉您的应用程序自动下载模型。


iOS 平台仅支持 64 位架构

不幸的是,Google 只发布了 64 位二进制文件的 MLKit。这意味着该插件以及您的应用程序不支持在 32 位设备上构建或运行。处理这个问题有两种可能的方法,但只有一种方法能让大多数用户轻松使用插件。

如果您升级后仍然需要支持 iOS 11 之前的版本,您可能会在 pod install 期间看到警告,并且您的应用程序可能无法构建(至少在发布模式下)。这是因为系统试图构建 32 位版本,而找不到所需的文件。

解决方法:

  1. 在您的 Podfile 中添加以下行:

    platform :ios, '11.0'
  2. (可选)确保您的 Podfile 设置为 11 或更高版本。如果在 Podfile 文件底部看到以下内容,请确保设置部署目标为 11:

    post_install do |installer|
        installer.pods_project.targets.each do |target|
            target.build_configurations.each do |config|
                config.build_settings['ENABLE_BITCODE'] = 'NO'
                config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
            end
        end
    end
  3. 在 Xcode 中将“iOS 部署目标”设置为 11:

    • 打开 Xcode。
    • 导航到项目设置 -> Runner -> Build Settings -> Deployment -> iOS Deployment Target。
    • 将其设置为 11。

使用方法

要使用该插件,请查看示例代码,这是最佳资源,因为它展示了插件的实际用法。以下是使用插件的基本步骤:

1. 确定相机预览显示的区域

重要的是,预览需要一个固定大小,否则它将无法构建。这是因为为了在 iOS 和 Android 上正确显示相机预览,同时支持屏幕旋转等复杂情况,需要进行复杂的变换。

推荐的方式是将相机预览放在 SizedBoxContainer 中。

2. 包含插件并实例化相机

import 'package:gmschurch_qr_mobile_vision/qr_camera.dart';

...

SizedBox(
  width: 300.0,
  height: 600.0,
  child: QrCamera(
    qrCodeCallback: (code) {
      // 处理扫描到的二维码
      print("Scanned Code: $code");
    },
  ),
)

QrCodeCallback 可以做任何你想做的事情,并且会持续接收二维码,直到相机停止。

3. 可选参数

fit

参数接受 BoxFit 类型。将其设置为不同的值可以让预览图像以不同方式适应,但只有 BoxFit = cover 被广泛测试过。

notStartedBuilder

如果定义了该回调,则必须返回一个 Widget。它应该构建在相机加载时(可能需要几毫秒到几秒钟,具体取决于设备)显示的内容。

child

这是一个显示在 QrCamera 上的子部件。如果为其指定特定大小,可能会导致奇怪的问题,因此尽量避免这样做。

key

标准的 Flutter Key 参数。可以用来通过 GlobalKey 获取 QrCameraState。

cameraDirection

指定要使用的相机方向,默认为 BACK

支持的类型:

FRONT,
BACK

offscreenBuilder

如果定义了该回调,则必须返回一个 Widget。它应该构建当相机视图“离线”时显示的内容,例如应用程序暂停时。可能不会在应用程序预览中显示。

onError

错误回调。当发生错误时调用。

formats

支持的格式列表,默认情况下支持所有格式。如果使用所有格式,则不应定义其他格式。

支持的类型:

ALL_FORMATS,
AZTEC,
CODE_128,
CODE_39,
CODE_93,
CODABAR,
DATA_MATRIX,
EAN_13,
EAN_8,
ITF,
PDF417,
QR_CODE,
UPC_A,
UPC_E

direction

指定要使用前置还是后置摄像头。


开关闪光灯

当相机正在运行时,您可以使用 QrCamera.toggleFlash()QrMobileVision.toggleFlash() 方法打开或关闭闪光灯。更好的解决方案正在开发中,但目前无法承诺完成的时间。


推入和弹出

如果您使用导航器将新部件推送到当前页面之上,相机不一定知道这一点。


示例代码

以下是完整的示例代码,展示了如何使用插件:

import 'package:flutter/material.dart';
import 'package:gmschurch_qr_mobile_vision/qr_camera.dart';

void main() {
  runApp(const HomePage());
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  [@override](/user/override)
  HomeState createState() => HomeState();
}

class HomeState extends State<HomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(home: MyApp());
  }
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  MyAppState createState() => MyAppState();
}

class MyAppState extends State<MyApp> {
  String? qr;
  bool camState = false;
  bool dirState = false;

  [@override](/user/override)
  void initState() {
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Plugin example app'),
        actions: [
          IconButton(
            icon: const Icon(Icons.light),
            onPressed: _swapBackLightState,
          ),
        ],
      ),
      body: Center(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                const Text("Back"),
                Switch(
                  value: dirState,
                  onChanged: (val) => setState(() => dirState = val),
                ),
                const Text("Front"),
              ],
            ),
            Expanded(
              child: camState
                  ? Center(
                      child: SizedBox(
                        width: 300.0,
                        height: 600.0,
                        child: QrCamera(
                          onError: (context, error) => Text(
                            error.toString(),
                            style: const TextStyle(color: Colors.red),
                          ),
                          cameraDirection:
                              dirState ? CameraDirection.FRONT : CameraDirection.BACK,
                          qrCodeCallback: (code) {
                            setState(() {
                              qr = code;
                            });
                          },
                          child: Container(
                            decoration: BoxDecoration(
                              color: Colors.transparent,
                              border: Border.all(
                                color: Colors.orange,
                                width: 10.0,
                                style: BorderStyle.solid,
                              ),
                            ),
                          ),
                        ),
                      ),
                    )
                  : const Center(child: Text("Camera inactive")),
            ),
            Text("QRCODE: $qr"),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: const Text("on/off"),
        onPressed: () {
          setState(() {
            camState = !camState;
          });
        },
      ),
    );
  }

  _swapBackLightState() async {
    await QrCamera.toggleFlash();
  }
}
1 回复

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


gmschurch_qr_mobile_vision 是一个用于 Flutter 的二维码扫描插件,它基于 Google 的 Mobile Vision API 实现。这个插件允许你在 Flutter 应用中集成二维码扫描功能。以下是如何使用 gmschurch_qr_mobile_vision 插件的步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 gmschurch_qr_mobile_vision 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  gmschurch_qr_mobile_vision: ^1.0.0

然后运行 flutter pub get 来获取依赖。

2. 配置 Android 和 iOS 项目

Android

android/app/build.gradle 文件中,确保 minSdkVersion 至少为 21:

android {
    defaultConfig {
        minSdkVersion 21
        ...
    }
    ...
}

iOS

ios/Podfile 中,确保 platform 设置为 10.0 或更高版本:

platform :ios, '10.0'

然后运行 pod install 来更新 iOS 项目。

3. 使用插件进行二维码扫描

在你的 Flutter 代码中,你可以使用 gmschurch_qr_mobile_vision 插件来启动二维码扫描并获取扫描结果。

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: QRScannerScreen(),
    );
  }
}

class QRScannerScreen extends StatefulWidget {
  @override
  _QRScannerScreenState createState() => _QRScannerScreenState();
}

class _QRScannerScreenState extends State<QRScannerScreen> {
  String _scanResult = 'Scan a QR Code';

  Future<void> _scanQR() async {
    try {
      String? qrResult = await GmschurchQrMobileVision.scan();
      if (qrResult != null) {
        setState(() {
          _scanResult = qrResult;
        });
      }
    } catch (e) {
      setState(() {
        _scanResult = 'Failed to scan QR Code: $e';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('QR Scanner'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              _scanResult,
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _scanQR,
              child: Text('Scan QR Code'),
            ),
          ],
        ),
      ),
    );
  }
}

4. 运行应用

现在你可以运行你的 Flutter 应用,点击“Scan QR Code”按钮来启动二维码扫描。扫描结果将会显示在屏幕上。

5. 处理权限

在 Android 和 iOS 上,你需要在 AndroidManifest.xmlInfo.plist 文件中添加相机权限。

Android

android/app/src/main/AndroidManifest.xml 中添加以下权限:

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

iOS

ios/Runner/Info.plist 中添加以下权限:

<key>NSCameraUsageDescription</key>
<string>We need access to your camera to scan QR codes.</string>

6. 处理错误和异常

在实际应用中,你可能会遇到各种错误和异常,例如用户拒绝授予相机权限、设备不支持二维码扫描等。你需要在代码中妥善处理这些情况,以提供更好的用户体验。

7. 自定义扫描界面

gmschurch_qr_mobile_vision 插件允许你自定义扫描界面的外观和行为。你可以通过传递参数来调整扫描框的大小、颜色等。

String? qrResult = await GmschurchQrMobileVision.scan(
  formats: [BarcodeFormat.qrCode],
  autoFocus: true,
  flash: false,
  multiple: false,
);
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!