The QR Code Scanner package for Appeto SDK.
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

260 wiersze
6.3 KiB

  1. import 'dart:async';
  2. import 'package:flutter/foundation.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter/services.dart';
  5. import 'package:qr_code_scanner/qr_code_scanner.dart';
  6. typedef QRViewCreatedCallback = void Function(QRViewController);
  7. enum BarcodeFormat {
  8. /// Aztec 2D barcode format.
  9. aztec,
  10. /// CODABAR 1D format.
  11. codabar,
  12. /// Code 39 1D format.
  13. code39,
  14. /// Code 93 1D format.
  15. code93,
  16. /// Code 128 1D format.
  17. code128,
  18. /// Data Matrix 2D barcode format.
  19. dataMatrix,
  20. /// EAN-8 1D format.
  21. ean8,
  22. /// EAN-13 1D format.
  23. ean13,
  24. /// ITF (Interleaved Two of Five) 1D format.
  25. itf,
  26. /// MaxiCode 2D barcode format.
  27. maxicode,
  28. /// PDF417 format.
  29. pdf417,
  30. /// QR Code 2D barcode format.
  31. qrcode,
  32. /// RSS 14
  33. rss14,
  34. /// RSS EXPANDED
  35. rssExpanded,
  36. /// UPC-A 1D format.
  37. upcA,
  38. /// UPC-E 1D format.
  39. upcE,
  40. /// UPC/EAN extension format. Not a stand-alone format.
  41. upcEanExtension
  42. }
  43. const _formatNames = <String, BarcodeFormat>{
  44. 'AZTEC': BarcodeFormat.aztec,
  45. 'CODABAR': BarcodeFormat.codabar,
  46. 'CODE_39': BarcodeFormat.code39,
  47. 'CODE_93': BarcodeFormat.code93,
  48. 'CODE_128': BarcodeFormat.code128,
  49. 'DATA_MATRIX': BarcodeFormat.dataMatrix,
  50. 'EAN_8': BarcodeFormat.ean8,
  51. 'EAN_13': BarcodeFormat.ean13,
  52. 'ITF': BarcodeFormat.itf,
  53. 'MAXICODE': BarcodeFormat.maxicode,
  54. 'PDF_417': BarcodeFormat.pdf417,
  55. 'QR_CODE': BarcodeFormat.qrcode,
  56. 'RSS_14': BarcodeFormat.rss14,
  57. 'RSS_EXPANDED': BarcodeFormat.rssExpanded,
  58. 'UPC_A': BarcodeFormat.upcA,
  59. 'UPC_E': BarcodeFormat.upcE,
  60. 'UPC_EAN_EXTENSION': BarcodeFormat.upcEanExtension,
  61. };
  62. class Barcode {
  63. Barcode(this.code, this.format, this.rawBytes);
  64. final String code;
  65. final BarcodeFormat format;
  66. /// Raw bytes are only supported by Android.
  67. final List<int> rawBytes;
  68. }
  69. class QRView extends StatefulWidget {
  70. const QRView({
  71. @required Key key,
  72. @required this.onQRViewCreated,
  73. this.overlay,
  74. this.overlayMargin = EdgeInsets.zero,
  75. }) : assert(key != null),
  76. assert(onQRViewCreated != null),
  77. super(key: key);
  78. final QRViewCreatedCallback onQRViewCreated;
  79. final ShapeBorder overlay;
  80. final EdgeInsetsGeometry overlayMargin;
  81. @override
  82. State<StatefulWidget> createState() => _QRViewState();
  83. }
  84. class _QRViewState extends State<QRView> {
  85. @override
  86. Widget build(BuildContext context) {
  87. return Stack(
  88. children: [
  89. _getPlatformQrView(widget.key),
  90. if (widget.overlay != null)
  91. Container(
  92. padding: widget.overlayMargin,
  93. decoration: ShapeDecoration(
  94. shape: widget.overlay,
  95. ),
  96. )
  97. else
  98. Container(),
  99. ],
  100. );
  101. }
  102. Widget _getPlatformQrView(GlobalKey key) {
  103. Widget _platformQrView;
  104. switch (defaultTargetPlatform) {
  105. case TargetPlatform.android:
  106. _platformQrView = AndroidView(
  107. viewType: 'net.touchcapture.qr.flutterqr/qrview',
  108. onPlatformViewCreated: _onPlatformViewCreated,
  109. );
  110. break;
  111. case TargetPlatform.iOS:
  112. _platformQrView = UiKitView(
  113. viewType: 'net.touchcapture.qr.flutterqr/qrview',
  114. onPlatformViewCreated: _onPlatformViewCreated,
  115. creationParams:
  116. _CreationParams.fromWidget(MediaQuery.of(context).size.width, 400)
  117. .toMap(),
  118. creationParamsCodec: StandardMessageCodec(),
  119. );
  120. break;
  121. default:
  122. throw UnsupportedError(
  123. "Trying to use the default webview implementation for $defaultTargetPlatform but there isn't a default one");
  124. }
  125. return _platformQrView;
  126. }
  127. void _onPlatformViewCreated(int id) {
  128. if (widget.onQRViewCreated == null) {
  129. return;
  130. }
  131. // We pass the cutout size so that the scanner respects the scan area.
  132. var cutOutSize = 0.0;
  133. if (widget.overlay != null) {
  134. cutOutSize = (widget.overlay as QrScannerOverlayShape).cutOutSize;
  135. }
  136. widget.onQRViewCreated(QRViewController._(id, widget.key, cutOutSize));
  137. }
  138. }
  139. class _CreationParams {
  140. _CreationParams({this.width, this.height});
  141. static _CreationParams fromWidget(double width, double height) {
  142. return _CreationParams(
  143. width: width,
  144. height: height,
  145. );
  146. }
  147. final double width;
  148. final double height;
  149. Map<String, dynamic> toMap() {
  150. return <String, dynamic>{
  151. 'width': width,
  152. 'height': height,
  153. };
  154. }
  155. }
  156. class QRViewController {
  157. QRViewController._(int id, GlobalKey qrKey, double scanArea)
  158. : _channel = MethodChannel('net.touchcapture.qr.flutterqr/qrview_$id') {
  159. updateDimensions(qrKey, scanArea: scanArea);
  160. _channel.setMethodCallHandler(
  161. (call) async {
  162. switch (call.method) {
  163. case scanMethodCall:
  164. if (call.arguments != null) {
  165. final args = call.arguments as Map;
  166. final code = args['code'] as String;
  167. final rawType = args['type'] as String;
  168. // Raw bytes are only supported by Android.
  169. final rawBytes = args['rawBytes'] as List<int>;
  170. final format = _formatNames[rawType];
  171. if (format != null) {
  172. final barcode = Barcode(code, format, rawBytes);
  173. _scanUpdateController.sink.add(barcode);
  174. } else {
  175. throw Exception('Unexpected barcode type $rawType');
  176. }
  177. }
  178. }
  179. },
  180. );
  181. }
  182. static const scanMethodCall = 'onRecognizeQR';
  183. final MethodChannel _channel;
  184. final StreamController<Barcode> _scanUpdateController =
  185. StreamController<Barcode>();
  186. Stream<Barcode> get scannedDataStream => _scanUpdateController.stream;
  187. void flipCamera() {
  188. _channel.invokeMethod('flipCamera');
  189. }
  190. void toggleFlash() {
  191. _channel.invokeMethod('toggleFlash');
  192. }
  193. void pauseCamera() {
  194. _channel.invokeMethod('pauseCamera');
  195. }
  196. void resumeCamera() {
  197. _channel.invokeMethod('resumeCamera');
  198. }
  199. void dispose() {
  200. _scanUpdateController.close();
  201. }
  202. void updateDimensions(GlobalKey key, {double scanArea}) {
  203. if (defaultTargetPlatform == TargetPlatform.iOS) {
  204. final RenderBox renderBox = key.currentContext.findRenderObject();
  205. _channel.invokeMethod('setDimensions', {
  206. 'width': renderBox.size.width,
  207. 'height': renderBox.size.height,
  208. 'scanArea': scanArea ?? 0
  209. });
  210. }
  211. }
  212. }