今回はFlutterでQRコードを生成・読み取りする方法をご紹介します。
QRコードの生成と読み取りをセットで実装することは多々あると思います。
一緒に実装したい!という方はぜひ参考にしてください。
qr_flutter: ^4.0.0
qr_code_scanner: ^0.5.2
QRコードの生成はqr_flutter、読み取りはqr_code_scannerというパッケージを使用します。
どちらもサクッと実装できると思います。
pubspec.yaml
のdependencies
に以下を追加
dependencies:
qr_flutter: ^4.0.0 #なるべく最新のものを使用してください
そしてflutter pub get
でOKです。
詳細は公式のインストールページを参照してください。
ios,androidともにOSごとの設定は不要なので、もう以下をコピペするだけで実装完了です!
import 'package:qr_flutter/qr_flutter.dart';
QrImage(
data: 'https://www.kamo-it.org/blog/36/',
version: QrVersions.auto,
size: 200.0,
)
例として、このブログのリンク情報を含んだQRコードを生成できます。
他のQRコードリーダーで読み取って、このブログに遷移したら成功です!
せっかくのなので、生成するQRコードをカスタマイズしてみましょう!
QrImage(
data: 'https://www.kamo-it.org/blog/36/',
version: QrVersions.auto,
size: 300.0, //QRコードのサイズ
foregroundColor: Colors.pink, //QRコードの色
backgroundColor: Colors.grey, //QRコードの背景色
padding: const EdgeInsets.all(40),
embeddedImage: Image.network(
'https://icooon-mono.com/i/icon_11354/icon_113541_64.png')
.image, //QRコードの真ん中に表示する画像
)
カスタマイズも含め、QRコードの生成はかなりシンプルに実装できますね。
作成するのは上記の画像のような画面です。
pubspec.yaml
のdependencies
に以下を追加
dependencies:
qr_code_scanner: ^0.5.2 #なるべく最新のものを使用してください
そしてflutter pub get
でOKです。
詳細は公式のインストールページを参照してください。
Requires at least SDK 21 (Android 5.0). Requires at least iOS 8.
こちらも考慮しながら設定しましょう。
プロジェクト/ios/Podfile
の(だいたい)2行目あたりにあるiosのバージョン指定を8.0以降にしましょう。
この記事を書いている現在は、デフォルトでios8.0
になっているので、問題はなさそうですが。
僕はios10.0
を使用しています。
platform :ios, '10.0'
info.plist
ファイルに以下を追加
<key>io.flutter.embedded_views_preview</key>
<true/>
<key>NSCameraUsageDescription</key>
<string>This app needs camera access to scan QR codes(カメラの使用許可のための文言)</string>
Requires at least SDK 21 (Android 5.0)
という注意事項があるので、まずはこの部分を確認しましょう。
プロジェクト/android/app/build.gradle
でminSdkVersion
を確認します。
defaultConfig {
applicationId "ApplicationID"
minSdkVersion 21 //ここ
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
この部分はデフォルトのままだと、16
になっていました。21
に変更しましょう。
android/build.gradle
で、
ext.kotlin_version = '1.5.10'
...
classpath 'com.android.tools.build:gradle:4.2.0'
...
を指定。
android/gradle/wrapper/gradle-wrapper.properties
で、
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-all.zip
を指定。
上記のバージョン指定は、パッケージのアップデートとともに更新されていくので、パッケージのREADMEを参考にしてください。
以下に実装例を示します。
コードの詳細については、別途説明しています。
import 'dart:developer';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
class QrScanView extends StatefulWidget {
const QrScanView({Key? key}) : super(key: key);
_QrScanViewState createState() => _QrScanViewState();
}
class _QrScanViewState extends State<QrScanView> {
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
QRViewController? controller;
// In order to get hot reload to work we need to pause the camera if the platform
// is android, or resume the camera if the platform is iOS.
void reassemble() {
super.reassemble();
if (Platform.isAndroid) {
controller?.pauseCamera();
}
controller?.resumeCamera();
}
void dispose() {
controller?.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('QR読み取り'),
centerTitle: true,
),
body: _buildQrView(context),
);
}
Widget _buildQrView(BuildContext context) {
// For this example we check how width or tall the device is and change the scanArea and overlay accordingly.
var scanArea = (MediaQuery.of(context).size.width < 400 ||
MediaQuery.of(context).size.height < 400)
? 150.0
: 300.0;
// To ensure the Scanner view is properly sizes after rotation
// we need to listen for Flutter SizeChanged notification and update controller
return QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.red,
borderRadius: 10,
borderLength: 30,
borderWidth: 10,
cutOutSize: scanArea),
onPermissionSet: (ctrl, p) => _onPermissionSet(context, ctrl, p),
);
}
void _onQRViewCreated(QRViewController controller) {
setState(() {
this.controller = controller;
});
controller.scannedDataStream.listen((scanData) async {
print(scanData.code);
});
}
void _onPermissionSet(BuildContext context, QRViewController ctrl, bool p) {
log('${DateTime.now().toIso8601String()}_onPermissionSet $p');
if (!p) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('no Permission')),
);
}
}
}
ホットリロードすると呼ばれる処理です。
パッケージのREADMEのコメントを引用していますが、ホットリロードを使用するために必要な処理です。
// In order to get hot reload to work we need to pause the camera if the platform
// is android, or resume the camera if the platform is iOS.
void reassemble() {
super.reassemble();
if (Platform.isAndroid) {
controller?.pauseCamera();
}
controller?.resumeCamera();
}
QRカメラの初期化時に呼ばれます。
void _onQRViewCreated(QRViewController controller) {
setState(() {
this.controller = controller;
});
controller.scannedDataStream.listen((scanData) async {
print(scanData.code);
});
}
こちらもカメラのパーミッションがセットされた時点で呼ばれる処理です。
iosシミュレータを使用していると、no Permission
というスナックバーが表示されると思います。
テストは実機で行いましょう!
void _onPermissionSet(BuildContext context, QRViewController ctrl, bool p) {
log('${DateTime.now().toIso8601String()}_onPermissionSet $p');
if (!p) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('no Permission')),
);
}
}
QRコードスキャナーの表示部分です。
QrScannerOverlayShape
のプロパティをカスタマイズすることで、QR読み取り部分のUIを調整できます。
Widget _buildQrView(BuildContext context) {
// For this example we check how width or tall the device is and change the scanArea and overlay accordingly.
var scanArea = (MediaQuery.of(context).size.width < 400 ||
MediaQuery.of(context).size.height < 400)
? 150.0
: 300.0;
// To ensure the Scanner view is properly sizes after rotation
// we need to listen for Flutter SizeChanged notification and update controller
return QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.red,
borderRadius: 10,
borderLength: 30,
borderWidth: 10,
cutOutSize: scanArea),
onPermissionSet: (ctrl, p) => _onPermissionSet(context, ctrl, p),
);
}
いかがでしたでしょうか。
QRコードの生成・読み取り部分は実装できたでしょうか。
QRコード周りは意外とシンプルに実装できるので、めげずに立ち向かってみましょう。
この記事が参考になれば幸いです。
https://pub.dev/packages/qr_code_scanner https://pub.dev/packages/qr_flutter
可茂IT塾ではFlutterインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。
Read More可茂IT塾ではFlutterインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。
Read More