Flutter银行卡扫描插件ml_card_scanner的使用

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

Flutter银行卡扫描插件ml_card_scanner的使用

插件简介

ml_card_scanner 是一个用于扫描银行卡的Flutter插件,它能够识别银行卡的过期日期、卡类型和卡号。该插件支持横版和竖版银行卡,并且基于Google的机器学习模型,提供高性能和高准确率的扫描功能。此外,所有扫描过程都是完全离线进行的,确保了数据的安全性。

注意事项

  • 该插件不能保证100%准确地扫描卡信息,因此在使用扫描结果之前,请务必给用户提供检查和修改数据的机会。

准备工作

Android平台

  1. android/gradle.properties 文件中添加以下内容:

    android.useAndroidX=true
    android.enableJetifier=true
    
  2. android/app/build.gradle 文件中设置编译SDK版本和最小SDK版本:

    android {
      compileSdkVersion 31 // 至少为31
      minSdkVersion 21 // 至少为21
      ...
    }
    
  3. android/app/src/main/AndroidManifest.xml 文件中添加相机权限:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android">
      <uses-permission android:name="android.permission.CAMERA"/>
      ...
    </manifest>
    

iOS平台

  1. ios/Runner/Info.plist 文件中添加相机使用描述:

    <key>NSCameraUsageDescription</key>
    <string>您的描述</string>
    
  2. Podfile 文件的顶部添加以下内容:

    platform :ios, '10.0'
    
  3. Podfile 文件的末尾添加以下内容以启用相机权限:

    post_install do |installer|
      installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
          config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
            '$(inherited)',
            'PERMISSION_CAMERA=1',
          ]
        end
      end
    end
    

使用方法

基本用法

要使用 ml_card_scanner 插件,只需导入包并在代码中使用 ScannerWidget 即可:

ScannerWidget(controller: _controller)

ScannerWidget 提供了多个参数,您可以根据需要进行配置:

  • overlayBuilder:自定义覆盖层小部件或设置为 null 使用默认值。
  • overlayTextBuilder:自定义文本覆盖层小部件或设置为 null 使用默认值。
  • cameraPreviewBuilder:自定义相机预览约束或设置为 null 使用默认值。
  • scannerDelay:设置扫描延迟(毫秒),默认为400。
  • oneShotScanning:设置为 false 时,扫描将持续进行;设置为 true 时,检测到卡片后停止扫描。
  • overlayOrientation:设置默认覆盖层方向,默认为 portrait(竖屏)。
  • cameraResolution:设置相机分辨率,默认为 high(高)。
  • controllerScannerWidgetController,用于获取扫描的卡信息或错误。
  • cardScanTries:设置在提供扫描结果之前收集的识别变体数量。

示例代码

以下是一个完整的示例代码,展示了如何使用 ml_card_scanner 插件来扫描银行卡并显示扫描结果:

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:ml_card_scanner/ml_card_scanner.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MaterialApp(home: InitialScreen()));
}

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

  @override
  State<InitialScreen> createState() => _InitialScreenState();
}

