├── ios ├── Assets │ └── .gitkeep ├── Classes │ ├── QrcodeFlutterPlugin.h │ ├── QRCaptureView.h │ ├── QRCaptureViewFactory.h │ ├── QRCapturePlatformView.h │ ├── QRCaptureViewFactory.m │ ├── QRCapturePlatformView.m │ ├── QrcodeFlutterPlugin.m │ └── QRCaptureView.m ├── .gitignore └── qrcode_flutter.podspec ├── android ├── settings.gradle ├── gradle.properties ├── .gitignore ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ └── com │ │ └── xzp │ │ └── qrcode_flutter │ │ ├── QRCaptureViewFactory.kt │ │ ├── FlutterRegister.kt │ │ ├── QrcodeFlutterPlugin.kt │ │ └── QRCaptureView.kt ├── .classpath └── build.gradle ├── example ├── ios │ ├── Runner │ │ ├── Runner-Bridging-Header.h │ │ ├── Assets.xcassets │ │ │ ├── LaunchImage.imageset │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ ├── README.md │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ ├── Flutter │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ ├── Flutter.podspec │ │ └── AppFrameworkInfo.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── xcshareddata │ │ │ └── xcschemes │ │ │ │ └── Runner.xcscheme │ │ └── project.pbxproj │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── .gitignore │ ├── Podfile.lock │ └── Podfile ├── web │ ├── favicon.png │ ├── icons │ │ ├── Icon-192.png │ │ ├── Icon-512.png │ │ ├── Icon-maskable-192.png │ │ └── Icon-maskable-512.png │ ├── manifest.json │ └── index.html ├── android │ ├── gradle.properties │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21 │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night │ │ │ │ │ │ └── styles.xml │ │ │ │ ├── kotlin │ │ │ │ │ └── com │ │ │ │ │ │ └── example │ │ │ │ │ │ └── qrcode_example │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── AndroidManifest.xml │ │ │ ├── profile │ │ │ │ └── AndroidManifest.xml │ │ │ └── debug │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── .gitignore │ ├── settings.gradle │ └── build.gradle ├── README.md ├── pubspec.yaml ├── test │ └── widget_test.dart ├── analysis_options.yaml ├── .gitignore ├── lib │ └── main.dart └── pubspec.lock ├── .gitignore ├── analysis_options.yaml ├── pubspec.yaml ├── LICENSE ├── lib ├── qrcode_flutter.dart ├── qrcode_flutter_platform_interface.dart ├── qrcode_flutter_io.dart └── qrcode_flutter_web.dart ├── assets └── qrcode_flutter_web.js ├── CHANGELOG.md ├── README.md └── pubspec.lock /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'qrcode' 2 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | 3 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /example/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/web/favicon.png -------------------------------------------------------------------------------- /example/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/web/icons/Icon-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/web/icons/Icon-512.png -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /ios/Classes/QrcodeFlutterPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface QrcodeFlutterPlugin : NSObject 4 | @end 5 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzhongpeng/qrcode_flutter/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/example/qrcode_example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.qrcode_example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | 4 | .packages 5 | .pub/ 6 | 7 | build/ 8 | 9 | example/build/ 10 | example/.vscode 11 | example/.dart_tool 12 | 13 | .dart_tool 14 | .idea 15 | example/android/.settings 16 | android/.settings 17 | publish.sh 18 | qrcode_flutter.iml 19 | .vscode/ 20 | .metadata -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | analyzer: 3 | exclude: 4 | - example/** 5 | - build/** 6 | errors: 7 | unused_import: warning 8 | unused_local_variable: warning 9 | public_member_api_docs: warning 10 | undefined_prefixed_name: ignore 11 | linter: 12 | rules: 13 | public_member_api_docs: true -------------------------------------------------------------------------------- /android/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | .flutter-plugins-dependencies -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Classes/QRCaptureView.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRCaptureView.h 3 | // Pods-Runner 4 | // 5 | // Created by xzp on 2020/5/15. 6 | // 7 | 8 | #import 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface QRCaptureView : UIView 14 | 15 | - (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args registrar:(NSObject*)registrar; 16 | - (void)pause; 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /ios/Classes/QRCaptureViewFactory.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRCaptureViewFactory.h 3 | // Runner 4 | // 5 | // Created by xzp 2020/5/15 6 | // Copyright © 2019 The Chromium Authors. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface QRCaptureViewFactory : NSObject 15 | 16 | - (instancetype)initWithRegistrar:(NSObject*)registrar; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | -------------------------------------------------------------------------------- /ios/Classes/QRCapturePlatformView.h: -------------------------------------------------------------------------------- 1 | // 2 | // QRCapturePlatformView.h 3 | // Pods-Runner 4 | // 5 | // Created by xzp on 2020/5/15. 6 | // 7 | 8 | #import 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface QRCapturePlatformView : NSObject 14 | 15 | - (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args registrar:(NSObject*)registrar; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/xzp/qrcode_flutter/QRCaptureViewFactory.kt: -------------------------------------------------------------------------------- 1 | package com.xzp.qrcode_flutter 2 | 3 | import android.content.Context 4 | import io.flutter.plugin.common.PluginRegistry 5 | import io.flutter.plugin.common.StandardMessageCodec 6 | import io.flutter.plugin.platform.PlatformView 7 | import io.flutter.plugin.platform.PlatformViewFactory 8 | 9 | class QRCaptureViewFactory() : 10 | PlatformViewFactory(StandardMessageCodec.INSTANCE) { 11 | 12 | override fun create(context: Context, id: Int, obj: Any?): PlatformView { 13 | return QRCaptureView(id) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # qrcode_example 2 | 3 | Demonstrates how to use the qrcode plugin. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: qrcode_flutter_example 2 | description: Demo how to use the qrcode_flutter plugin. 3 | publish_to: "none" 4 | version: 0.0.1 5 | author: xuzhongpeng 6 | environment: 7 | sdk: ">=2.1.0 <3.0.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | 13 | # The following adds the Cupertino Icons font to your application. 14 | # Use with the CupertinoIcons class for iOS style icons. 15 | cupertino_icons: ^0.1.2 16 | 17 | dev_dependencies: 18 | flutter_test: 19 | sdk: flutter 20 | 21 | qrcode_flutter: 22 | path: ../ 23 | image_picker: 0.8.4+2 24 | flutter: 25 | uses-material-design: true 26 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.7.21' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.2.2' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Generated.xcconfig 21 | Flutter/ephemeral/ 22 | Flutter/app.flx 23 | Flutter/app.zip 24 | Flutter/flutter_assets/ 25 | Flutter/flutter_export_environment.sh 26 | ServiceDefinitions.json 27 | Runner/GeneratedPluginRegistrant.* 28 | 29 | # Exceptions to above rules. 30 | !default.mode1v3 31 | !default.mode2v3 32 | !default.pbxuser 33 | !default.perspectivev3 34 | 35 | Flutter/flutter_export_environment.sh -------------------------------------------------------------------------------- /ios/qrcode_flutter.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 3 | # 4 | Pod::Spec.new do |s| 5 | s.name = 'qrcode_flutter' 6 | s.version = '0.0.1' 7 | s.summary = 'A new flutter plugin project.' 8 | s.description = <<-DESC 9 | A new flutter plugin project. 10 | DESC 11 | s.homepage = 'http://jsshou.cn' 12 | s.license = { :file => '../LICENSE' } 13 | s.author = { 'Your Company' => 'xuzhongpeng@foxmail.com' } 14 | s.source = { :path => '.' } 15 | s.source_files = 'Classes/**/*' 16 | s.public_header_files = 'Classes/**/*.h' 17 | s.dependency 'Flutter' 18 | 19 | s.ios.deployment_target = '8.0' 20 | end 21 | 22 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - image_picker (0.0.1): 4 | - Flutter 5 | - qrcode_flutter (0.0.1): 6 | - Flutter 7 | 8 | DEPENDENCIES: 9 | - Flutter (from `Flutter`) 10 | - image_picker (from `.symlinks/plugins/image_picker/ios`) 11 | - qrcode_flutter (from `.symlinks/plugins/qrcode_flutter/ios`) 12 | 13 | EXTERNAL SOURCES: 14 | Flutter: 15 | :path: Flutter 16 | image_picker: 17 | :path: ".symlinks/plugins/image_picker/ios" 18 | qrcode_flutter: 19 | :path: ".symlinks/plugins/qrcode_flutter/ios" 20 | 21 | SPEC CHECKSUMS: 22 | Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 23 | image_picker: 9aa50e1d8cdacdbed739e925b7eea16d014367e6 24 | qrcode_flutter: de88a439c5eebe01b38b647af520e674770d4462 25 | 26 | PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 27 | 28 | COCOAPODS: 1.10.0 29 | -------------------------------------------------------------------------------- /example/ios/Flutter/Flutter.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: This podspec is NOT to be published. It is only used as a local source! 3 | # This is a generated file; do not edit or check into version control. 4 | # 5 | 6 | Pod::Spec.new do |s| 7 | s.name = 'Flutter' 8 | s.version = '1.0.0' 9 | s.summary = 'A UI toolkit for beautiful and fast apps.' 10 | s.homepage = 'https://flutter.dev' 11 | s.license = { :type => 'BSD' } 12 | s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } 13 | s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s } 14 | s.ios.deployment_target = '11.0' 15 | # Framework linking is handled by Flutter tooling, not CocoaPods. 16 | # Add a placeholder to satisfy `s.dependency 'Flutter'` plugin podspecs. 17 | s.vendored_frameworks = 'path/to/nothing' 18 | end 19 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 11.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | 12 | void main() { 13 | testWidgets('Verify Platform version', (WidgetTester tester) async { 14 | // Build our app and trigger a frame. 15 | // Verify that platform version is retrieved. 16 | expect( 17 | find.byWidgetPredicate( 18 | (Widget widget) => 19 | widget is Text && widget.data.startsWith('Running on:'), 20 | ), 21 | findsOneWidget, 22 | ); 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: qrcode_flutter 2 | description: Flutter plugin for scanning QR codes.You can customize your page by using PlatformView.Scanning Picture from path (photo album). 3 | version: 3.1.0 4 | # author: JSShou 5 | homepage: https://github.com/xuzhongpeng/qrcode_flutter 6 | 7 | environment: 8 | sdk: ">=2.16.0 <3.0.0" 9 | flutter: ">=3.0.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | plugin_platform_interface: ^2.1.3 15 | flutter_web_plugins: 16 | sdk: flutter 17 | 18 | dev_dependencies: 19 | flutter_test: 20 | sdk: flutter 21 | flutter_lints: ^2.0.0 22 | 23 | flutter: 24 | plugin: 25 | platforms: 26 | android: 27 | package: com.xzp.qrcode_flutter 28 | pluginClass: QrcodeFlutterPlugin 29 | ios: 30 | pluginClass: QrcodeFlutterPlugin 31 | web: 32 | pluginClass: QrcodeFlutterWeb 33 | fileName: qrcode_flutter_web.dart 34 | assets: 35 | - assets/ -------------------------------------------------------------------------------- /ios/Classes/QRCaptureViewFactory.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRCaptureViewFactory.m 3 | // Runner 4 | // 5 | // Created by xzp 2020/5/15. 6 | // Copyright © 2020 The Chromium Authors. All rights reserved. 7 | // 8 | 9 | #import "QRCaptureViewFactory.h" 10 | #import "QRCapturePlatformView.h" 11 | 12 | @interface QRCaptureViewFactory () 13 | 14 | @property(nonatomic, strong) NSObject* registrar; 15 | 16 | @end 17 | 18 | @implementation QRCaptureViewFactory 19 | 20 | - (instancetype)initWithRegistrar:(NSObject*)registrar { 21 | self = [super init]; 22 | if (self) { 23 | self.registrar = registrar; 24 | } 25 | return self; 26 | } 27 | 28 | 29 | - (nonnull NSObject *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args { 30 | return [[QRCapturePlatformView alloc] initWithFrame:frame viewIdentifier:viewId arguments:args registrar:self.registrar]; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /ios/Classes/QRCapturePlatformView.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRCapturePlatformView.m 3 | // Pods-Runner 4 | // 5 | // Created by xzp on 2020/5/15. 6 | // 7 | 8 | #import "QRCapturePlatformView.h" 9 | #import "QRCaptureView.h" 10 | 11 | @interface QRCapturePlatformView () 12 | 13 | @property(nonatomic, strong) QRCaptureView *captureView; 14 | 15 | @end 16 | 17 | @implementation QRCapturePlatformView 18 | 19 | - (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args registrar:(NSObject*)registrar { 20 | if (self = [super init]) { 21 | self.captureView = [[QRCaptureView alloc] initWithFrame:frame viewIdentifier:viewId arguments:args registrar:registrar]; 22 | self.captureView.frame = frame; 23 | self.captureView.backgroundColor = [UIColor clearColor]; 24 | } 25 | return self; 26 | } 27 | 28 | - (nonnull UIView *)view { 29 | return self.captureView; 30 | } 31 | //stop camera 32 | - (void)dealloc{ 33 | [self.captureView pause]; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "qrcode_flutter_example", 3 | "short_name": "qrcode_flutter_example", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "Demonstrates how to use the qrcode_flutter plugin.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | }, 22 | { 23 | "src": "icons/Icon-maskable-192.png", 24 | "sizes": "192x192", 25 | "type": "image/png", 26 | "purpose": "maskable" 27 | }, 28 | { 29 | "src": "icons/Icon-maskable-512.png", 30 | "sizes": "512x512", 31 | "type": "image/png", 32 | "purpose": "maskable" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 JSShou 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.xzp.qrcode_flutter' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.7.21' 6 | repositories { 7 | google() 8 | mavenCentral() 9 | } 10 | 11 | dependencies { 12 | classpath 'com.android.tools.build:gradle:3.6.4' 13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 14 | } 15 | } 16 | 17 | rootProject.allprojects { 18 | repositories { 19 | google() 20 | mavenCentral() 21 | } 22 | } 23 | 24 | apply plugin: 'com.android.library' 25 | apply plugin: 'kotlin-android' 26 | 27 | android { 28 | compileSdkVersion 30 29 | 30 | sourceSets { 31 | main.java.srcDirs += 'src/main/kotlin' 32 | } 33 | defaultConfig { 34 | minSdkVersion 24 35 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 36 | } 37 | lintOptions { 38 | disable 'InvalidPackage' 39 | } 40 | } 41 | 42 | dependencies { 43 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 44 | implementation "com.journeyapps:zxing-android-embedded:4.3.0" 45 | } 46 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/xzp/qrcode_flutter/FlutterRegister.kt: -------------------------------------------------------------------------------- 1 | package com.xzp.qrcode_flutter 2 | 3 | import android.app.Activity 4 | import io.flutter.embedding.engine.plugins.FlutterPlugin 5 | import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding 6 | import io.flutter.plugin.common.BinaryMessenger 7 | import io.flutter.plugin.common.PluginRegistry 8 | import java.lang.ref.WeakReference 9 | 10 | object FlutterRegister { 11 | var activity: WeakReference? = null 12 | var messenger: BinaryMessenger? = null 13 | var activityBinding: ActivityPluginBinding? = null 14 | var registrar: PluginRegistry.Registrar? = null 15 | fun getActivity(): Activity? { 16 | return activity?.get() 17 | } 18 | 19 | //获取权限 20 | fun addRequestPermissionsResultListener(listerner: PluginRegistry.RequestPermissionsResultListener) { 21 | if (activityBinding != null) { 22 | activityBinding?.addRequestPermissionsResultListener(listerner) 23 | } else { 24 | registrar?.addRequestPermissionsResultListener(listerner) 25 | } 26 | } 27 | 28 | fun clear() { 29 | activity?.clear() 30 | // activity?.clear() 31 | // messenger = null 32 | // registrar = null 33 | // activityBinding = null 34 | } 35 | } -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '11.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /example/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 15 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | /build/ 31 | 32 | # Android related 33 | **/android/**/gradle-wrapper.jar 34 | **/android/.gradle 35 | **/android/captures/ 36 | **/android/gradlew 37 | **/android/gradlew.bat 38 | **/android/local.properties 39 | **/android/**/GeneratedPluginRegistrant.java 40 | 41 | # iOS/XCode related 42 | **/ios/**/*.mode1v3 43 | **/ios/**/*.mode2v3 44 | **/ios/**/*.moved-aside 45 | **/ios/**/*.pbxuser 46 | **/ios/**/*.perspectivev3 47 | **/ios/**/*sync/ 48 | **/ios/**/.sconsign.dblite 49 | **/ios/**/.tags* 50 | **/ios/**/.vagrant/ 51 | **/ios/**/DerivedData/ 52 | **/ios/**/Icon? 53 | **/ios/**/Pods/ 54 | **/ios/**/.symlinks/ 55 | **/ios/**/profile 56 | **/ios/**/xcuserdata 57 | **/ios/.generated/ 58 | **/ios/Flutter/App.framework 59 | **/ios/Flutter/Flutter.framework 60 | **/ios/Flutter/Generated.xcconfig 61 | **/ios/Flutter/app.flx 62 | **/ios/Flutter/app.zip 63 | **/ios/Flutter/flutter_assets/ 64 | **/ios/ServiceDefinitions.json 65 | **/ios/Runner/GeneratedPluginRegistrant.* 66 | 67 | # Exceptions to above rules. 68 | !**/ios/**/default.mode1v3 69 | !**/ios/**/default.mode2v3 70 | !**/ios/**/default.pbxuser 71 | !**/ios/**/default.perspectivev3 72 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 73 | .flutter-plugins-dependencies 74 | ios/Flutter/flutter_export_environment.sh 75 | .metadata -------------------------------------------------------------------------------- /lib/qrcode_flutter.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | import 'package:qrcode_flutter/qrcode_flutter_platform_interface.dart'; 3 | export 'package:qrcode_flutter/qrcode_flutter_platform_interface.dart'; 4 | 5 | /// 扫码及获取相册的控制类 6 | ///Scan code and access to the album control class 7 | class QRCaptureController { 8 | final QrcodeFlutterPlatform _platform = QrcodeFlutterPlatform.instance; 9 | 10 | /// 构造函数 11 | QRCaptureController(); 12 | 13 | /// 暂停扫码 14 | /// resume scanning code from camera 15 | void pause() { 16 | _platform.pause(); 17 | } 18 | 19 | /// 当调用[pause]后,恢复扫码 20 | /// resume scanning code from camera after [pause] 21 | void resume() { 22 | _platform.resume(); 23 | } 24 | 25 | /// 停止扫码 26 | /// Stop scanning code from camera 27 | void dispose() { 28 | _platform.dispose(); 29 | } 30 | 31 | /// 获取数据的回调函数 32 | /// The callback function that gets the data from camera 33 | void onCapture(CaptureCallback capture) { 34 | _platform.onCapture(capture); 35 | } 36 | 37 | /// 控制相机开关回调函数 38 | /// PhoneTorch ON or OFF 39 | set torchMode(CaptureTorchMode mode) => _platform.torchMode = mode; 40 | 41 | /// 从相机获取二维码并返回扫码信息 42 | /// Get the qrcode data from photo album 43 | static Future> getQrCodeByImagePath(String path) async { 44 | return QrcodeFlutterPlatform.instance.getQrCodeByImagePath(path); 45 | } 46 | 47 | Widget _buildWidget() { 48 | return _platform.buildWidget(); 49 | } 50 | } 51 | 52 | /// 使用Platform View展示相机,可在Flutter View中自定义相机显示位置 53 | /// Camera view 54 | class QRCaptureView extends StatelessWidget { 55 | /// 控制器 56 | final QRCaptureController controller; 57 | 58 | /// key for Widget 59 | /// controller 相机控制器 60 | const QRCaptureView({Key? key, required this.controller}) : super(key: key); 61 | 62 | @override 63 | Widget build(BuildContext context) { 64 | return controller._buildWidget(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /lib/qrcode_flutter_platform_interface.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | import 'package:plugin_platform_interface/plugin_platform_interface.dart'; 3 | 4 | import 'qrcode_flutter_io.dart'; 5 | 6 | /// get qrcode data in callback 7 | /// 定义回调函数,返回扫码数据 8 | typedef CaptureCallback = Function(String data); 9 | 10 | /// PhoneTorch 11 | /// 闪光灯开关 12 | enum CaptureTorchMode { 13 | /// ON 14 | on, 15 | 16 | /// OFF 17 | off 18 | } 19 | /// 定义插件抽象 20 | abstract class QrcodeFlutterPlatform extends PlatformInterface { 21 | /// Constructs a QrcodeFlutterPlatform. 22 | QrcodeFlutterPlatform() : super(token: _token); 23 | 24 | static final Object _token = Object(); 25 | 26 | static QrcodeFlutterPlatform _instance = QRCodeFlutterIO(); 27 | 28 | /// The default instance of [QrcodeFlutterPlatform] to use. 29 | /// 30 | /// Defaults to [MethodChannelQrcodeFlutter]. 31 | static QrcodeFlutterPlatform get instance => _instance; 32 | 33 | /// Platform-specific implementations should set this with their own 34 | /// platform-specific class that extends [QrcodeFlutterPlatform] when 35 | /// they register themselves. 36 | static set instance(QrcodeFlutterPlatform instance) { 37 | PlatformInterface.verifyToken(instance, _token); 38 | _instance = instance; 39 | } 40 | 41 | /// 暂停扫码 42 | /// resume scanning code from camera 43 | void pause(); 44 | 45 | /// 当调用[pause]后,恢复扫码 46 | /// resume scanning code from camera after [pause] 47 | void resume() ; 48 | 49 | /// 停止扫码 50 | /// Stop scanning code from camera 51 | void dispose(); 52 | 53 | /// 获取数据的回调函数 54 | /// The callback function that gets the data from camera 55 | void onCapture(CaptureCallback capture) ; 56 | 57 | /// 控制相机开关回调函数 58 | /// PhoneTorch ON or OFF 59 | set torchMode(CaptureTorchMode mode) ; 60 | 61 | /// 从相机获取二维码并返回扫码信息 62 | /// Get the qrcode data from photo album 63 | Future> getQrCodeByImagePath(String path); 64 | 65 | /// Build camera widget 66 | Widget buildWidget(); 67 | } 68 | -------------------------------------------------------------------------------- /example/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | qrcode_flutter_example 33 | 34 | 35 | 39 | 40 | 41 | 42 | 43 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CADisableMinimumFrameDurationOnPhone 6 | 7 | CFBundleDevelopmentRegion 8 | $(DEVELOPMENT_LANGUAGE) 9 | CFBundleDisplayName 10 | Example 11 | CFBundleExecutable 12 | $(EXECUTABLE_NAME) 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | example 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | $(FLUTTER_BUILD_NAME) 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | $(FLUTTER_BUILD_NUMBER) 27 | LSRequiresIPhoneOS 28 | 29 | NSCameraUsageDescription 30 | App需要您的同意,才能访问相机 31 | UIApplicationSupportsIndirectInputEvents 32 | 33 | UILaunchStoryboardName 34 | LaunchScreen 35 | UIMainStoryboardFile 36 | Main 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationLandscapeLeft 41 | UIInterfaceOrientationLandscapeRight 42 | 43 | UISupportedInterfaceOrientations~ipad 44 | 45 | UIInterfaceOrientationPortrait 46 | UIInterfaceOrientationPortraitUpsideDown 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | UIViewControllerBasedStatusBarAppearance 51 | 52 | io.flutter.embedded_views_preview 53 | 54 | NSPhotoLibraryUsageDescription 55 | Photo Library Access Warning 56 | NSBonjourServices 57 | 58 | _dartobservatory._tcp 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /ios/Classes/QrcodeFlutterPlugin.m: -------------------------------------------------------------------------------- 1 | #import "QrcodeFlutterPlugin.h" 2 | #import "QRCaptureViewFactory.h" 3 | 4 | @implementation QrcodeFlutterPlugin 5 | + (void)registerWithRegistrar:(NSObject*)registrar { 6 | QRCaptureViewFactory *factory = [[QRCaptureViewFactory alloc] initWithRegistrar:registrar]; 7 | [registrar registerViewFactory:factory withId:@"plugins/qr_capture_view"]; 8 | FlutterMethodChannel* channel = [FlutterMethodChannel 9 | methodChannelWithName:@"plugins/qr_capture/method" 10 | binaryMessenger:[registrar messenger]]; 11 | QrcodeFlutterPlugin *plugin = [[QrcodeFlutterPlugin alloc] init]; 12 | [registrar addMethodCallDelegate:plugin channel:channel]; 13 | } 14 | - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { 15 | if ([@"getQrCodeByImagePath" isEqualToString:call.method]) { 16 | NSString *path = call.arguments; 17 | UIImage *image=[[UIImage alloc]initWithContentsOfFile:path]; 18 | NSArray *array=[QrcodeFlutterPlugin readQRCodeFromImage:image]; 19 | NSMutableString *str = [[NSMutableString alloc] init]; 20 | NSMutableArray *res = [[NSMutableArray alloc] init]; 21 | [array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 22 | CIQRCodeFeature *temp = (CIQRCodeFeature *)obj; 23 | [res addObject:temp.messageString]; 24 | }]; 25 | result(res); 26 | } 27 | } 28 | + (NSArray *)readQRCodeFromImage:(UIImage *)image{ 29 | // 创建一个CIImage对象 30 | CIImage *ciImage = [[CIImage alloc] initWithCGImage:image.CGImage options:nil]; 31 | CIContext *context = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer : @(YES)}]; // 软件渲染 32 | CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:context options:@{CIDetectorAccuracy : CIDetectorAccuracyHigh}];// 二维码识别 33 | 34 | // [VNImageRequestHandler]; 35 | 36 | // 注意这里的CIDetectorTypeQRCode 37 | NSArray *features = [detector featuresInImage:ciImage]; 38 | for (CIQRCodeFeature *feature in features) { 39 | NSLog(@"msg = %@",feature.messageString); // 打印二维码中的信息 40 | } 41 | return features; 42 | } 43 | @end 44 | -------------------------------------------------------------------------------- /assets/qrcode_flutter_web.js: -------------------------------------------------------------------------------- 1 | ((window) => { 2 | let html5QrCode; 3 | let cameraId; 4 | // build camera view 5 | window.firstBuild = (width, height) => { 6 | console.log("build view"); 7 | html5QrCode = new Html5Qrcode( 8 | "flutter_plugin_camera", 9 | /* verbose= */ false 10 | ); 11 | Html5Qrcode.getCameras() 12 | .then((devices) => { 13 | if (devices && devices.length) { 14 | cameraId = devices[0].id; 15 | // .. use this to start scanning. 16 | html5QrCode 17 | .start( 18 | cameraId, 19 | { 20 | fps: 10, // Optional, frame per seconds for qr code scanning 21 | qrbox: { width: width, height: height }, // Optional, if you want bounded box UI 22 | }, 23 | (decodedText, decodedResult) => { 24 | window.onCapture(decodedText); 25 | } 26 | ) 27 | .catch((err) => { 28 | // Start failed, handle it. 29 | console.error("[qrcode_flutter] start err:" + err); 30 | }); 31 | } 32 | }) 33 | .catch((err) => { 34 | // handle err 35 | }); 36 | }; 37 | 38 | window.rebuild = async (width, height) => { 39 | await stop(); 40 | html5QrCode 41 | .start( 42 | cameraId, 43 | { 44 | fps: 10, // Optional, frame per seconds for qr code scanning 45 | qrbox: { width: width, height: height }, // Optional, if you want bounded box UI 46 | }, 47 | (decodedText, decodedResult) => { 48 | window.onCapture(decodedText); 49 | } 50 | ) 51 | .catch((err) => { 52 | // Start failed, handle it. 53 | console.log("[qrcode_flutter] start err:" + err); 54 | }); 55 | }; 56 | 57 | window.stop = () => { 58 | return html5QrCode?.stop().catch((err) => { 59 | console.log("[qrcode_flutter] stop err:" + err); 60 | }); 61 | }; 62 | window.dispose = () => { 63 | stop(); 64 | html5QrCode = null; 65 | }; 66 | window.pause = () => { 67 | try { 68 | html5QrCode?.pause(); 69 | } catch (err) { 70 | console.error("[qrcode_flutter] pause err:" + err); 71 | } 72 | }; 73 | window.resume = () => { 74 | try { 75 | html5QrCode?.resume(); 76 | } catch (err) { 77 | console.log("[qrcode_flutter] resume err:" + err); 78 | } 79 | }; 80 | })(window); 81 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 3.1.0 2 | 1. upgrade kotlin to 1.7.21 since 1.3.40 is too old 3 | 2. upgrade zxing android to [latest 4.3.0](https://mvnrepository.com/artifact/com.journeyapps/zxing-android-embedded) 4 | 3. remove unused android plugin:kapt and kae since this will block kotlin upgrade of 1.8+ 5 | 4. change android jcenter to mavenCentral since jcenter is [abandoned in 2021](https://developer.android.google.cn/studio/build/jcenter-migration) 6 | 5. upgrade agp from 3.2.1 to 3.6.4 since 3.2.1 is too old and 3.6.4 is [last stable release of agp 3+](https://developer.android.google.cn/studio/releases/gradle-plugin) 7 | ## 3.0.0-nullsafety.0 8 | 1. Support null safety 9 | ## 2.0.1 10 | 1. add documents 11 | ## 2.0.0 12 | 13 | 1. fix [#5 add dispose method](https://github.com/xuzhongpeng/qrcode_flutter/issues/5) 14 | 2. fix [10 相机不允许使用时,打开扫码功能会闪退](https://github.com/xuzhongpeng/qrcode_flutter/issues/10) 15 | 3. fix [issue8--Can't add a nil AVCaptureInput](https://github.com/xuzhongpeng/qrcode_flutter/issues/8) 16 | 4. fix [issue7--divide by zero](https://github.com/xuzhongpeng/qrcode_flutter/issues/7).Fixed only by upgrade [zixing4.0.2](https://github.com/journeyapps/zxing-android-embedded/issues/334) 17 | ## 1.0.9 18 | 19 | 1. dealloc camera view when camera page pop from flutter [pr6](https://github.com/xuzhongpeng/qrcode_flutter/pull/6) 20 | 21 | ## 1.0.8 22 | 23 | 1. Plugin can register many time 24 | 2. [Improvement: allow mocking of plugin method channel](https://github.com/xuzhongpeng/qrcode_flutter/pull/4) 25 | 26 | ## 1.0.6 27 | 28 | 1. fix small qrcode images scanning correct 29 | 30 | ## 1.0.5 31 | 32 | 1.fix requestPermissions callback error(cause open camera error when agree permissions) 33 | 34 | ## 1.0.4 35 | 36 | 1. change `implementation "com.journeyapps:zxing-android-embedded:3.5.0"` to `api "com.journeyapps:zxing-android-embedded:3.5.0"`(because the library `zxing-android-embedded` has built the class `CameraConfigurationUtils` the same as `com.google.zxing:android-core:3.2.1`) 37 | 2. fix Android clear bugs 38 | 39 | ## ~~1.0.3~~ 40 | 41 | 1. fix iOS errors 42 | 2. Support Android V2 embedding. 43 | 3. Change the result of the scanned album to List 44 | 45 | ## ~~1.0.2~~ 46 | 47 | 1. Support Android V2 embedding. 48 | 2. Change the result of the scanned album to List 49 | 50 | 51 | ## 1.0.1 52 | 53 | Modify the document 54 | 55 | ## 1.0.0 56 | 57 | 提供相机扫码功能,提供照片解析功能(通过相册选择照片或者网络下载照片) 58 | 59 | You can customize your page using by PlatformView.Scanning Picture from path(photo album). 60 | 61 | 62 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion flutter.compileSdkVersion 30 | ndkVersion flutter.ndkVersion 31 | 32 | compileOptions { 33 | sourceCompatibility JavaVersion.VERSION_1_8 34 | targetCompatibility JavaVersion.VERSION_1_8 35 | } 36 | 37 | kotlinOptions { 38 | jvmTarget = '1.8' 39 | } 40 | 41 | sourceSets { 42 | main.java.srcDirs += 'src/main/kotlin' 43 | } 44 | 45 | defaultConfig { 46 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 47 | applicationId "com.example.qrcode_example" 48 | // You can update the following values to match your application needs. 49 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. 50 | // minSdkVersion flutter.minSdkVersion 51 | minSdkVersion 24 52 | targetSdkVersion flutter.targetSdkVersion 53 | versionCode flutterVersionCode.toInteger() 54 | versionName flutterVersionName 55 | } 56 | 57 | buildTypes { 58 | release { 59 | // TODO: Add your own signing config for the release build. 60 | // Signing with the debug keys for now, so `flutter run --release` works. 61 | signingConfig signingConfigs.debug 62 | } 63 | } 64 | } 65 | 66 | flutter { 67 | source '../..' 68 | } 69 | 70 | dependencies { 71 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 72 | } 73 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /lib/qrcode_flutter_io.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter/services.dart'; 5 | import 'package:qrcode_flutter/qrcode_flutter_platform_interface.dart'; 6 | 7 | /// support android and ios 8 | class QRCodeFlutterIO extends QrcodeFlutterPlatform { 9 | MethodChannel? _methodChannel; 10 | CaptureCallback? _capture; 11 | 12 | /// 初始化方法,必须初始化 13 | /// The initialization method must be initialized 14 | void _onPlatformViewCreated(int id) { 15 | _methodChannel = MethodChannel('plugins/qr_capture/method_$id'); 16 | _methodChannel?.setMethodCallHandler((MethodCall call) async { 17 | if (call.method == 'onCaptured') { 18 | if (_capture != null && call.arguments != null) { 19 | _capture?.call(call.arguments.toString()); 20 | } 21 | } 22 | }); 23 | } 24 | 25 | /// 暂停扫码 26 | /// resume scanning code from camera 27 | @override 28 | void pause() { 29 | assert(_methodChannel != null, 30 | "_methodChannel can not be null. Please call onPlatformViewCreated first"); 31 | _methodChannel?.invokeMethod('pause'); 32 | } 33 | 34 | /// 当调用[pause]后,恢复扫码 35 | /// resume scanning code from camera after [pause] 36 | @override 37 | void resume() { 38 | assert(_methodChannel != null, 39 | "_methodChannel can not be null. Please call onPlatformViewCreated first"); 40 | _methodChannel?.invokeMethod('resume'); 41 | } 42 | 43 | /// 停止扫码 44 | /// Stop scanning code from camera 45 | @override 46 | void dispose() { 47 | pause(); 48 | _capture = null; 49 | _methodChannel = null; 50 | } 51 | 52 | /// 获取数据的回调函数 53 | /// The callback function that gets the data from camera 54 | @override 55 | void onCapture(CaptureCallback capture) { 56 | _capture = capture; 57 | } 58 | 59 | /// 控制相机开关回调函数 60 | /// PhoneTorch ON or OFF 61 | @override 62 | set torchMode(CaptureTorchMode mode) { 63 | var isOn = mode == CaptureTorchMode.on; 64 | assert(_methodChannel != null, 65 | "_methodChannel can not be null. Please call onPlatformViewCreated first"); 66 | _methodChannel?.invokeMethod('setTorchMode', isOn); 67 | } 68 | 69 | /// 从相机获取二维码并返回扫码信息 70 | /// Get the qrcode data from photo album 71 | @override 72 | Future> getQrCodeByImagePath(String path) async { 73 | var methodChannel = const MethodChannel('plugins/qr_capture/method'); 74 | var qrResult = 75 | await methodChannel.invokeMethod("getQrCodeByImagePath", path); 76 | return List.from(qrResult); 77 | } 78 | 79 | @override 80 | Widget buildWidget() => _QrCodeView(qrCodeFlutterIO: this); 81 | } 82 | 83 | class _QrCodeView extends StatefulWidget { 84 | final QRCodeFlutterIO qrCodeFlutterIO; 85 | const _QrCodeView({Key? key, required this.qrCodeFlutterIO}) 86 | : super(key: key); 87 | 88 | @override 89 | State<_QrCodeView> createState() => __QrCodeViewState(); 90 | } 91 | 92 | class __QrCodeViewState extends State<_QrCodeView> { 93 | 94 | @override 95 | void dispose() { 96 | widget.qrCodeFlutterIO.dispose(); 97 | super.dispose(); 98 | } 99 | 100 | @override 101 | Widget build(BuildContext context) { 102 | if (Platform.isIOS) { 103 | return UiKitView( 104 | viewType: 'plugins/qr_capture_view', 105 | creationParamsCodec: const StandardMessageCodec(), 106 | onPlatformViewCreated: (id) { 107 | widget.qrCodeFlutterIO._onPlatformViewCreated(id); 108 | }, 109 | ); 110 | } else { 111 | return AndroidView( 112 | viewType: 'plugins/qr_capture_view', 113 | creationParamsCodec: const StandardMessageCodec(), 114 | onPlatformViewCreated: (id) { 115 | widget.qrCodeFlutterIO._onPlatformViewCreated(id); 116 | }, 117 | ); 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![license MIT](https://img.shields.io/github/license/xuzhongpeng/qrcode_flutter) 2 | [![qrCode_flutter](https://img.shields.io/pub/v/qrcode_flutter.svg)](https://pub.dev/packages/qrcode_flutter) 3 | ![iOS&Android](https://img.shields.io/badge/platform-Android%7CiOS%7CWeb-red) 4 | 5 | # qrcode_flutter 6 | 7 | ## introduce 8 | 9 | [pub.dev](https://pub.dev/packages/qrcode_flutter) 10 | 11 | Flutter plugin for scanning QR codes.You can customize your page by using PlatformView.Scanning Picture from path(photo album). 12 | 13 | You can download [flutter_demo.apk](https://blog-1253495453.cos.ap-chongqing.myqcloud.com/app-debug.apk) for testing 14 | 15 | ## Usage 16 | 17 | ```dart 18 | class MyApp extends StatefulWidget { 19 | @override 20 | _MyAppState createState() => _MyAppState(); 21 | } 22 | 23 | class _MyAppState extends State with TickerProviderStateMixin { 24 | QRCaptureController _controller = QRCaptureController(); 25 | 26 | bool _isTorchOn = false; 27 | 28 | String _captureText = ''; 29 | 30 | @override 31 | void initState() { 32 | super.initState(); 33 | 34 | _controller.onCapture((data) { 35 | print('$data'); 36 | setState(() { 37 | _captureText = data; 38 | }); 39 | }); 40 | } 41 | 42 | @override 43 | Widget build(BuildContext context) { 44 | return Scaffold( 45 | appBar: AppBar( 46 | title: const Text('scan'), 47 | actions: [ 48 | TextButton( 49 | onPressed: () async { 50 | PickedFile image = 51 | await ImagePicker().getImage(source: ImageSource.gallery); 52 | var qrCodeResult = 53 | await QRCaptureController.getQrCodeByImagePath(image.path); 54 | setState(() { 55 | _captureText = qrCodeResult.join('\n'); 56 | }); 57 | }, 58 | child: Text('photoAlbum', style: TextStyle(color: Colors.white)), 59 | ), 60 | ], 61 | ), 62 | body: Stack( 63 | alignment: Alignment.center, 64 | children: [ 65 | Container( 66 | width: 300, 67 | height: 300, 68 | child: QRCaptureView( 69 | controller: _controller, 70 | ), 71 | ), 72 | SafeArea( 73 | child: Align( 74 | alignment: Alignment.bottomCenter, 75 | child: _buildToolBar(), 76 | ), 77 | ), 78 | Container( 79 | child: Text('$_captureText'), 80 | ) 81 | ], 82 | ), 83 | ); 84 | } 85 | 86 | Widget _buildToolBar() { 87 | return Row( 88 | mainAxisSize: MainAxisSize.max, 89 | mainAxisAlignment: MainAxisAlignment.center, 90 | children: [ 91 | TextButton( 92 | onPressed: () { 93 | _controller.pause(); 94 | }, 95 | child: Text('pause'), 96 | ), 97 | TextButton( 98 | onPressed: () { 99 | if (_isTorchOn) { 100 | _controller.torchMode = CaptureTorchMode.off; 101 | } else { 102 | _controller.torchMode = CaptureTorchMode.on; 103 | } 104 | _isTorchOn = !_isTorchOn; 105 | }, 106 | child: Text('torch'), 107 | ), 108 | TextButton( 109 | onPressed: () { 110 | _controller.resume(); 111 | }, 112 | child: Text('resume'), 113 | ), 114 | ], 115 | ); 116 | } 117 | } 118 | ``` 119 | 120 | ## Integration 121 | 122 | ### iOS 123 | 124 | To use on iOS, you must add the following to your Info.plist 125 | 126 | ``` 127 | NSCameraUsageDescription 128 | Camera permission is required for qrcode scanning. 129 | io.flutter.embedded_views_preview 130 | 131 | ``` 132 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:qrcode_flutter/qrcode_flutter.dart'; 3 | import 'package:image_picker/image_picker.dart'; 4 | 5 | void main() => runApp(_MyPage()); 6 | 7 | class _MyPage extends StatefulWidget { 8 | @override 9 | _OnePageState createState() => _OnePageState(); 10 | } 11 | 12 | class _OnePageState extends State<_MyPage> { 13 | @override 14 | void initState() { 15 | super.initState(); 16 | } 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return MaterialApp( 21 | home: Scaffold( 22 | appBar: AppBar( 23 | title: Text("qrcode_flutter"), 24 | ), 25 | body: Builder( 26 | builder: (context) => TextButton( 27 | child: Text("navigate to qrcode page"), 28 | onPressed: () { 29 | Navigator.of(context) 30 | .push(MaterialPageRoute(builder: (_) => MyApp())); 31 | }, 32 | ), 33 | ), 34 | )); 35 | } 36 | } 37 | 38 | class MyApp extends StatefulWidget { 39 | @override 40 | _MyAppState createState() => _MyAppState(); 41 | } 42 | 43 | class _MyAppState extends State with TickerProviderStateMixin { 44 | QRCaptureController _controller = QRCaptureController(); 45 | 46 | bool _isTorchOn = false; 47 | 48 | String _captureText = ''; 49 | 50 | @override 51 | void initState() { 52 | super.initState(); 53 | 54 | _controller.onCapture((data) { 55 | print('$data'); 56 | setState(() { 57 | _captureText = data; 58 | }); 59 | }); 60 | } 61 | 62 | @override 63 | Widget build(BuildContext context) { 64 | return Scaffold( 65 | appBar: AppBar( 66 | title: const Text('scan'), 67 | actions: [ 68 | TextButton( 69 | onPressed: () async { 70 | PickedFile image = 71 | await ImagePicker().getImage(source: ImageSource.gallery); 72 | var qrCodeResult = 73 | await QRCaptureController.getQrCodeByImagePath(image.path); 74 | setState(() { 75 | _captureText = qrCodeResult.join('\n'); 76 | }); 77 | }, 78 | child: Text('photoAlbum', style: TextStyle(color: Colors.white)), 79 | ), 80 | ], 81 | ), 82 | body: Stack( 83 | alignment: Alignment.center, 84 | children: [ 85 | Container( 86 | width: 300, 87 | height: 300, 88 | child: QRCaptureView( 89 | controller: _controller, 90 | ), 91 | ), 92 | SafeArea( 93 | child: Align( 94 | alignment: Alignment.bottomCenter, 95 | child: _buildToolBar(), 96 | ), 97 | ), 98 | Container( 99 | child: Text('$_captureText'), 100 | ) 101 | ], 102 | ), 103 | ); 104 | } 105 | 106 | Widget _buildToolBar() { 107 | return Row( 108 | mainAxisSize: MainAxisSize.max, 109 | mainAxisAlignment: MainAxisAlignment.center, 110 | children: [ 111 | TextButton( 112 | onPressed: () { 113 | _controller.pause(); 114 | }, 115 | child: Text('pause'), 116 | ), 117 | TextButton( 118 | onPressed: () { 119 | if (_isTorchOn) { 120 | _controller.torchMode = CaptureTorchMode.off; 121 | } else { 122 | _controller.torchMode = CaptureTorchMode.on; 123 | } 124 | _isTorchOn = !_isTorchOn; 125 | }, 126 | child: Text('torch'), 127 | ), 128 | TextButton( 129 | onPressed: () { 130 | _controller.resume(); 131 | }, 132 | child: Text('resume'), 133 | ), 134 | ], 135 | ); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/xzp/qrcode_flutter/QrcodeFlutterPlugin.kt: -------------------------------------------------------------------------------- 1 | package com.xzp.qrcode_flutter 2 | 3 | import android.graphics.BitmapFactory 4 | import com.google.zxing.BinaryBitmap 5 | import com.google.zxing.DecodeHintType 6 | import com.google.zxing.RGBLuminanceSource 7 | import com.google.zxing.common.HybridBinarizer 8 | import com.google.zxing.qrcode.QRCodeReader 9 | import io.flutter.embedding.engine.plugins.FlutterPlugin 10 | import io.flutter.embedding.engine.plugins.activity.ActivityAware 11 | import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding 12 | import io.flutter.plugin.common.BinaryMessenger 13 | import io.flutter.plugin.common.MethodCall 14 | import io.flutter.plugin.common.MethodChannel 15 | import io.flutter.plugin.common.PluginRegistry.Registrar 16 | import java.lang.ref.WeakReference 17 | import java.util.* 18 | 19 | class QrcodeFlutterPlugin : MethodChannel.MethodCallHandler, FlutterPlugin, ActivityAware { 20 | override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { 21 | when (call?.method) { 22 | "getQrCodeByImagePath" -> { 23 | val path = call.arguments as String 24 | // DecodeHintType 和EncodeHintType 25 | val options = BitmapFactory.Options() 26 | options.inJustDecodeBounds = true 27 | BitmapFactory.decodeFile(path, options) 28 | options.inJustDecodeBounds = false 29 | options.inSampleSize = 1 30 | var bitmap = BitmapFactory.decodeFile(path, options) 31 | val width = bitmap.width 32 | val height = bitmap.height 33 | val pixels = IntArray(width * height) 34 | bitmap.getPixels(pixels, 0, width, 0, 0, width, height) 35 | var source = RGBLuminanceSource(width, height, pixels) 36 | var hints: Hashtable = Hashtable() 37 | hints.put(DecodeHintType.CHARACTER_SET, "utf-8"); // 设置二维码内容的编码 38 | try { 39 | var result1 = QRCodeReader().decode(BinaryBitmap(HybridBinarizer(source)), hints) 40 | result.success(listOf(result1.text)) 41 | } catch (e: Exception) { 42 | // nothing qrcode found 43 | val list: List = listOf() 44 | result.success(list) 45 | } 46 | } 47 | } 48 | } 49 | 50 | override fun onDetachedFromActivity() { 51 | FlutterRegister.clear() 52 | } 53 | 54 | override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) { 55 | onAttachedToActivity(binding) 56 | } 57 | 58 | override fun onDetachedFromActivityForConfigChanges() { 59 | onDetachedFromActivity() 60 | } 61 | 62 | override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { 63 | // FlutterRegister.clear() 64 | pluginBinding = null 65 | } 66 | 67 | override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { 68 | pluginBinding = binding 69 | } 70 | 71 | override fun onAttachedToActivity(binding: ActivityPluginBinding) { 72 | //v2 embedding 73 | FlutterRegister.activityBinding = binding 74 | FlutterRegister.messenger=pluginBinding?.binaryMessenger 75 | FlutterRegister.activity= WeakReference(binding.activity) 76 | pluginBinding?.platformViewRegistry?.registerViewFactory("plugins/qr_capture_view", QRCaptureViewFactory()) 77 | var channel = MethodChannel(pluginBinding?.binaryMessenger!!, "plugins/qr_capture/method") 78 | channel.setMethodCallHandler(QrcodeFlutterPlugin()) 79 | } 80 | var pluginBinding:FlutterPlugin.FlutterPluginBinding ?= null 81 | companion object { 82 | @JvmStatic 83 | fun registerWith(registrar: Registrar) { 84 | FlutterRegister.registrar = registrar 85 | FlutterRegister.messenger = registrar.messenger() 86 | FlutterRegister.activity = WeakReference(registrar.activity()) 87 | registrar.platformViewRegistry().registerViewFactory("plugins/qr_capture_view", QRCaptureViewFactory()) 88 | var channel = MethodChannel(registrar.messenger(), "plugins/qr_capture/method") 89 | channel.setMethodCallHandler(QrcodeFlutterPlugin()) 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /lib/qrcode_flutter_web.dart: -------------------------------------------------------------------------------- 1 | // In order to *not* need this ignore, consider extracting the "web" version 2 | // of your plugin as a separate package, instead of inlining it in the same 3 | // package as the core of your plugin. 4 | // ignore: avoid_web_libraries_in_flutter 5 | // ignore: avoid_web_libraries_in_flutter 6 | import 'dart:html' as html; 7 | import 'dart:ui' as ui; 8 | import 'dart:js' as js; 9 | import 'dart:js_util' as js_util; 10 | import 'package:flutter/foundation.dart'; 11 | import 'package:flutter/widgets.dart'; 12 | import 'package:flutter_web_plugins/flutter_web_plugins.dart'; 13 | 14 | import 'qrcode_flutter_platform_interface.dart'; 15 | 16 | const String _tag = '[qrcode_flutter_web]'; 17 | 18 | /// A web implementation of the QrcodeFlutterPlatform of the QrcodeFlutter plugin. 19 | class QrcodeFlutterWeb extends QrcodeFlutterPlatform { 20 | final String _viewType = 'flutter_plugin_camera'; 21 | CaptureCallback? _capture; 22 | 23 | /// Constructs a QrcodeFlutterWeb 24 | QrcodeFlutterWeb() { 25 | // ignore:undefined_prefixed_name 26 | ui.platformViewRegistry.registerViewFactory( 27 | _viewType, 28 | (int viewId) => html.DivElement() 29 | ..style.width = '100%' 30 | ..style.height = '100%' 31 | ..id = _viewType); 32 | html.document.body!.append(html.ScriptElement() 33 | ..src = 34 | 'assets/packages/qrcode_flutter/assets/html5-qrcode.min.js' // ignore: unsafe_html 35 | ..type = 'application/javascript'); 36 | html.document.body!.append(html.ScriptElement() 37 | ..src = 38 | 'assets/packages/qrcode_flutter/assets/qrcode_flutter_web.js' // ignore: unsafe_html 39 | ..type = 'application/javascript'); 40 | js_util.setProperty(html.window, "onCapture", js.allowInterop((args) { 41 | _capture?.call(args); 42 | })); 43 | } 44 | 45 | // ignore: public_member_api_docs 46 | static void registerWith(Registrar registrar) { 47 | QrcodeFlutterPlatform.instance = QrcodeFlutterWeb(); 48 | } 49 | 50 | @override 51 | void dispose() { 52 | js.context.callMethod('dispose'); 53 | _capture = null; 54 | } 55 | 56 | @override 57 | Future> getQrCodeByImagePath(String path) { 58 | throw UnimplementedError('$_tag not support getQrCodeByImagePath on Web'); 59 | } 60 | 61 | @override 62 | void onCapture(CaptureCallback capture) { 63 | _capture = capture; 64 | } 65 | 66 | @override 67 | void pause() { 68 | js.context.callMethod('pause'); 69 | } 70 | 71 | @override 72 | void resume() { 73 | js.context.callMethod('resume'); 74 | } 75 | 76 | @override 77 | set torchMode(CaptureTorchMode mode) { 78 | if (kDebugMode) { 79 | print('$_tag not support torchMode on Web'); 80 | } 81 | } 82 | 83 | @override 84 | Widget buildWidget() => _QRcodeFlutter( 85 | viewType: _viewType, 86 | controller: this, 87 | ); 88 | } 89 | 90 | class _QRcodeFlutter extends StatefulWidget { 91 | final String viewType; 92 | final QrcodeFlutterWeb controller; 93 | const _QRcodeFlutter( 94 | {Key? key, required this.viewType, required this.controller}) 95 | : super(key: key); 96 | 97 | @override 98 | State<_QRcodeFlutter> createState() => __QRcodeFlutterState(); 99 | } 100 | 101 | class __QRcodeFlutterState extends State<_QRcodeFlutter> { 102 | @override 103 | void initState() { 104 | super.initState(); 105 | } 106 | 107 | double? _width; 108 | double? _height; 109 | 110 | @override 111 | void dispose() { 112 | widget.controller.dispose(); 113 | super.dispose(); 114 | } 115 | 116 | _init(double width, double height) { 117 | if (_width != width || _height != height) { 118 | if (_width != null && _height != null) { 119 | // not first call 120 | try { 121 | WidgetsBinding.instance.addPostFrameCallback((timeStamp) { 122 | js.context.callMethod('rebuild', [width, height]); 123 | }); 124 | } catch (e) { 125 | if (kDebugMode) { 126 | print('$_tag rebuild error: $e'); 127 | } 128 | } 129 | } else { 130 | try { 131 | WidgetsBinding.instance.addPostFrameCallback((timeStamp) { 132 | js.context.callMethod('firstBuild', [width, height]); 133 | }); 134 | } catch (e) { 135 | if (kDebugMode) { 136 | print('$_tag firstBuild error: $e'); 137 | } 138 | } 139 | } 140 | _width = width; 141 | _height = height; 142 | } 143 | } 144 | 145 | @override 146 | Widget build(BuildContext context) { 147 | return LayoutBuilder(builder: (context, constraints) { 148 | _init(constraints.maxWidth, constraints.maxHeight); 149 | return HtmlElementView(viewType: widget.viewType); 150 | }); 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /ios/Classes/QRCaptureView.m: -------------------------------------------------------------------------------- 1 | // 2 | // QRCaptureView.m 3 | // Pods-Runner 4 | // 5 | // Created by xzp on 2020/5/15. 6 | // 7 | 8 | #import "QRCaptureView.h" 9 | #import 10 | 11 | @interface QRCaptureView () 12 | 13 | @property(nonatomic, strong) AVCaptureSession *session; 14 | @property(nonatomic, strong) FlutterMethodChannel *channel; 15 | @property(nonatomic, weak) AVCaptureVideoPreviewLayer *captureLayer; 16 | 17 | @end 18 | 19 | @implementation QRCaptureView 20 | 21 | - (AVCaptureSession *)session { 22 | if (!_session) { 23 | _session = [[AVCaptureSession alloc] init]; 24 | } 25 | return _session; 26 | } 27 | // init capture frame 28 | - (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args registrar:(NSObject*)registrar { 29 | if (self = [super initWithFrame:frame]) { 30 | NSString *name = [NSString stringWithFormat:@"plugins/qr_capture/method_%lld", viewId]; 31 | FlutterMethodChannel *channel = [FlutterMethodChannel 32 | methodChannelWithName:name 33 | binaryMessenger:registrar.messenger]; 34 | self.channel = channel; 35 | [registrar addMethodCallDelegate:self channel:channel]; 36 | 37 | AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:self.session]; 38 | self.captureLayer = layer; 39 | 40 | layer.backgroundColor = [UIColor darkGrayColor].CGColor; 41 | [self.layer addSublayer:layer]; 42 | layer.videoGravity = AVLayerVideoGravityResizeAspectFill; 43 | 44 | AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 45 | AVCaptureDeviceInput *input = [[AVCaptureDeviceInput alloc] initWithDevice:device error:nil]; 46 | AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init]; 47 | if ([self.session canAddInput: input]) 48 | { 49 | [self.session addInput: input]; 50 | } 51 | if ([self.session canAddOutput: output]) 52 | { 53 | [self.session addOutput: output]; 54 | } 55 | self.session.sessionPreset = AVCaptureSessionPresetHigh; 56 | 57 | output.metadataObjectTypes = output.availableMetadataObjectTypes; 58 | [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; 59 | // setMetadataObjectTypes when input is not nil 60 | if (input) 61 | { 62 | [output setMetadataObjectTypes:@[AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeCode39Code, AVMetadataObjectTypeCode39Mod43Code, 63 | AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode93Code, AVMetadataObjectTypeCode128Code, 64 | AVMetadataObjectTypePDF417Code, AVMetadataObjectTypeQRCode, AVMetadataObjectTypeAztecCode]]; 65 | } 66 | [self.session startRunning]; 67 | } 68 | return self; 69 | } 70 | 71 | - (void)layoutSubviews { 72 | [super layoutSubviews]; 73 | self.captureLayer.frame = self.bounds; 74 | } 75 | 76 | - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { 77 | // stop camera 78 | if ([call.method isEqualToString:@"pause"]) { 79 | [self pause]; 80 | } 81 | // resume camera from state 'pause' 82 | else if ([call.method isEqualToString:@"resume"]) { 83 | [self resume]; 84 | } 85 | //Set your phone's flash 86 | else if ([call.method isEqualToString:@"setTorchMode"]) { 87 | AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 88 | if (!device.hasTorch) { 89 | return; 90 | } 91 | NSNumber *isOn = call.arguments; 92 | [device lockForConfiguration:nil]; 93 | if (isOn.boolValue) { 94 | [device setTorchMode:AVCaptureTorchModeOn]; 95 | } else { 96 | [device setTorchMode:AVCaptureTorchModeOff]; 97 | } 98 | [device unlockForConfiguration]; 99 | } 100 | } 101 | 102 | + (void)registerWithRegistrar:(nonnull NSObject *)registrar {} 103 | 104 | 105 | - (void)resume { 106 | [self.session startRunning]; 107 | } 108 | 109 | - (void)pause { 110 | [self.session stopRunning]; 111 | } 112 | 113 | #pragma mark - AVCaptureMetadataOutputObjectsDelegate 114 | -(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{ 115 | if (metadataObjects.count>0) { 116 | AVMetadataMachineReadableCodeObject *metadataObject = metadataObjects[0]; 117 | NSString *value = metadataObject.stringValue; 118 | if (value.length && self.channel) { 119 | [self.channel invokeMethod:@"onCaptured" arguments:value]; 120 | } 121 | } 122 | } 123 | 124 | - (void)dealloc { 125 | [self.session stopRunning]; 126 | } 127 | 128 | @end 129 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/xzp/qrcode_flutter/QRCaptureView.kt: -------------------------------------------------------------------------------- 1 | package com.xzp.qrcode_flutter 2 | 3 | import android.Manifest 4 | import android.app.Activity 5 | import android.app.Application 6 | import android.content.pm.PackageManager 7 | import android.content.pm.PackageManager.PERMISSION_GRANTED 8 | import android.os.Build 9 | import android.os.Bundle 10 | import android.view.View 11 | import com.google.zxing.ResultPoint 12 | import com.journeyapps.barcodescanner.BarcodeCallback 13 | import com.journeyapps.barcodescanner.BarcodeResult 14 | import com.journeyapps.barcodescanner.BarcodeView 15 | import io.flutter.plugin.common.MethodCall 16 | import io.flutter.plugin.common.MethodChannel 17 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler 18 | import io.flutter.plugin.common.PluginRegistry 19 | import io.flutter.plugin.platform.PlatformView 20 | 21 | class QRCaptureView(id: Int) : 22 | PlatformView, MethodCallHandler { 23 | override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { 24 | when (call?.method) { 25 | "checkAndRequestPermission" -> { 26 | checkAndRequestPermission(result) 27 | } 28 | } 29 | 30 | when (call?.method) { 31 | "resume" -> { 32 | resume() 33 | } 34 | } 35 | 36 | when (call?.method) { 37 | "pause" -> { 38 | pause() 39 | } 40 | } 41 | 42 | when (call?.method) { 43 | "setTorchMode" -> { 44 | val isOn = call.arguments as Boolean 45 | barcodeView?.setTorch(isOn) 46 | } 47 | } 48 | } 49 | 50 | private fun resume() { 51 | barcodeView?.resume() 52 | } 53 | 54 | private fun pause() { 55 | barcodeView?.pause() 56 | } 57 | 58 | private fun checkAndRequestPermission(result: MethodChannel.Result?) { 59 | if (cameraPermissionContinuation != null) { 60 | result?.error("cameraPermission", "Camera permission request ongoing", null) 61 | } 62 | 63 | cameraPermissionContinuation = Runnable { 64 | cameraPermissionContinuation = null 65 | if (!hasCameraPermission()) { 66 | result?.error( 67 | "cameraPermission", "MediaRecorderCamera permission not granted", null) 68 | return@Runnable 69 | } 70 | } 71 | 72 | requestingPermission = false 73 | if (hasCameraPermission()) { 74 | cameraPermissionContinuation?.run() 75 | } else { 76 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 77 | requestingPermission = true 78 | FlutterRegister.getActivity()?.requestPermissions( 79 | arrayOf(Manifest.permission.CAMERA), 80 | CAMERA_REQUEST_ID) 81 | } 82 | } 83 | } 84 | 85 | private fun hasCameraPermission(): Boolean { 86 | return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || 87 | activity?.checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED 88 | } 89 | 90 | companion object { 91 | const val CAMERA_REQUEST_ID = 513469796 92 | } 93 | 94 | var barcodeView: BarcodeView? = null 95 | private val activity = FlutterRegister.getActivity() 96 | var cameraPermissionContinuation: Runnable? = null 97 | var requestingPermission = false 98 | val channel: MethodChannel 99 | 100 | init { 101 | FlutterRegister.addRequestPermissionsResultListener(CameraRequestPermissionsListener()) 102 | channel = MethodChannel(FlutterRegister.messenger!!, "plugins/qr_capture/method_$id") 103 | channel.setMethodCallHandler(this) 104 | checkAndRequestPermission(null) 105 | val barcode = BarcodeView(FlutterRegister.getActivity()) 106 | this.barcodeView = barcode 107 | barcode.decodeContinuous( 108 | object : BarcodeCallback { 109 | override fun barcodeResult(result: BarcodeResult) { 110 | channel.invokeMethod("onCaptured", result.text) 111 | } 112 | 113 | override fun possibleResultPoints(resultPoints: List) {} 114 | } 115 | ) 116 | 117 | barcode.resume() 118 | 119 | FlutterRegister.getActivity()?.application?.registerActivityLifecycleCallbacks( 120 | object : Application.ActivityLifecycleCallbacks { 121 | override fun onActivityPaused(p0: Activity) { 122 | if (p0 == FlutterRegister.getActivity()) { 123 | barcodeView?.pause() 124 | } 125 | } 126 | 127 | override fun onActivityResumed(p0: Activity) { 128 | if (p0 == FlutterRegister.getActivity()) { 129 | barcodeView?.resume() 130 | } 131 | } 132 | 133 | override fun onActivityStarted(p0: Activity) { 134 | } 135 | 136 | override fun onActivityDestroyed(p0: Activity) { 137 | } 138 | 139 | override fun onActivitySaveInstanceState(p0: Activity, p1: Bundle) { 140 | } 141 | 142 | override fun onActivityStopped(p0: Activity) { 143 | } 144 | 145 | override fun onActivityCreated(p0: Activity, p1: Bundle?) { 146 | } 147 | } 148 | ) 149 | } 150 | 151 | override fun getView(): View { 152 | return this.barcodeView!! 153 | } 154 | 155 | override fun dispose() { 156 | barcodeView?.pause() 157 | barcodeView = null 158 | } 159 | 160 | private inner class CameraRequestPermissionsListener : PluginRegistry.RequestPermissionsResultListener { 161 | override fun onRequestPermissionsResult(id: Int, permissions: Array, grantResults: IntArray): Boolean { 162 | if (id == CAMERA_REQUEST_ID && grantResults[0] == PERMISSION_GRANTED) { 163 | cameraPermissionContinuation?.run() 164 | return true 165 | } 166 | return false 167 | } 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 9 | url: "https://pub.flutter-io.cn" 10 | source: hosted 11 | version: "2.10.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.flutter-io.cn" 18 | source: hosted 19 | version: "2.1.1" 20 | characters: 21 | dependency: transitive 22 | description: 23 | name: characters 24 | sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c 25 | url: "https://pub.flutter-io.cn" 26 | source: hosted 27 | version: "1.2.1" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 33 | url: "https://pub.flutter-io.cn" 34 | source: hosted 35 | version: "1.1.1" 36 | collection: 37 | dependency: transitive 38 | description: 39 | name: collection 40 | sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 41 | url: "https://pub.flutter-io.cn" 42 | source: hosted 43 | version: "1.17.0" 44 | fake_async: 45 | dependency: transitive 46 | description: 47 | name: fake_async 48 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 49 | url: "https://pub.flutter-io.cn" 50 | source: hosted 51 | version: "1.3.1" 52 | flutter: 53 | dependency: "direct main" 54 | description: flutter 55 | source: sdk 56 | version: "0.0.0" 57 | flutter_lints: 58 | dependency: "direct dev" 59 | description: 60 | name: flutter_lints 61 | sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c 62 | url: "https://pub.flutter-io.cn" 63 | source: hosted 64 | version: "2.0.1" 65 | flutter_test: 66 | dependency: "direct dev" 67 | description: flutter 68 | source: sdk 69 | version: "0.0.0" 70 | flutter_web_plugins: 71 | dependency: "direct main" 72 | description: flutter 73 | source: sdk 74 | version: "0.0.0" 75 | js: 76 | dependency: transitive 77 | description: 78 | name: js 79 | sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" 80 | url: "https://pub.flutter-io.cn" 81 | source: hosted 82 | version: "0.6.5" 83 | lints: 84 | dependency: transitive 85 | description: 86 | name: lints 87 | sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" 88 | url: "https://pub.flutter-io.cn" 89 | source: hosted 90 | version: "2.0.1" 91 | matcher: 92 | dependency: transitive 93 | description: 94 | name: matcher 95 | sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" 96 | url: "https://pub.flutter-io.cn" 97 | source: hosted 98 | version: "0.12.13" 99 | material_color_utilities: 100 | dependency: transitive 101 | description: 102 | name: material_color_utilities 103 | sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 104 | url: "https://pub.flutter-io.cn" 105 | source: hosted 106 | version: "0.2.0" 107 | meta: 108 | dependency: transitive 109 | description: 110 | name: meta 111 | sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" 112 | url: "https://pub.flutter-io.cn" 113 | source: hosted 114 | version: "1.8.0" 115 | path: 116 | dependency: transitive 117 | description: 118 | name: path 119 | sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b 120 | url: "https://pub.flutter-io.cn" 121 | source: hosted 122 | version: "1.8.2" 123 | plugin_platform_interface: 124 | dependency: "direct main" 125 | description: 126 | name: plugin_platform_interface 127 | sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a 128 | url: "https://pub.flutter-io.cn" 129 | source: hosted 130 | version: "2.1.3" 131 | sky_engine: 132 | dependency: transitive 133 | description: flutter 134 | source: sdk 135 | version: "0.0.99" 136 | source_span: 137 | dependency: transitive 138 | description: 139 | name: source_span 140 | sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 141 | url: "https://pub.flutter-io.cn" 142 | source: hosted 143 | version: "1.9.1" 144 | stack_trace: 145 | dependency: transitive 146 | description: 147 | name: stack_trace 148 | sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 149 | url: "https://pub.flutter-io.cn" 150 | source: hosted 151 | version: "1.11.0" 152 | stream_channel: 153 | dependency: transitive 154 | description: 155 | name: stream_channel 156 | sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" 157 | url: "https://pub.flutter-io.cn" 158 | source: hosted 159 | version: "2.1.1" 160 | string_scanner: 161 | dependency: transitive 162 | description: 163 | name: string_scanner 164 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 165 | url: "https://pub.flutter-io.cn" 166 | source: hosted 167 | version: "1.2.0" 168 | term_glyph: 169 | dependency: transitive 170 | description: 171 | name: term_glyph 172 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 173 | url: "https://pub.flutter-io.cn" 174 | source: hosted 175 | version: "1.2.1" 176 | test_api: 177 | dependency: transitive 178 | description: 179 | name: test_api 180 | sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 181 | url: "https://pub.flutter-io.cn" 182 | source: hosted 183 | version: "0.4.16" 184 | vector_math: 185 | dependency: transitive 186 | description: 187 | name: vector_math 188 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 189 | url: "https://pub.flutter-io.cn" 190 | source: hosted 191 | version: "2.1.4" 192 | sdks: 193 | dart: ">=2.18.0 <4.0.0" 194 | flutter: ">=3.0.0" 195 | -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 9 | url: "https://pub.flutter-io.cn" 10 | source: hosted 11 | version: "2.10.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.flutter-io.cn" 18 | source: hosted 19 | version: "2.1.1" 20 | characters: 21 | dependency: transitive 22 | description: 23 | name: characters 24 | sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c 25 | url: "https://pub.flutter-io.cn" 26 | source: hosted 27 | version: "1.2.1" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 33 | url: "https://pub.flutter-io.cn" 34 | source: hosted 35 | version: "1.1.1" 36 | collection: 37 | dependency: transitive 38 | description: 39 | name: collection 40 | sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 41 | url: "https://pub.flutter-io.cn" 42 | source: hosted 43 | version: "1.17.0" 44 | cross_file: 45 | dependency: transitive 46 | description: 47 | name: cross_file 48 | sha256: f71079978789bc2fe78d79227f1f8cfe195b31bbd8db2399b0d15a4b96fb843b 49 | url: "https://pub.flutter-io.cn" 50 | source: hosted 51 | version: "0.3.3+2" 52 | cupertino_icons: 53 | dependency: "direct main" 54 | description: 55 | name: cupertino_icons 56 | sha256: a937da4c006989739ceb4d10e3bd6cce64ca85d0fe287fc5b2b9f6ee757dcee6 57 | url: "https://pub.flutter-io.cn" 58 | source: hosted 59 | version: "0.1.3" 60 | fake_async: 61 | dependency: transitive 62 | description: 63 | name: fake_async 64 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 65 | url: "https://pub.flutter-io.cn" 66 | source: hosted 67 | version: "1.3.1" 68 | flutter: 69 | dependency: "direct main" 70 | description: flutter 71 | source: sdk 72 | version: "0.0.0" 73 | flutter_plugin_android_lifecycle: 74 | dependency: transitive 75 | description: 76 | name: flutter_plugin_android_lifecycle 77 | sha256: "60fc7b78455b94e6de2333d2f95196d32cf5c22f4b0b0520a628804cb463503b" 78 | url: "https://pub.flutter-io.cn" 79 | source: hosted 80 | version: "2.0.7" 81 | flutter_test: 82 | dependency: "direct dev" 83 | description: flutter 84 | source: sdk 85 | version: "0.0.0" 86 | flutter_web_plugins: 87 | dependency: transitive 88 | description: flutter 89 | source: sdk 90 | version: "0.0.0" 91 | http: 92 | dependency: transitive 93 | description: 94 | name: http 95 | sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" 96 | url: "https://pub.flutter-io.cn" 97 | source: hosted 98 | version: "0.13.5" 99 | http_parser: 100 | dependency: transitive 101 | description: 102 | name: http_parser 103 | sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" 104 | url: "https://pub.flutter-io.cn" 105 | source: hosted 106 | version: "4.0.2" 107 | image_picker: 108 | dependency: "direct dev" 109 | description: 110 | name: image_picker 111 | sha256: "401a3a3cb3efbfacad692335b70f36c4e86af01380c25d9a73d5a980a521cc02" 112 | url: "https://pub.flutter-io.cn" 113 | source: hosted 114 | version: "0.8.4+2" 115 | image_picker_for_web: 116 | dependency: transitive 117 | description: 118 | name: image_picker_for_web 119 | sha256: "111b14052ba8a06528487abcb579c152efee06c33b5d109154ce424d97139e10" 120 | url: "https://pub.flutter-io.cn" 121 | source: hosted 122 | version: "2.1.3" 123 | image_picker_platform_interface: 124 | dependency: transitive 125 | description: 126 | name: image_picker_platform_interface 127 | sha256: "7cef2f28f4f2fef99180f636c3d446b4ccbafd6ba0fad2adc9a80c4040f656b8" 128 | url: "https://pub.flutter-io.cn" 129 | source: hosted 130 | version: "2.6.2" 131 | js: 132 | dependency: transitive 133 | description: 134 | name: js 135 | sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" 136 | url: "https://pub.flutter-io.cn" 137 | source: hosted 138 | version: "0.6.5" 139 | matcher: 140 | dependency: transitive 141 | description: 142 | name: matcher 143 | sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" 144 | url: "https://pub.flutter-io.cn" 145 | source: hosted 146 | version: "0.12.13" 147 | material_color_utilities: 148 | dependency: transitive 149 | description: 150 | name: material_color_utilities 151 | sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 152 | url: "https://pub.flutter-io.cn" 153 | source: hosted 154 | version: "0.2.0" 155 | meta: 156 | dependency: transitive 157 | description: 158 | name: meta 159 | sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" 160 | url: "https://pub.flutter-io.cn" 161 | source: hosted 162 | version: "1.8.0" 163 | path: 164 | dependency: transitive 165 | description: 166 | name: path 167 | sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b 168 | url: "https://pub.flutter-io.cn" 169 | source: hosted 170 | version: "1.8.2" 171 | plugin_platform_interface: 172 | dependency: transitive 173 | description: 174 | name: plugin_platform_interface 175 | sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a 176 | url: "https://pub.flutter-io.cn" 177 | source: hosted 178 | version: "2.1.3" 179 | qrcode_flutter: 180 | dependency: "direct dev" 181 | description: 182 | path: ".." 183 | relative: true 184 | source: path 185 | version: "3.0.0-nullsafety.0" 186 | sky_engine: 187 | dependency: transitive 188 | description: flutter 189 | source: sdk 190 | version: "0.0.99" 191 | source_span: 192 | dependency: transitive 193 | description: 194 | name: source_span 195 | sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 196 | url: "https://pub.flutter-io.cn" 197 | source: hosted 198 | version: "1.9.1" 199 | stack_trace: 200 | dependency: transitive 201 | description: 202 | name: stack_trace 203 | sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 204 | url: "https://pub.flutter-io.cn" 205 | source: hosted 206 | version: "1.11.0" 207 | stream_channel: 208 | dependency: transitive 209 | description: 210 | name: stream_channel 211 | sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" 212 | url: "https://pub.flutter-io.cn" 213 | source: hosted 214 | version: "2.1.1" 215 | string_scanner: 216 | dependency: transitive 217 | description: 218 | name: string_scanner 219 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 220 | url: "https://pub.flutter-io.cn" 221 | source: hosted 222 | version: "1.2.0" 223 | term_glyph: 224 | dependency: transitive 225 | description: 226 | name: term_glyph 227 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 228 | url: "https://pub.flutter-io.cn" 229 | source: hosted 230 | version: "1.2.1" 231 | test_api: 232 | dependency: transitive 233 | description: 234 | name: test_api 235 | sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 236 | url: "https://pub.flutter-io.cn" 237 | source: hosted 238 | version: "0.4.16" 239 | typed_data: 240 | dependency: transitive 241 | description: 242 | name: typed_data 243 | sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" 244 | url: "https://pub.flutter-io.cn" 245 | source: hosted 246 | version: "1.3.1" 247 | vector_math: 248 | dependency: transitive 249 | description: 250 | name: vector_math 251 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 252 | url: "https://pub.flutter-io.cn" 253 | source: hosted 254 | version: "2.1.4" 255 | sdks: 256 | dart: ">=2.18.0 <3.0.0" 257 | flutter: ">=3.0.0" 258 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 270FF563EC6CB398E10062E0 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4568B750FD61735D0D5F7590 /* Pods_Runner.framework */; }; 12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 13 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 14 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 15 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 16 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXCopyFilesBuildPhase section */ 20 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 21 | isa = PBXCopyFilesBuildPhase; 22 | buildActionMask = 2147483647; 23 | dstPath = ""; 24 | dstSubfolderSpec = 10; 25 | files = ( 26 | ); 27 | name = "Embed Frameworks"; 28 | runOnlyForDeploymentPostprocessing = 0; 29 | }; 30 | /* End PBXCopyFilesBuildPhase section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 030E79E72981374609AE8FF3 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 34 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 35 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 36 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 37 | 4568B750FD61735D0D5F7590 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 39 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 40 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 41 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 42 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 43 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 45 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 46 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 47 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 48 | B64CCA17FBF26C1F0C552B9B /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 49 | FA9916945E5ADC3CC5639B3C /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | 270FF563EC6CB398E10062E0 /* Pods_Runner.framework in Frameworks */, 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | 257062D195F7C9D261CDE970 /* Frameworks */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 4568B750FD61735D0D5F7590 /* Pods_Runner.framework */, 68 | ); 69 | name = Frameworks; 70 | sourceTree = ""; 71 | }; 72 | 4DC3131724F7F14DC38836F4 /* Pods */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | 030E79E72981374609AE8FF3 /* Pods-Runner.debug.xcconfig */, 76 | FA9916945E5ADC3CC5639B3C /* Pods-Runner.release.xcconfig */, 77 | B64CCA17FBF26C1F0C552B9B /* Pods-Runner.profile.xcconfig */, 78 | ); 79 | path = Pods; 80 | sourceTree = ""; 81 | }; 82 | 9740EEB11CF90186004384FC /* Flutter */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 86 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 87 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 88 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 89 | ); 90 | name = Flutter; 91 | sourceTree = ""; 92 | }; 93 | 97C146E51CF9000F007C117D = { 94 | isa = PBXGroup; 95 | children = ( 96 | 9740EEB11CF90186004384FC /* Flutter */, 97 | 97C146F01CF9000F007C117D /* Runner */, 98 | 97C146EF1CF9000F007C117D /* Products */, 99 | 4DC3131724F7F14DC38836F4 /* Pods */, 100 | 257062D195F7C9D261CDE970 /* Frameworks */, 101 | ); 102 | sourceTree = ""; 103 | }; 104 | 97C146EF1CF9000F007C117D /* Products */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 97C146EE1CF9000F007C117D /* Runner.app */, 108 | ); 109 | name = Products; 110 | sourceTree = ""; 111 | }; 112 | 97C146F01CF9000F007C117D /* Runner */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 116 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 117 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 118 | 97C147021CF9000F007C117D /* Info.plist */, 119 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 120 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 121 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 122 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 123 | ); 124 | path = Runner; 125 | sourceTree = ""; 126 | }; 127 | /* End PBXGroup section */ 128 | 129 | /* Begin PBXNativeTarget section */ 130 | 97C146ED1CF9000F007C117D /* Runner */ = { 131 | isa = PBXNativeTarget; 132 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 133 | buildPhases = ( 134 | 2F7D5257E9F2CBA4042814D9 /* [CP] Check Pods Manifest.lock */, 135 | 9740EEB61CF901F6004384FC /* Run Script */, 136 | 97C146EA1CF9000F007C117D /* Sources */, 137 | 97C146EB1CF9000F007C117D /* Frameworks */, 138 | 97C146EC1CF9000F007C117D /* Resources */, 139 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 140 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 141 | C83E3AF023960BF40632C969 /* [CP] Embed Pods Frameworks */, 142 | ); 143 | buildRules = ( 144 | ); 145 | dependencies = ( 146 | ); 147 | name = Runner; 148 | productName = Runner; 149 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 150 | productType = "com.apple.product-type.application"; 151 | }; 152 | /* End PBXNativeTarget section */ 153 | 154 | /* Begin PBXProject section */ 155 | 97C146E61CF9000F007C117D /* Project object */ = { 156 | isa = PBXProject; 157 | attributes = { 158 | LastUpgradeCheck = 1300; 159 | ORGANIZATIONNAME = ""; 160 | TargetAttributes = { 161 | 97C146ED1CF9000F007C117D = { 162 | CreatedOnToolsVersion = 7.3.1; 163 | LastSwiftMigration = 1100; 164 | }; 165 | }; 166 | }; 167 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 168 | compatibilityVersion = "Xcode 9.3"; 169 | developmentRegion = en; 170 | hasScannedForEncodings = 0; 171 | knownRegions = ( 172 | en, 173 | Base, 174 | ); 175 | mainGroup = 97C146E51CF9000F007C117D; 176 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 177 | projectDirPath = ""; 178 | projectRoot = ""; 179 | targets = ( 180 | 97C146ED1CF9000F007C117D /* Runner */, 181 | ); 182 | }; 183 | /* End PBXProject section */ 184 | 185 | /* Begin PBXResourcesBuildPhase section */ 186 | 97C146EC1CF9000F007C117D /* Resources */ = { 187 | isa = PBXResourcesBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 191 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 192 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 193 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 194 | ); 195 | runOnlyForDeploymentPostprocessing = 0; 196 | }; 197 | /* End PBXResourcesBuildPhase section */ 198 | 199 | /* Begin PBXShellScriptBuildPhase section */ 200 | 2F7D5257E9F2CBA4042814D9 /* [CP] Check Pods Manifest.lock */ = { 201 | isa = PBXShellScriptBuildPhase; 202 | buildActionMask = 2147483647; 203 | files = ( 204 | ); 205 | inputFileListPaths = ( 206 | ); 207 | inputPaths = ( 208 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 209 | "${PODS_ROOT}/Manifest.lock", 210 | ); 211 | name = "[CP] Check Pods Manifest.lock"; 212 | outputFileListPaths = ( 213 | ); 214 | outputPaths = ( 215 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 216 | ); 217 | runOnlyForDeploymentPostprocessing = 0; 218 | shellPath = /bin/sh; 219 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 220 | showEnvVarsInLog = 0; 221 | }; 222 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 223 | isa = PBXShellScriptBuildPhase; 224 | alwaysOutOfDate = 1; 225 | buildActionMask = 2147483647; 226 | files = ( 227 | ); 228 | inputPaths = ( 229 | ); 230 | name = "Thin Binary"; 231 | outputPaths = ( 232 | ); 233 | runOnlyForDeploymentPostprocessing = 0; 234 | shellPath = /bin/sh; 235 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 236 | }; 237 | 9740EEB61CF901F6004384FC /* Run Script */ = { 238 | isa = PBXShellScriptBuildPhase; 239 | alwaysOutOfDate = 1; 240 | buildActionMask = 2147483647; 241 | files = ( 242 | ); 243 | inputPaths = ( 244 | ); 245 | name = "Run Script"; 246 | outputPaths = ( 247 | ); 248 | runOnlyForDeploymentPostprocessing = 0; 249 | shellPath = /bin/sh; 250 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 251 | }; 252 | C83E3AF023960BF40632C969 /* [CP] Embed Pods Frameworks */ = { 253 | isa = PBXShellScriptBuildPhase; 254 | buildActionMask = 2147483647; 255 | files = ( 256 | ); 257 | inputFileListPaths = ( 258 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", 259 | ); 260 | name = "[CP] Embed Pods Frameworks"; 261 | outputFileListPaths = ( 262 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", 263 | ); 264 | runOnlyForDeploymentPostprocessing = 0; 265 | shellPath = /bin/sh; 266 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 267 | showEnvVarsInLog = 0; 268 | }; 269 | /* End PBXShellScriptBuildPhase section */ 270 | 271 | /* Begin PBXSourcesBuildPhase section */ 272 | 97C146EA1CF9000F007C117D /* Sources */ = { 273 | isa = PBXSourcesBuildPhase; 274 | buildActionMask = 2147483647; 275 | files = ( 276 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 277 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 278 | ); 279 | runOnlyForDeploymentPostprocessing = 0; 280 | }; 281 | /* End PBXSourcesBuildPhase section */ 282 | 283 | /* Begin PBXVariantGroup section */ 284 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 285 | isa = PBXVariantGroup; 286 | children = ( 287 | 97C146FB1CF9000F007C117D /* Base */, 288 | ); 289 | name = Main.storyboard; 290 | sourceTree = ""; 291 | }; 292 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 293 | isa = PBXVariantGroup; 294 | children = ( 295 | 97C147001CF9000F007C117D /* Base */, 296 | ); 297 | name = LaunchScreen.storyboard; 298 | sourceTree = ""; 299 | }; 300 | /* End PBXVariantGroup section */ 301 | 302 | /* Begin XCBuildConfiguration section */ 303 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 304 | isa = XCBuildConfiguration; 305 | buildSettings = { 306 | ALWAYS_SEARCH_USER_PATHS = NO; 307 | CLANG_ANALYZER_NONNULL = YES; 308 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 309 | CLANG_CXX_LIBRARY = "libc++"; 310 | CLANG_ENABLE_MODULES = YES; 311 | CLANG_ENABLE_OBJC_ARC = YES; 312 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 313 | CLANG_WARN_BOOL_CONVERSION = YES; 314 | CLANG_WARN_COMMA = YES; 315 | CLANG_WARN_CONSTANT_CONVERSION = YES; 316 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 317 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 318 | CLANG_WARN_EMPTY_BODY = YES; 319 | CLANG_WARN_ENUM_CONVERSION = YES; 320 | CLANG_WARN_INFINITE_RECURSION = YES; 321 | CLANG_WARN_INT_CONVERSION = YES; 322 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 323 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 324 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 325 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 326 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 327 | CLANG_WARN_STRICT_PROTOTYPES = YES; 328 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 329 | CLANG_WARN_UNREACHABLE_CODE = YES; 330 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 331 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 332 | COPY_PHASE_STRIP = NO; 333 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 334 | ENABLE_NS_ASSERTIONS = NO; 335 | ENABLE_STRICT_OBJC_MSGSEND = YES; 336 | GCC_C_LANGUAGE_STANDARD = gnu99; 337 | GCC_NO_COMMON_BLOCKS = YES; 338 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 339 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 340 | GCC_WARN_UNDECLARED_SELECTOR = YES; 341 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 342 | GCC_WARN_UNUSED_FUNCTION = YES; 343 | GCC_WARN_UNUSED_VARIABLE = YES; 344 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 345 | MTL_ENABLE_DEBUG_INFO = NO; 346 | SDKROOT = iphoneos; 347 | SUPPORTED_PLATFORMS = iphoneos; 348 | TARGETED_DEVICE_FAMILY = "1,2"; 349 | VALIDATE_PRODUCT = YES; 350 | }; 351 | name = Profile; 352 | }; 353 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 354 | isa = XCBuildConfiguration; 355 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 356 | buildSettings = { 357 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 358 | CLANG_ENABLE_MODULES = YES; 359 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 360 | DEVELOPMENT_TEAM = L53UC8DFTK; 361 | ENABLE_BITCODE = NO; 362 | INFOPLIST_FILE = Runner/Info.plist; 363 | LD_RUNPATH_SEARCH_PATHS = ( 364 | "$(inherited)", 365 | "@executable_path/Frameworks", 366 | ); 367 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 368 | PRODUCT_NAME = "$(TARGET_NAME)"; 369 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 370 | SWIFT_VERSION = 5.0; 371 | VERSIONING_SYSTEM = "apple-generic"; 372 | }; 373 | name = Profile; 374 | }; 375 | 97C147031CF9000F007C117D /* Debug */ = { 376 | isa = XCBuildConfiguration; 377 | buildSettings = { 378 | ALWAYS_SEARCH_USER_PATHS = NO; 379 | CLANG_ANALYZER_NONNULL = YES; 380 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 381 | CLANG_CXX_LIBRARY = "libc++"; 382 | CLANG_ENABLE_MODULES = YES; 383 | CLANG_ENABLE_OBJC_ARC = YES; 384 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 385 | CLANG_WARN_BOOL_CONVERSION = YES; 386 | CLANG_WARN_COMMA = YES; 387 | CLANG_WARN_CONSTANT_CONVERSION = YES; 388 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 389 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 390 | CLANG_WARN_EMPTY_BODY = YES; 391 | CLANG_WARN_ENUM_CONVERSION = YES; 392 | CLANG_WARN_INFINITE_RECURSION = YES; 393 | CLANG_WARN_INT_CONVERSION = YES; 394 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 395 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 396 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 397 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 398 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 399 | CLANG_WARN_STRICT_PROTOTYPES = YES; 400 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 401 | CLANG_WARN_UNREACHABLE_CODE = YES; 402 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 403 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 404 | COPY_PHASE_STRIP = NO; 405 | DEBUG_INFORMATION_FORMAT = dwarf; 406 | ENABLE_STRICT_OBJC_MSGSEND = YES; 407 | ENABLE_TESTABILITY = YES; 408 | GCC_C_LANGUAGE_STANDARD = gnu99; 409 | GCC_DYNAMIC_NO_PIC = NO; 410 | GCC_NO_COMMON_BLOCKS = YES; 411 | GCC_OPTIMIZATION_LEVEL = 0; 412 | GCC_PREPROCESSOR_DEFINITIONS = ( 413 | "DEBUG=1", 414 | "$(inherited)", 415 | ); 416 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 417 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 418 | GCC_WARN_UNDECLARED_SELECTOR = YES; 419 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 420 | GCC_WARN_UNUSED_FUNCTION = YES; 421 | GCC_WARN_UNUSED_VARIABLE = YES; 422 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 423 | MTL_ENABLE_DEBUG_INFO = YES; 424 | ONLY_ACTIVE_ARCH = YES; 425 | SDKROOT = iphoneos; 426 | TARGETED_DEVICE_FAMILY = "1,2"; 427 | }; 428 | name = Debug; 429 | }; 430 | 97C147041CF9000F007C117D /* Release */ = { 431 | isa = XCBuildConfiguration; 432 | buildSettings = { 433 | ALWAYS_SEARCH_USER_PATHS = NO; 434 | CLANG_ANALYZER_NONNULL = YES; 435 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 436 | CLANG_CXX_LIBRARY = "libc++"; 437 | CLANG_ENABLE_MODULES = YES; 438 | CLANG_ENABLE_OBJC_ARC = YES; 439 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 440 | CLANG_WARN_BOOL_CONVERSION = YES; 441 | CLANG_WARN_COMMA = YES; 442 | CLANG_WARN_CONSTANT_CONVERSION = YES; 443 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 444 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 445 | CLANG_WARN_EMPTY_BODY = YES; 446 | CLANG_WARN_ENUM_CONVERSION = YES; 447 | CLANG_WARN_INFINITE_RECURSION = YES; 448 | CLANG_WARN_INT_CONVERSION = YES; 449 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 450 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 451 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 452 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 453 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 454 | CLANG_WARN_STRICT_PROTOTYPES = YES; 455 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 456 | CLANG_WARN_UNREACHABLE_CODE = YES; 457 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 458 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 459 | COPY_PHASE_STRIP = NO; 460 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 461 | ENABLE_NS_ASSERTIONS = NO; 462 | ENABLE_STRICT_OBJC_MSGSEND = YES; 463 | GCC_C_LANGUAGE_STANDARD = gnu99; 464 | GCC_NO_COMMON_BLOCKS = YES; 465 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 466 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 467 | GCC_WARN_UNDECLARED_SELECTOR = YES; 468 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 469 | GCC_WARN_UNUSED_FUNCTION = YES; 470 | GCC_WARN_UNUSED_VARIABLE = YES; 471 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 472 | MTL_ENABLE_DEBUG_INFO = NO; 473 | SDKROOT = iphoneos; 474 | SUPPORTED_PLATFORMS = iphoneos; 475 | SWIFT_COMPILATION_MODE = wholemodule; 476 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 477 | TARGETED_DEVICE_FAMILY = "1,2"; 478 | VALIDATE_PRODUCT = YES; 479 | }; 480 | name = Release; 481 | }; 482 | 97C147061CF9000F007C117D /* Debug */ = { 483 | isa = XCBuildConfiguration; 484 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 485 | buildSettings = { 486 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 487 | CLANG_ENABLE_MODULES = YES; 488 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 489 | DEVELOPMENT_TEAM = L53UC8DFTK; 490 | ENABLE_BITCODE = NO; 491 | INFOPLIST_FILE = Runner/Info.plist; 492 | LD_RUNPATH_SEARCH_PATHS = ( 493 | "$(inherited)", 494 | "@executable_path/Frameworks", 495 | ); 496 | PRODUCT_BUNDLE_IDENTIFIER = "com.qrcode-example"; 497 | PRODUCT_NAME = "$(TARGET_NAME)"; 498 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 499 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 500 | SWIFT_VERSION = 5.0; 501 | VERSIONING_SYSTEM = "apple-generic"; 502 | }; 503 | name = Debug; 504 | }; 505 | 97C147071CF9000F007C117D /* Release */ = { 506 | isa = XCBuildConfiguration; 507 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 508 | buildSettings = { 509 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 510 | CLANG_ENABLE_MODULES = YES; 511 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 512 | DEVELOPMENT_TEAM = L53UC8DFTK; 513 | ENABLE_BITCODE = NO; 514 | INFOPLIST_FILE = Runner/Info.plist; 515 | LD_RUNPATH_SEARCH_PATHS = ( 516 | "$(inherited)", 517 | "@executable_path/Frameworks", 518 | ); 519 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 520 | PRODUCT_NAME = "$(TARGET_NAME)"; 521 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 522 | SWIFT_VERSION = 5.0; 523 | VERSIONING_SYSTEM = "apple-generic"; 524 | }; 525 | name = Release; 526 | }; 527 | /* End XCBuildConfiguration section */ 528 | 529 | /* Begin XCConfigurationList section */ 530 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 531 | isa = XCConfigurationList; 532 | buildConfigurations = ( 533 | 97C147031CF9000F007C117D /* Debug */, 534 | 97C147041CF9000F007C117D /* Release */, 535 | 249021D3217E4FDB00AE95B9 /* Profile */, 536 | ); 537 | defaultConfigurationIsVisible = 0; 538 | defaultConfigurationName = Release; 539 | }; 540 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 541 | isa = XCConfigurationList; 542 | buildConfigurations = ( 543 | 97C147061CF9000F007C117D /* Debug */, 544 | 97C147071CF9000F007C117D /* Release */, 545 | 249021D4217E4FDB00AE95B9 /* Profile */, 546 | ); 547 | defaultConfigurationIsVisible = 0; 548 | defaultConfigurationName = Release; 549 | }; 550 | /* End XCConfigurationList section */ 551 | }; 552 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 553 | } 554 | --------------------------------------------------------------------------------