こんにちは、CX事業本部 Delivery部の若槻です。
Flutter アプリケーションで QR コードスキャナーを実装したい場合には、下記のようにパッケージの選択肢がいくつかあります。
パッケージ | LIKES | PUB POINTS | POPULARITY | Last Published |
---|---|---|---|---|
mobile_scanner | 1139 | 130 | 99% | 38 days ago |
qr_code_scanner | 1798 | 120 | 99% | 13 months ago |
zxing2 | 42 | 140 | 95% | 7 months agos |
最も枯れているのは qr_code_scanner ですが、メンテナンスモードとなりしばらく更新されていません。よって現在最も有力なのは下記の mobile_scanner のようです。mobile_scanner は iOS、Android に加えて Web および macOS にも対応しています。
今回は mobile_scanner を使った Flutter アプリでの QR コードスキャンの実装を Web で試してみました。
試してみた
環境
$ flutter --version
Flutter 3.7.7 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 2ad6cd72c0 (6 months ago) • 2023-03-08 09:41:59 -0800
Engine • revision 1837b5be5f
Tools • Dart 2.19.4 • DevTools 2.20.1
プロジェクト作成
flutter create my_app
code my_app
パッケージ導入
flutter pub add mobile_scanner
導入されました。
$ git diff pubspec.yaml
diff --git a/pubspec.yaml b/pubspec.yaml
index 4dfe6bc..ac5348d 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -35,6 +35,7 @@ dependencies:
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
+ mobile_scanner: ^3.4.1
dev_dependencies:
flutter_test:
index.html の修正
index.html
に下記を追加して、ZXing on Web を読み込むようにします。
<script src="https://unpkg.com/@zxing/library@0.19.1" type="application/javascript"></script>
実装
Usage を参考に実装してみます。
lib/main.dart
import 'package:flutter/material.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
void main() => runApp(const MaterialApp(home: MyHome()));
class MyHome extends StatelessWidget {
const MyHome({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Mobile Scanner')),
body: MobileScanner(
// fit: BoxFit.contain,
onDetect: (capture) {
final List<Barcode> barcodes = capture.barcodes;
// final Uint8List? image = capture.image;
for (final barcode in barcodes) {
debugPrint('Barcode found! ${barcode.rawValue}');
}
},
),
);
}
}
MobileScanner()
を使用すると端末のカメラが起動します。onDetect
を使用することにより、QR コードが読み取れた際の処理を記述できます。capture.barcodes
で読み取ったバーコードのリストを取得できます。capture.image
で読み取った画像バイナリを取得できます。
動作確認
アプリケーションを起動します。
flutter run -d chrome
起動時にカメラのパーミッションを求められるので許可します。
AppBar 以外の部分がカメラ映像となります。QR コードをカメラにかざすと自動で読み取られます。
次のようにカメラ映像内に QR コードが映っている間は継続して読み取られます。実際の実装では、読み取りが完了したら別の画面に遷移するなどの処理を行うことになると思います。
$ flutter run -d chrome
Launching lib/main.dart on Chrome in debug mode...
Waiting for connection from debug service on Chrome... 10.3s
This app is linked to the debug service: ws://127.0.0.1:61158/fuksFUIMVMQ=/ws
Debug service listening on ws://127.0.0.1:61158/fuksFUIMVMQ=/ws
💪 Running with sound null safety 💪
🔥 To hot restart changes while running, press "r" or "R".
For a more detailed help message, press "h". To quit, press "q".
An Observatory debugger and profiler on Chrome is available at: http://127.0.0.1:61158/fuksFUIMVMQ=
The Flutter DevTools debugger and profiler on Chrome is available at: http://127.0.0.1:9103?uri=http://127.0.0.1:61158/fuksFUIMVMQ=
Barcode found! https://ja.wikipedia.org/
Barcode found! https://ja.wikipedia.org/
Barcode found! https://ja.wikipedia.org/
Barcode found! https://ja.wikipedia.org/
Barcode found! https://ja.wikipedia.org/
Barcode found! https://ja.wikipedia.org/
遭遇したエラー
前述の実装のアプリケーション実行時に下記のエラーが発生しました。
══╡ EXCEPTION CAUGHT BY SERVICES LIBRARY ╞══════════════════════════════════════════════════════════
The following MissingPluginException was thrown while activating platform stream on channel
dev.steenbakker.mobile_scanner/scanner/event:
MissingPluginException(No implementation found for method listen on channel
dev.steenbakker.mobile_scanner/scanner/event)
When the exception was thrown, this was the stack:
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 266:49 throw_
packages/flutter/src/services/platform_channel.dart 313:7 _invokeMethod
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 45:50 <fn>
dart-sdk/lib/async/zone.dart 1660:54 runUnary
dart-sdk/lib/async/future_impl.dart 147:18 handleValue
dart-sdk/lib/async/future_impl.dart 767:44 handleValueCallback
dart-sdk/lib/async/future_impl.dart 796:13 _propagateToListeners
dart-sdk/lib/async/future_impl.dart 567:5 [_completeWithValue]
dart-sdk/lib/async/future_impl.dart 640:7 callback
dart-sdk/lib/async/schedule_microtask.dart 40:11 _microtaskLoop
dart-sdk/lib/async/schedule_microtask.dart 49:5 _startMicrotaskLoop
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 166:15 <fn>
════════════════════════════════════════════════════════════════════════════════════════════════════
Error: Expected a value of type 'MobileScannerException', but got one of type 'MissingPluginException'
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 266:49 throw_
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 99:3 castError
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 485:10 cast
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart 638:14 as_C
packages/mobile_scanner/src/mobile_scanner.dart 142:35 <fn>
packages/flutter/src/widgets/framework.dart 1133:30 setState
packages/mobile_scanner/src/mobile_scanner.dart 141:9 <fn>
dart-sdk/lib/async/zone.dart 1660:54 runUnary
dart-sdk/lib/async/future_impl.dart 165:22 handleError
dart-sdk/lib/async/future_impl.dart 779:46 handleError
dart-sdk/lib/async/future_impl.dart 800:13 _propagateToListeners
dart-sdk/lib/async/future_impl.dart 567:5 [_completeWithValue]
dart-sdk/lib/async/future_impl.dart 640:7 callback
dart-sdk/lib/async/schedule_microtask.dart 40:11 _microtaskLoop
dart-sdk/lib/async/schedule_microtask.dart 49:5 _startMicrotaskLoop
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 166:15 <fn>
原因としては、Flutter 本体を読み込む前に ZXing on Web を読み込む必要があったためでした。追記位置に注意してください。
+ <script src="https://unpkg.com/@zxing/library@0.19.1" type="application/javascript"></script>
<script src="flutter.js" defer></script>
- <script src="https://unpkg.com/@zxing/library@0.19.1" type="application/javascript"></script>
おわりに
Flutter で QR コードスキャンを実装できる mobile_scanner を Web アプリで試してみました。
mobile_scanner はスコアが高いとは言いつつネット上にあまり情報がないのが心配だったのですが、使ってみると思った以上に簡単に QR コードスキャンを実装することができました。
次回は iOS アプリでも試してみたいと思います。
参考
以上