class _InitialScreenState extends State<InitialScreen> {
  CardInfo? _cardInfo;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Card Scanner Demo'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          (_cardInfo != null)
              ? Expanded(
                  child: Center(
                    child: Container(
                      padding: const EdgeInsets.all(16),
                      width: MediaQuery.of(context).size.width - 32,
                      height: MediaQuery.of(context).size.width / 2,
                      decoration: const BoxDecoration(
                        color: Colors.blueGrey,
                        borderRadius: BorderRadius.all(
                          Radius.circular(16),
                        ),
                      ),
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.end,
                        children: [
                          Text(
                            _cardInfo?.numberFormatted() ?? '',
                            style: const TextStyle(
                              color: Colors.white,
                              fontSize: 24,
                              letterSpacing: 2,
                            ),
                          ),
                          const SizedBox(height: 32),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.start,
                            children: [
                              Expanded(
                                child: Text(
                                  _cardInfo?.expiry ?? '',
                                  style: const TextStyle(
                                    color: Colors.white,
                                    fontSize: 16,
                                    letterSpacing: 2,
                                  ),
                                ),
                              ),
                              Text(
                                _cardInfo?.type ?? '',
                                style: const TextStyle(
                                  color: Colors.white,
                                  fontSize: 16,
                                  letterSpacing: 2,
                                ),
                              ),
                            ],
                          ),
                        ],
                      ),
                    ),
                  ),
                )
              : const SizedBox.shrink(),
          const SizedBox(height: 16),
          Center(
            child: ElevatedButton(
              onPressed: _scanCard,
              child: const Text('Tap to Scan Card'),
            ),
          ),
          const SizedBox(height: 16),
        ],
      ),
    );
  }

  void _scanCard() async {
    setState(() {
      _cardInfo = null;
    });
    final result = await Navigator.of(context).push(
      MaterialPageRoute(
        builder: (context) {
          return const MainScreen();
        },
      ),
    ) as CardInfo?;
    if (result != null) {
      setState(() {
        _cardInfo = result;
      });
    }
  }
}

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

  @override
  State<MainScreen> createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> {
  final ScannerWidgetController _controller = ScannerWidgetController();

  @override
  void initState() {
    super.initState();
    _controller
      ..setCardListener(_onListenCard)
      ..setErrorListener(_onError);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ScannerWidget(
        controller: _controller,
        overlayOrientation: CardOrientation.landscape,
        cameraResolution: CameraResolution.high,
        oneShotScanning: true,
      ),
    );
  }

  @override
  void dispose() {
    _controller
      ..removeCardListeners(_onListenCard)
      ..removeErrorListener(_onError)
      ..dispose();
    super.dispose();
  }

  void _onListenCard(CardInfo? value) {
    if (value != null) {
      Navigator.of(context).pop(value);
    }
  }

  void _onError(ScannerException exception) {
    if (kDebugMode) {
      print('Error: ${exception.message}');
    }
  }
}

示例输出

扫描成功后,您将看到类似以下的输出:

Number card: 5173949390587465
Type: Master Card
Expiry: 10/24

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

1 回复

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


当然,以下是如何在Flutter项目中集成和使用ml_card_scanner插件来扫描银行卡的示例代码。ml_card_scanner是一个用于识别银行卡信息的Flutter插件,它依赖于机器学习技术来提取银行卡号、有效期、持卡人姓名等信息。

步骤 1: 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  ml_card_scanner: ^最新版本号  # 请替换为最新的版本号

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

步骤 2: 配置Android权限

由于扫描银行卡通常需要访问相机,你需要在AndroidManifest.xml文件中添加相机权限:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yourapp">

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" android:required="true" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

    <!-- 其他配置 -->

</manifest>

步骤 3: 使用ml_card_scanner插件

接下来,在你的Flutter代码中导入并使用ml_card_scanner插件。以下是一个简单的示例,展示如何启动银行卡扫描并处理结果:

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

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

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

class ScanCardScreen extends StatefulWidget {
  @override
  _ScanCardScreenState createState() => _ScanCardScreenState();
}

class _ScanCardScreenState extends State<ScanCardScreen> {
  CardRecognitionResult? _result;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('银行卡扫描'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            if (_result != null)
              Card(
                child: Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      Text('银行卡号: ${_result!.cardNumber}'),
                      Text('有效期: ${_result!.expiryDate}'),
                      Text('持卡人姓名: ${_result!.cardHolderName}'),
                    ],
                  ),
                ),
              ),
            ElevatedButton(
              onPressed: () async {
                final result = await MLCardScanner.scanCard(
                  context: context,
                  options: CardScannerOptions(
                    bezelColor: Colors.red,
                    scanAreaColor: Colors.blue.withOpacity(0.5),
                    bezelWidth: 20.0,
                    scanAreaHeight: 300.0,
                    scanAreaWidth: 400.0,
                  ),
                );

                setState(() {
                  _result = result;
                });
              },
              child: Text('扫描银行卡'),
            ),
          ],
        ),
      ),
    );
  }
}

解释

  1. 依赖添加:在pubspec.yaml中添加ml_card_scanner依赖。
  2. 权限配置:在AndroidManifest.xml中添加相机权限。
  3. UI界面:创建一个简单的UI界面,包含一个按钮用于启动银行卡扫描。
  4. 扫描功能:使用MLCardScanner.scanCard方法启动扫描,并在扫描完成后更新UI显示结果。

确保在实际项目中处理错误和异常,比如用户拒绝相机权限的情况。此外,根据实际需求调整UI和扫描选项。

回到顶部