FlutterでQRコードやバーコードを読み取る方法
このブログは、「Challenge! スマホアプリ勉強会Vol.3」で作成予定のアプリについての解説ページです。
QRコードやバーコードの読み取りを行うアプリをFlutterで作る方法について解説します。
今回利用するパッケージ
今回は、barcode_scan 1.0.0というパッケージを使ってQRコードの読み取りを実現します。
pub.dev
QRコード以外にもバーコードの読み取りも可能にしているようです。
準備
まず、Androidおよびiphoneのアプリ内でカメラのパーミッションを許可するコードを書きます。
Android側
android/app/src/main/AndroidMainifest.xmlを以下のように編集します。2つの記述を追加するだけです。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.third_app"> <!-- 次の記述を追加する --> <uses-permission android:name="android.permission.CAMERA" /> <!-- 英語のコメント --> <application android:name="io.flutter.app.FlutterApplication" android:label="third_app" android:icon="@mipmap/ic_launcher"> <activity android:name=".MainActivity" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> <!-- 英語のコメント --> <meta-data android:name="io.flutter.app.android.SplashScreenUntilFirstFrame" android:value="true" /> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <!-- 次の記述を追加する --> <activity android:name="com.apptreesoftware.barcodescan.BarcodeScannerActivity"/> </application> </manifest>
android/build.gradleを以下のように編集します。自動的に生成されている場合もあります。その際は編集の必要はありません。
Kotlinで書かれているパッケージなのでこのような処理が必要となります。
buildscript { // 1.2.31以前だったら次を変更 ext.kotlin_version = '1.2.71' repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.2.1' // 記述がなければ次を追加 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } allprojects { repositories { google() jcenter() } } rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" } subprojects { project.evaluationDependsOn(':app') } task clean(type: Delete) { delete rootProject.buildDir }
android/app/build.gradleを以下のように編集します。自動的に生成されていることもあります。その際は編集の必要はありません。
/* 省略 */ apply plugin: 'com.android.application' // 次の記述がなければ追加 apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { compileSdkVersion 28 sourceSets { main.java.srcDirs += 'src/main/kotlin' } lintOptions { disable 'InvalidPackage' } defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.third_app" minSdkVersion 16 targetSdkVersion 28 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug } } } flutter { source '../..' } dependencies { // 次の記述がなければ追加 implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
AndroidMainifest.xml、android/build.gradle、android/app/build.gradleは以下のような位置にあります。
ios側
ios/Runner/info.plistにカメラの説明を以下のように追加します。
<key>NSCameraUsageDescription</key> <string>Camera permission is required for barcode scanning.</string>
pubsec.ymlの編集
pubsec.ymlを以下のように編集します。
name: third_app description: A new Flutter application. # 英語の文章 version: 1.0.0+1 environment: sdk: ">=2.1.0 <3.0.0" dependencies: flutter: sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.2 # 以下を追加する barcode_scan: ^0.0.3 dev_dependencies: flutter_test: sdk: flutter # 以下省略
編集後は、packages getボタンを必ず押してください。
QRアプリのプログラミング
いよいよアプリのプログラミングをしていきます。
lib/main.dartを以下のように編集します。
重要な点には、コメントを付けていますので合わせてお読みください。
import 'package:flutter/material.dart'; // 必要なQRコードを読み取る際に必要なpackageをインポート import 'package:flutter/material.dart'; import 'package:barcode_scan/barcode_scan.dart'; import 'package:flutter/services.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'QR scaner And QR Maker', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'QR scaner And QR Maker'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { // 読み取り結果を格納するString型の変数readData String readData = ""; /// QR及びバーコードスキャンを行うメソッドscan() /// Future:非同期処理を実現する Future scan() async { try { // String型のcodeにBarcodeScanner.scan()の結果を代入 // await:非同期対応の要素のキーワード String code = await BarcodeScanner.scan(); // readDataに読み取ったデータを格納する setState(() => this.readData = code); } // 例外処理:プラグインが何らかのエラーを出したとき on PlatformException catch (e) { // エラーコードがBarcodeScanner.CameraAccessDeniedであるときは、 // このアプリにカメラ機能のパーミッションを許可していない状態であることを示す if (e.code == BarcodeScanner.CameraAccessDenied) { setState(() { // readDataにエラー内容を代入 this.readData = 'カメラのパーミッションが有効になっていません。'; }); } // その他の場合は不明のエラー else { setState(() => this.readData = '原因不明のエラー: $e'); } } // 意図しない入力、操作を受けたとき on FormatException{ setState(() => this.readData = '読み取れませんでした (スキャンを開始する前に戻るボタンを使用しました)'); } catch (e) { setState(() => this.readData = '不明なエラー: $e'); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'QRボタンを押すと読み取りを開始します', ), Text( // 読み取り結果readDataを表示 '$readData', style: Theme.of(context).textTheme.display1, ), ], ), ), // ボタンを用意する floatingActionButton: FloatingActionButton( // onPressed:ボタンを押すことでscan()という関数が実行される onPressed: scan, tooltip: 'QR SCAN', child: Icon(Icons.add), ), // This trailing comma makes auto-formatting nicer for build methods. ); } }
実行結果
プログラムを実行すると、以下のような画面が現れます。
下側のボタンを押すと、以下のようにカメラ画面が表示されます。
QRコードを読み取ると、トップの画面に戻り読み取った結果が表示されます。
バーコードの読み取りもできます。