You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Windows平台基于WebView实现二维码扫码功能的技术求助

Flutter Windows 基于WebView实现二维码扫码方案

1. 引入依赖

在项目的pubspec.yaml中添加WebView相关依赖:

dependencies:
  webview_flutter: ^4.4.0
  webview_flutter_windows: ^0.3.0

执行flutter pub get安装依赖。

2. 准备本地扫码资源

  1. 在项目根目录创建assets文件夹,放入两个文件:
    • 下载html5-qrcode.min.js(可从官方仓库获取源码打包,或直接下载已编译版本)
    • 创建qr_scan.html,内容如下:
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>QR Scanner</title>
    <script src="html5-qrcode.min.js"></script>
    <style>
        body { margin: 0; padding: 0; overflow: hidden; }
        #reader { width: 100vw; height: 100vh; }
    </style>
</head>
<body>
    <div id="reader"></div>
    <script>
        const scanner = new Html5Qrcode('reader');
        // 扫码成功回调
        const onScanSuccess = (text) => {
            // 将结果发送给Flutter
            window.flutter_inappwebview.callHandler('qrResult', text);
            // 停止扫码
            scanner.stop().catch(err => console.error(err));
        };
        // 扫码配置
        const scanConfig = {
            fps: 15, // 帧率
            qrbox: { width: 300, height: 300 }, // 扫码框大小
            aspectRatio: 1.0 // 宽高比
        };
        // 启动摄像头扫码
        scanner.start(
            { facingMode: "environment" }, // 使用后置摄像头
            scanConfig,
            onScanSuccess
        ).catch(err => {
            console.error('扫码启动失败:', err);
        });
    </script>
</body>
</html>
  1. 在pubspec.yaml中声明assets:
flutter:
  assets:
    - assets/qr_scan.html
    - assets/html5-qrcode.min.js

3. 实现Flutter侧的WebView页面

创建一个扫码页面,初始化WebView并处理扫码结果:

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_windows/webview_flutter_windows.dart';

class WebViewQrScanner extends StatefulWidget {
  const WebViewQrScanner({super.key});

  @override
  State<WebViewQrScanner> createState() => _WebViewQrScannerState();
}

class _WebViewQrScannerState extends State<WebViewQrScanner> {
  late WebViewController _webViewController;

  @override
  void initState() {
    super.initState();
    _initWebViewController();
  }

  void _initWebViewController() {
    _webViewController = WebViewController()
      // 开启JS支持
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      // 添加JS通道,接收WebView传来的扫码结果
      ..addJavaScriptChannel(
        'qrResult',
        onMessageReceived: (JavaScriptMessage message) {
          final result = message.message;
          if (result.isNotEmpty) {
            // 拿到结果后返回上一页,或者做其他处理
            Navigator.pop(context, result);
          }
        },
      )
      // 加载本地HTML页面
      ..loadFlutterAsset('assets/qr_scan.html');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('扫码'),
        leading: IconButton(
          icon: const Icon(Icons.close),
          onPressed: () => Navigator.pop(context),
        ),
      ),
      body: WebViewWidget(controller: _webViewController),
    );
  }
}

4. 配置Windows相机权限

Windows平台需要声明相机权限,否则无法访问摄像头:

  1. 打开项目的windows/runner/Runner.rc文件
  2. 在MANIFEST区块中添加摄像头权限声明:
MANIFEST
{
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
        <!-- 其他原有内容保留 -->
        <!-- 添加相机权限 -->
        <DeviceCapability Name="webcam"/>
    </assembly>
}

5. 调用扫码页面

在需要扫码的地方导航到这个WebView页面:

final qrResult = await Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => const WebViewQrScanner()),
);
if (qrResult != null) {
  // 处理扫码结果
  print('扫码结果: $qrResult');
}

常见问题处理

  • 摄像头无法启动:检查权限是否配置正确,确保设备摄像头可用,且系统已授予权限
  • 扫码灵敏度低:调整HTML中的fps(提高帧率)或qrbox(扩大扫码框)参数
  • WebView加载失败:检查assets路径是否正确,确保pubspec.yaml中已正确声明assets

内容的提问来源于stack exchange,提问作者Tuần

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 22:16:17