Flutter扫描二维码功能开发

2019/7/30 posted in  Flutter

今天用Flutter开发扫描二维码功能,发现还是有一些坑的,整理记录一下采坑过程。

barcode_scan安装

Android设置

  1. Android相机权限许可设置
    AndroidManifest.xml 下添加权限许可和activity

    <!-- 权限许可 -->
    <uses-permission android:name="android.permission.CAMERA" />
    <!-- 添加扫描二维码的activity -->
    <activity android:name="com.apptreesoftware.barcodescan.BarcodeScannerActivity"/>
  1. 编辑android/build.gradle文件,添加如下代码

    buildscript {
        ext.kotlin_version = '1.3.41'
    ...
    dependencies {
    ...
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
    }
    ...
  2. 编辑android/app/build.gradle文件,添加如下代码

    ...
    dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    ...
    }

iOS设置

ios/Runner/info.plist文件中添加相机权限设置

<key>NSCameraUsageDescription</key>
<string>Camera permission is required for barcode scanning.</string>

安装插件

pubspec.yaml文件中添加插件

dependencies:
  ...
  barcode_scan: any

然后点击右上角的Packages get按钮进行安装。

barcode_scan使用

因为我是用的Fish Redux框架,所以是在effect中调用,整体代码如下:

import 'package:fish_redux/fish_redux.dart';
import 'action.dart';
import 'state.dart';
import 'package:barcode_scan/barcode_scan.dart';
import 'package:flutter/services.dart';

Effect<ScanState> buildEffect() {
  return combineEffects(<Object, Effect<ScanState>>{
    Lifecycle.initState: _onScan,
  });
}

void _onScan(Action action, Context<ScanState> ctx) async {
  try {
    String barcode = await BarcodeScanner.scan();
    // 回调扫描结果
    ctx.dispatch(ScanActionCreator.didScan(null, barcode));
  } on PlatformException catch (e) {
    if (e.code == BarcodeScanner.CameraAccessDenied) {
      // 回调错误信息
      ctx.dispatch(ScanActionCreator.didScan("The user did not grant the camera permission!", null));
    } else {
      // 回调错误信息
      ctx.dispatch(ScanActionCreator.didScan("Unknown error: $e", null));
    }
  } on FormatException {
    // 回调错误信息
    ctx.dispatch(ScanActionCreator.didScan("null (User returned using the back-button before scanning anything. Result)", null));
  } catch (e) {
    // 回调错误信息
    ctx.dispatch(ScanActionCreator.didScan("Unknown error: $e", null));
  }
}

ScanActionCreator的定义如下:

class ScanActionCreator {

  static Action didScan(String error, String code) {
    return Action(ScanAction.didScan, payload: {"error": error, "code": code});
  }
}

遇到的错误

  1. 遇到下图的问题是因为没有添加权限设置,按照前面的方法设置就可以了。

  2. error: unexpected element <activity> found in <manifest>
    错误原因是设置Android权限的时候没有吧activity放到application下面。

    <application>
    ...
    <!-- 扫描二维码 -->
    <activity android:name="com.apptreesoftware.barcodescan.BarcodeScannerActivity"/>
    </application>
    <!-- 权限许可 -->
    <uses-permission android:name="android.permission.CAMERA" />
  3. 点击扫描崩溃,报如下错误

    android.content.ActivityNotFoundException: Unable to find explicit activity class {com.met.metchain2/com.apptreesoftware.barcodescan.BarcodeScannerActivity}; have you declared this activity in your AndroidManifest.xml?
    

    解决办法: 删除android/.gradle文件夹,重新运行即可。