diff --git a/.gitignore b/.gitignore index 94ca90d..ae1f183 100644 --- a/.gitignore +++ b/.gitignore @@ -1,87 +1,37 @@ -# ---> Android -# Built application files -*.apk -*.aar -*.ap_ -*.aab - -# Files for the ART/Dalvik VM -*.dex - -# Java class files +# Miscellaneous *.class - -# Generated files -bin/ -gen/ -out/ -# Uncomment the following line in case you need and you don't have the release build type files in your app -# release/ - -# Gradle files -.gradle/ -build/ - -# Local configuration file (sdk path, etc) -local.properties - -# Proguard folder generated by Eclipse -proguard/ - -# Log Files *.log - -# Android Studio Navigation editor temp files -.navigation/ - -# Android Studio captures folder -captures/ - -# IntelliJ +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related *.iml -.idea/workspace.xml -.idea/tasks.xml -.idea/gradle.xml -.idea/assetWizardSettings.xml -.idea/dictionaries -.idea/libraries -# Android Studio 3 in .gitignore file. -.idea/caches -.idea/modules.xml -# Comment next line if keeping position of elements in Navigation Editor is relevant for you -.idea/navEditor.xml - -# Keystore files -# Uncomment the following lines if you do not want to check your keystore files in. -#*.jks -#*.keystore - -# External native build folder generated in Android Studio 2.2 and later -.externalNativeBuild -.cxx/ - -# Google Services (e.g. APIs or Firebase) -# google-services.json - -# Freeline -freeline.py -freeline/ -freeline_project_description.json - -# fastlane -fastlane/report.xml -fastlane/Preview.html -fastlane/screenshots -fastlane/test_output -fastlane/readme.md - -# Version control -vcs.xml - -# lint -lint/intermediates/ -lint/generated/ -lint/outputs/ -lint/tmp/ -# lint/reports/ - +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Exceptions to above rules. +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/.metadata b/.metadata new file mode 100644 index 0000000..4adf4bf --- /dev/null +++ b/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: f139b11009aeb8ed2a3a3aa8b0066e482709dde3 + channel: stable + +project_type: app diff --git a/README.md b/README.md index 87b8799..ebc299c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,16 @@ -# Unit-App +# unitstocks -flutter app untuk unitstock \ No newline at end of file +App to stock Thamrin Brothers Units + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..bc2100d --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,7 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 0000000..9cadf73 --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,108 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply plugin: 'com.google.protobuf' +apply plugin: 'kotlin-android' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +protobuf { + protoc { + artifact = 'com.google.protobuf:protoc:3.8.0' + } + plugins { + javalite { + artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0' + } + grpc { + artifact = 'io.grpc:protoc-gen-grpc-java:1.0.0-pre2' + } + } + generateProtoTasks { + all().each { task -> + task.builtins { + remove java + } + task.plugins { + javalite { } + grpc { + option 'lite' + } + } + } + } +} + +def keystoreProperties = new Properties() +def keystorePropertiesFile = rootProject.file('key.properties') +if (keystorePropertiesFile.exists()) { + keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) +} + +android { + compileSdkVersion 29 + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.thamringroup.unitstocks" + minSdkVersion 18 + targetSdkVersion 29 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + signingConfigs { + release { + keyAlias keystoreProperties['keyAlias'] + keyPassword keystoreProperties['keyPassword'] + storeFile keystoreProperties['storeFile'] ? rootProject.file(keystoreProperties['storeFile']) : null + storePassword keystoreProperties['storePassword'] + } + } + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.release + } + } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' +} diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..42ba5a7 --- /dev/null +++ b/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..dcfa65d --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/thamringroup/hris/unitstocks/MainActivity.kt b/android/app/src/main/kotlin/com/thamringroup/hris/unitstocks/MainActivity.kt new file mode 100644 index 0000000..d844a62 --- /dev/null +++ b/android/app/src/main/kotlin/com/thamringroup/hris/unitstocks/MainActivity.kt @@ -0,0 +1,12 @@ +package com.thamringroup.unitstocks + +import androidx.annotation.NonNull; +import io.flutter.embedding.android.FlutterActivity +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.plugins.GeneratedPluginRegistrant + +class MainActivity: FlutterActivity() { + override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { + GeneratedPluginRegistrant.registerWith(flutterEngine); + } +} diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..db77bb4 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/launcher_icon.png b/android/app/src/main/res/mipmap-hdpi/launcher_icon.png new file mode 100644 index 0000000..d55ec26 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/launcher_icon.png b/android/app/src/main/res/mipmap-mdpi/launcher_icon.png new file mode 100644 index 0000000..089f421 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png new file mode 100644 index 0000000..10b044f Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png new file mode 100644 index 0000000..d322750 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png new file mode 100644 index 0000000..e7d59c0 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..00fa441 --- /dev/null +++ b/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..42ba5a7 --- /dev/null +++ b/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000..65044f4 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,32 @@ +buildscript { + ext.kotlin_version = '1.3.50' + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.5.0' + classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.10' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000..150ede1 --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx5120M +android.enableR8=true +android.useAndroidX=true +android.enableJetifier=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..296b146 --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip diff --git a/android/key.properties b/android/key.properties new file mode 100644 index 0000000..9f02b55 --- /dev/null +++ b/android/key.properties @@ -0,0 +1,4 @@ +storePassword=Thamrin1234 +keyPassword=Thamrin1234 +keyAlias=key +storeFile=\\unitKey.jks diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..5a2f14f --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/android/unitKey.jks b/android/unitKey.jks new file mode 100644 index 0000000..e0511e7 Binary files /dev/null and b/android/unitKey.jks differ diff --git a/asset/icon.png b/asset/icon.png new file mode 100644 index 0000000..f13d7f7 Binary files /dev/null and b/asset/icon.png differ diff --git a/ios/.gitignore b/ios/.gitignore new file mode 100644 index 0000000..e96ef60 --- /dev/null +++ b/ios/.gitignore @@ -0,0 +1,32 @@ +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..6b4c0f7 --- /dev/null +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..0f94b90 --- /dev/null +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,518 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.thamringroup.unitstocks; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.thamringroup.unitstocks; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.thamringroup.unitstocks; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..a28140c --- /dev/null +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..70693e4 --- /dev/null +++ b/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..7b42fc4 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..1b0ecd7 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..e5d936a Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..1aff437 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..729704c Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..c07e1d9 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..a3e2f55 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..e5d936a Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..db82a86 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..ca7be23 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png new file mode 100644 index 0000000..35c36af Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png new file mode 100644 index 0000000..397800f Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png new file mode 100644 index 0000000..371c3e2 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png new file mode 100644 index 0000000..e15f751 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..ca7be23 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..b906a37 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png new file mode 100644 index 0000000..d55ec26 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png new file mode 100644 index 0000000..d322750 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..14070c3 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..fcd3028 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..f296dd4 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +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. \ No newline at end of file diff --git a/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist new file mode 100644 index 0000000..d503459 --- /dev/null +++ b/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + unitstocks + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/ios/Runner/Runner-Bridging-Header.h b/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..7335fdf --- /dev/null +++ b/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" \ No newline at end of file diff --git a/lib/Util/DBHelper.dart b/lib/Util/DBHelper.dart new file mode 100644 index 0000000..f6e9e69 --- /dev/null +++ b/lib/Util/DBHelper.dart @@ -0,0 +1,324 @@ +import 'dart:async'; +import 'dart:io' as io; +import 'UnitModel.dart'; +import 'package:path/path.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:sqflite/sqflite.dart'; +import 'Prefs.dart'; +import '../main.dart'; + +class DBHelper { + DBHelper._(); + + static final DBHelper database = DBHelper._(); + static Database _db; + + Future get db async { + if (_db != null) return _db; + _db = await initDb(); + return _db; + } + + initDb() async { + io.Directory documentsDirectory = await getApplicationDocumentsDirectory(); + String path = join(documentsDirectory.path, "UnitStocking.db"); + var theDb = await openDatabase(path, version: 1,onCreate: await _onCreate); + return theDb; + } + + closeDb() async { + final database = await db; + await database.close(); + _db = null; + } + + _onCreate(Database db, int version) async { + io.Directory documentsDirectory = await getApplicationDocumentsDirectory(); + String path = join(documentsDirectory.path, "UnitStocking.db"); + io.File file = io.File(path); + print('Database created, ${file.lengthSync()}'); + var res = await db.query(tableName.values,where: "${columnName.name} = ?",whereArgs: [keyClass.stock_id]); + valueTab value = valueTab.fromJson(res.first); + await prefs.setString(keyClass.stock_id, value.value); + } + + getCount(mesin) async { + final database = await db; + var res = + await database.rawQuery("SELECT COUNT(*) as count FROM ${tableName.blob} where ${columnName.mesin} = '$mesin'"); + return res.isNotEmpty ? Count.fromJson(res.first).count : 0; + } + + getUnitdetailMaster(id) async{ + try{ + final database = await db; + var res = await database.rawQuery("SELECT * FROM '${tableName.master}' WHERE ${columnName.id} = $id"); + return res.isNotEmpty ? Unit.fromJson(res.first) : null; + } + catch(e){ + print(e); + return null; + } + } + +// Future> getAllUnits() async { +// final database = await db; +// var res = await database.query("${tableName.master}"); +//// var res = await database.rawQuery("SELECT ${columnName.tipe} from ${tableName.}"); +//// var res = await database.rawQuery("SELECT b.${columnName.id}, b.${columnName.mesin}, b.${columnName.tipe}, b.${columnName.warna}, IFNULL((SELECT ${columnName.timestamp} from ${tableName.unit} where ${columnName.mesin} = b.${columnName.mesin}),'-') ${columnName.timestamp}, (SELECT ${columnName.id} from ${tableName.unit} where ${columnName.mesin} = b.${columnName.mesin}) ${columnName.mesin_id} from ${tableName.master} b"); +// List list = +// res.isNotEmpty ? res.map((c) => Unit.fromJson(c)).toList() : []; +// return list; +// } + + Future> getAllUnits({inserted=false}) async { + final database = await db; + var res = await database.query("${tableName.master}",where: (inserted)?"${columnName.flag} = 'TRUE'":null,orderBy: "CASE WHEN ${columnName.flag} = 'FALSE' THEN 0 ELSE 1 END, ${columnName.state} desc"); +// var res = await database.rawQuery("SELECT ${columnName.id}, ${columnName.mesin}, ${columnName.tipe}, ${columnName.state}, ${columnName.warna}, ${columnName.rangka},${columnName.kode},${columnName.flag}, ${columnName.timestamp} from ${tableName.master} ORDER BY CASE WHEN ${columnName.flag} = 'FALSE' THEN 0 ELSE 1 END, ${columnName.state} desc"); + List list = + res.isNotEmpty ? res.map((c) => Unit.fromJson(c)).toList() : []; + return list; + } + + Future> searchAllUnits(String query,{inserted:false}) async { + print("${(inserted)?"${columnName.flag} = 'TRUE' AND ":''} REPLACE(${columnName.mesin},'-','') like '%$query%' or ${columnName.rangka} like '%$query%' or ${columnName.mesin} like '%$query%' or ${columnName.timestamp} like '%$query%' or ${columnName.tipe} like '%$query%' or ${columnName.warna} like '%$query%' or UPPER(${columnName.state}) like '%$query%'"); + final database = await db; + try{ + var res = await database.query(tableName.master,where: "${(inserted)?"${columnName.flag} = 'TRUE' AND ":''} (REPLACE(${columnName.mesin},'-','') like '%$query%' or ${columnName.rangka} like '%$query%' or ${columnName.mesin} like '%$query%' or ${columnName.timestamp} like '%$query%' or ${columnName.tipe} like '%$query%' or ${columnName.warna} like '%$query%' or UPPER(${columnName.state}) like '%$query%')",orderBy: "CASE WHEN ${columnName.flag} = 'FALSE' THEN 0 ELSE 1 END, ${columnName.state} desc"); +// var res = await database.rawQuery( +// "select * from (SELECT ${columnName.id}, ${columnName.state}, ${columnName.rangka}, ${columnName.mesin}, ${columnName.tipe}, ${columnName.warna}, ${columnName.timestamp}, ${columnName.mesin} from ${tableName.master} ) where REPLACE(${columnName.mesin},'-','') like '%$query%' or ${columnName.rangka} like '%$query%' or ${columnName.mesin} like '%$query%' or ${columnName.timestamp} like '%$query%' or ${columnName.tipe} like '%$query%' or ${columnName.warna} like '%$query%' or UPPER(${columnName.state}) like '%$query%' ORDER BY CASE WHEN ${columnName.flag} = 'FALSE' THEN 0 ELSE 1 END, ${columnName.state} desc"); + List list = + res.isNotEmpty ? res.map((c) => Unit.fromJson(c)).toList() : []; + return list; + } + catch(e){ + print(e); + return []; + } + + } + +// Future> getAllInsertUnits() async { +// final database = await db; +//// var res = await database.query("${tableName.unit}"); +// var res = await database.rawQuery("SELECT a.${columnName.id},a.${columnName.mesin},b.${columnName.rangka},b.${columnName.tipe},b.${columnName.warna}, a.${columnName.timestamp}, b.${columnName.state} from ${tableName.unit} a, ${tableName.master} b where a.${columnName.mesin} = b.${columnName.mesin}"); +// List list = +// res.isNotEmpty ? res.map((c) => insertUnit.fromJson(c)).toList() : []; +// return list; +// } + +// Future> getAllBlobImage(mesin) async { +// final database = await db; +//// var res = await database.query("${tableName.blob}"); +// var res = await database.query("${tableName.blob}",where: "${columnName.mesin} = ?",whereArgs: [mesin]); +//// print([mesin_id,res]); +// +// List list = +// res.isNotEmpty ? res.map((c) => blobImage.fromJson(c)).toList() : []; +// return list; +// } + + getBlobUnits(mesin) async{ + try{ + final database = await db; + var res = await database.query("${tableName.blob}" ,where: "${columnName.mesin} = ?", whereArgs: [mesin]); + List list = + res.isNotEmpty ? res.map((c) => blobImage.fromJson(c)).toList() : []; + return list; + } + catch(e){ + print(e); + return null; + } + } + + insertUpdateBlob(blobImage blob) async{ + return (blob.blob_id==null)?newInsertBlob(blob):updateBlob(blob); + } + + deleteBlob(blob_id) async { + final database = await db; + try{ + await database.delete("${tableName.blob}", where: "${columnName.blob_id} = ?", whereArgs: [blob_id]); + return true; + } + catch(e){ + print(e); + return null; + } + } + + updateUnit(Unit unitUpdate) async{ + try{ + final database = await db; + var res = await database.update("${tableName.master}", unitUpdate.toJson(), + where: "${columnName.id} = ?", whereArgs: [unitUpdate.id]); + print('Row Updated'); + return res; + } + catch(e){ + print(e); + return null; + } + } + + updateBlob(blobImage blobUpdate) async{ + try{ + final database = await db; + var res = await database.update("${tableName.blob}", blobUpdate.toJson(), + where: "${columnName.blob_id} = ?", whereArgs: [blobUpdate.blob_id]); + print('Row Updated'); + return res; + } + catch(e){ + print(e); + return null; + } + } + + newInsertBlob(blobImage newBlob) async { + final database = await db; + try{ + var res = await database.rawInsert("Insert into ${tableName.blob}(${columnName.blob_file},${columnName.mesin},${columnName.lat},${columnName.long},${columnName.jenis})VALUES(?,?,?,?,?)", [ + newBlob.blob_file, + newBlob.mesin, + newBlob.lat, + newBlob.long, + newBlob.jenis + ]); + print('Image Inserted'); + return res; + } + catch(e){ + print(e); + return null; + } + } + + getBlobImage(mesin) async{ + final database = await db; + var res = await database.query("${tableName.blob}",where: "${columnName.mesin} = ? AND ${columnName.no_urut} = ?",whereArgs: [mesin,'1']); + return res.isNotEmpty ? blobImage.fromJson(res.first) : null; + } + +// Future> searchAllInsertUnits(String query) async { +// final database = await db; +// var res = await database.rawQuery( +// "select * from (SELECT a.${columnName.id},a.${columnName.mesin},b.${columnName.tipe},b.${columnName.warna}, a.${columnName.timestamp}, b.${columnName.state}, b.${columnName.rangka} from ${tableName.unit} a, ${tableName.master} b where a.${columnName.mesin} = b.${columnName.mesin}) where REPLACE(${columnName.mesin},'-','') like '%$query%' or ${columnName.mesin} like '%$query%' or ${columnName.timestamp} like '%$query%' or ${columnName.warna} like '%$query%' or ${columnName.tipe} like '%$query%'"); +// List list = +// res.isNotEmpty ? res.map((c) => insertUnit.fromJson(c)).toList() : []; +// return list; +// } +// +// updateInsertUnit(insertUnit newPart) async { +// try{ +// final database = await db; +//// var res = await database.update("${tableName.unit}", newPart.toJson(), +//// where: "${columnName.id} = ?", whereArgs: [newPart.id]); +// var res = await database.rawQuery("Update ${tableName.unit} SET ${columnName.id} = ${newPart.id}, ${columnName.mesin} = '${newPart.mesin}' WHERE ${columnName.id} = ${newPart.id}"); +// print('Row Updated'); +// return res; +// } +// catch(e){ +// print(e); +// return null; +// } +// } + + Future> getAllJenis() async { + try{ + final database = await db; + var res = await database.query("${tableName.jenis}"); +// var res = (id==null)?await database.query("${tableName.jenis}") :await database.rawQuery("select a.${columnName.value}, b.${columnName.jenis} from ${tableName.jenis} a, ${tableName.blob} b where a.${columnName.value} <> b.${columnName.jenis} AND b.${columnName.mesin_id} = $id"); +// print(res); + List list = + res.isNotEmpty ? res.map((c) => jenisDrop.fromJson(c)).toList() : []; + return list; + } + catch(e){ + print(e); + return null; + } + } + + getValue(value)async{ + try{ + final database = await db; + var res = await database.query(tableName.values,where: "${columnName.name} = ?",whereArgs: [value]); + return res.isEmpty?null:valueTab.fromJson(res.first); + } + catch(e){ + return null; + } + } + + insertUpdateValue(valueTab newValue)async{ + try{ + final database = await db; + var res = await database.rawQuery("Select Count(*) as count from ${tableName.values} where ${columnName.name} = '${newValue.name}'"); + int count = res.isNotEmpty ? Count.fromJson(res.first).count : 0; + return (count==0)?addNewValue(newValue):updateValue(newValue); + } + catch(e){ + print(e); + return null; + } + } + + updateValue(valueTab newValue) async { + try{ + final database = await db; + var res = await database.update("${tableName.values}", newValue.toJson(), + where: "${columnName.name} = ?", whereArgs: [newValue.name]); + print('Row Updated'); + return res; + } + catch(e){ + print(e); + return null; + } + } + + addNewValue(valueTab newValue) async { + final database = await db; + try{ + var res = await database.rawInsert("Insert into ${tableName.values}(${columnName.name},${columnName.value})VALUES(?,?)", [ + newValue.name, + newValue.value + ]); + print('Row Inserted'); + return res; + } + catch(e){ + print(e); + return null; + } + } + +// deleteInsertUnit(String id) async { +// final database = await db; +// try{ +// await database.delete("${tableName.unit}", where: "${columnName.id} = ?", whereArgs: [id]); +// return true; +// } +// catch(e){ +// print(e); +// return null; +// } +// } + + deleteAll() async { + final database = await db; + try{ + await database.rawQuery("DROP TABLE IF EXISTS ${tableName.blob}"); +// await database.rawQuery("DROP TABLE IF EXISTS ${tableName.unit}"); + await database.rawQuery("DROP TABLE IF EXISTS ${tableName.master}"); + return true; + } + catch(e){ + print(e); + return null; + } + } + +} diff --git a/lib/Util/Prefs.dart b/lib/Util/Prefs.dart new file mode 100644 index 0000000..7295e3d --- /dev/null +++ b/lib/Util/Prefs.dart @@ -0,0 +1,41 @@ +class keyClass{ + static String lastDownload = 'LAST_DOWNLOAD'; + static String lastUpload = 'LAST_UPLOAD'; + static String duration = 'DURATION'; + static String loginId = 'LOGIN_ID'; + static String hostAddress = 'HOST'; + static String company = 'COMPANY'; + static String user_id = 'USER'; + static String cabang_id = 'CABANG_ID'; + static String logged_in = 'LOGGED_IN'; + static String targetProccess = 'dbPath'; + static String submitProccess = 'SUBMIT'; + static String stock_id = 'STOCK_TAKING_UNIT_ID'; +} +class columnName{ + static String id = 'ID'; + static String mesin = 'MESIN'; + static String warna = 'WARNA'; + static String tipe = 'TIPE'; + static String rangka = 'RANGKA'; + static String kode = 'KODE'; + static String tahun = 'TAHUN'; + static String lat = 'LATITUDE'; + static String long = 'LONGITUDE'; + static String timestamp = 'TIMESTAMP'; + static String blob_id = 'BLOB_ID'; + static String blob_file = 'BLOB_FILE'; + static String name = 'NAME'; + static String value = 'VALUE'; + static String optional = 'OPTIONAL'; + static String jenis = 'JENIS'; + static String state = 'STATE'; + static String no_urut = 'NO_URUT'; + static String flag = 'FLAG_INSERT'; +} +class tableName{ + static String master = 'refTable'; + static String blob = 'blobTable'; + static String jenis = 'jenisBlobTable'; + static String values = 'valueTable'; +} \ No newline at end of file diff --git a/lib/Util/UnitModel.dart b/lib/Util/UnitModel.dart new file mode 100644 index 0000000..0b69e9e --- /dev/null +++ b/lib/Util/UnitModel.dart @@ -0,0 +1,149 @@ +import 'Prefs.dart'; + + +class Unit { + int id; + String rangka; + String mesin; + String kode; + String tahun; + String tipe; + String warna; + String state; + String flag; + String timestamp; + + + Unit({ + this.id, + this.rangka, + this.mesin, + this.kode, + this.tahun, + this.tipe, + this.warna, + this.state, + this.flag, + this.timestamp, + }); + + factory Unit.fromJson(Map json) { + return new Unit( + id: json[columnName.id], + rangka: json[columnName.rangka], + mesin: json[columnName.mesin], + kode: json[columnName.kode], + tahun: json[columnName.tahun], + tipe: json[columnName.tipe], + warna : json[columnName.warna], + state: json[columnName.state], + flag: json[columnName.flag], + timestamp: json[columnName.timestamp]??'' + );} + + Map toJson() => { + columnName.id: id, + columnName.rangka: rangka.toUpperCase(), + columnName.mesin : mesin.toUpperCase(), + columnName.kode : kode.toUpperCase(), + columnName.tahun : tahun, + columnName.tipe: tipe, + columnName.warna: warna, + columnName.state :state, + columnName.flag :flag, + columnName.timestamp :timestamp, + }; +} + +class blobImage { + int blob_id; + var blob_file; + String mesin; + String lat; + String long; + String jenis; + String no_urut; + + + blobImage({ + this.blob_id, + this.blob_file, + this.mesin, + this.lat, + this.long, + this.jenis, + this.no_urut + }); + + Map toJson() => { + columnName.blob_id: blob_id, + columnName.blob_file : blob_file, + columnName.mesin : mesin, + columnName.lat : lat, + columnName.long : long, + columnName.jenis : jenis, + columnName.no_urut : no_urut + }; + + factory blobImage.fromJson(Map json) => new blobImage( + blob_id: json[columnName.blob_id], + blob_file: json[columnName.blob_file], + mesin: json[columnName.mesin], + lat: json[columnName.lat], + long: json[columnName.long], + jenis: json[columnName.jenis], + no_urut: json[columnName.no_urut] + ); +} + +class valueTab { + String name; + String value; + + + valueTab({ + this.name, + this.value + }); + + Map toJson() => { + columnName.name : name, + columnName.value : value, + }; + + factory valueTab.fromJson(Map json) => new valueTab( + name: json[columnName.name], + value: json[columnName.value], + ); +} + +class jenisDrop { + String value; + String no_urut; + + jenisDrop({ + this.value, + this.no_urut + }); + + Map toJson() => { + columnName.value : value, + columnName.no_urut : no_urut + }; + + factory jenisDrop.fromJson(Map json) => new jenisDrop( + value: json[columnName.value], + no_urut: json[columnName.no_urut] + ); +} + +class Count { + int count; + Count({ + this.count, + }); + + factory Count.fromJson(Map json) => new Count( + count: json["count"], + ); +} diff --git a/lib/Util/Util.dart b/lib/Util/Util.dart new file mode 100644 index 0000000..8ad12e5 --- /dev/null +++ b/lib/Util/Util.dart @@ -0,0 +1,96 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; +import 'package:http/http.dart' as http; +import 'package:flutter/material.dart'; +import 'package:flushbar/flushbar.dart'; +import '../main.dart'; +import 'package:location/location.dart'; +import 'package:permission_handler/permission_handler.dart' as pHandler; +import 'package:app_settings/app_settings.dart'; + +class Util{ + JsonDataPostRaw(Map jsonData, String url,{timeout:false}) async{ + const JsonDecoder decoder = const JsonDecoder(); + try { + var response; + if (timeout) + response = await http.post( + '$url', headers: {'Content-type': 'application/json'}, + body: json.encode(jsonData)).timeout( + const Duration(seconds: 10)); + else + response = await http.post( + '$url', headers: {'Content-type': 'application/json'}, + body: json.encode(jsonData)); + final Map data = decoder.convert(response.body); + return data; + } on TimeoutException catch(e){ + return {"STATUS":0,"DATA":"Request Timeout"}; + } + on Exception catch(exception){ + print(url); +// Toast("Not Connected to Server", Colors.red); + return {"STATUS":0,"DATA":"Not Connected to Server. $exception"}; + } + } + + showLoading(context,{dissmissable=false,onwillpop}){ + showDialog( + context: context, + builder: (BuildContext context) { + return WillPopScope( + onWillPop: onwillpop??()async{return true;}, + child: new Center( + child: new CircularProgressIndicator(), + ), + ); + }, + barrierDismissible: dissmissable, + ); + } + + showFlushbar(context,text,{color:Colors.grey}){ + Flushbar( + message: "$text", + backgroundColor: color, + duration: Duration(seconds: 5), + )..show(context); + } + streamLocation(context)async{ + print('checking location'); + bool gpsEnabled = false; + pHandler.PermissionStatus permissionEnabled = await pHandler.Permission.locationWhenInUse.status; + if(await location.serviceEnabled()){ + gpsEnabled = await location.serviceEnabled(); + } + else{ + print('requesting gps'); + gpsEnabled = await location.requestService(); + await streamLocation(context); + } +// print([gpsEnabled,permissionEnabled]); + if(gpsEnabled){ + if(permissionEnabled == pHandler.PermissionStatus.granted){ + if(locationStream==null){ + locationStream = location.onLocationChanged.listen((LocationData event) { + currentPosisiton = event; + }); + } + } + else if(permissionEnabled==pHandler.PermissionStatus.denied || permissionEnabled==pHandler.PermissionStatus.undetermined){ + print('requesting permission'); + showFlushbar(context,'Location permission is needed to locate your REAL location. Please grant the permission!'); + await Future.delayed(Duration(seconds: 1)); + await pHandler.Permission.locationWhenInUse.request(); + await streamLocation(context); + } + else if (permissionEnabled==pHandler.PermissionStatus.permanentlyDenied){ + showFlushbar(context,'It seems, your system security explicitly denied the permission to access your location. Please MANUALLY enable it in setings!'); + await Future.delayed(Duration(seconds: 3)); + AppSettings.openAppSettings(); + exit(0); + } + } + } +} \ No newline at end of file diff --git a/lib/Util/download_Upload_Handler.dart b/lib/Util/download_Upload_Handler.dart new file mode 100644 index 0000000..2a83318 --- /dev/null +++ b/lib/Util/download_Upload_Handler.dart @@ -0,0 +1,154 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; +import 'dart:typed_data'; +import 'package:path_provider/path_provider.dart'; +import 'package:http/http.dart'; +class file_Trans_Handler { + +// double _progress = 0; + String _path = ''; + StreamSubscription dlulStream; + String _error = ''; + get path => _path; + get error => _error; + StreamController _progress = new StreamController(); + Stream get progress =>_progress.stream; + var client = new Client(); + + downloadFile(String fileName,String link) async { + StreamedResponse _response; + List _bytes = []; + int _total = 0; + print('Start Download'); + _progress.add(null); + try { + Request req = new Request('GET', Uri.parse(link)); +// req.headers = ''; + _response = await client.send(req).timeout( + Duration(seconds: 20)); +// _response = await client.get('$link',headers: 'application/json') + _total = _response.contentLength; + print('${_total / 1024} KB'); + dlulStream = _response.stream.listen((value) { + _bytes.addAll(value); + _progress.add(((_bytes.length / _total))); + }) + ..onDone(() async { + _progress.add(0.0); + print('Finish Download'); + final file = File( + "${(await getApplicationDocumentsDirectory()).path}/$fileName"); + await file.writeAsBytes(_bytes); + _path = file.path; + }) + ..onError((e) async { + print('Error Download, $e'); + _progress.add(-1.0); + _error = e.toString(); + }); + } + catch(e){ + print('Error Download, $e'); + _progress.add(-1.0); + _error = e.toString(); + } + } + + uploadFile(String fileName,String link,String company,String cabang_id) async{ + final file = File( + "${(await getApplicationDocumentsDirectory()).path}/$fileName"); + if(file.existsSync()){ + Uint8List byte = file.readAsBytesSync(); +// print("file size ${file.lengthSync()/1024}"); + try{ + var _reponse = await client.post( + '$link', headers: {'Content-type': 'application/json'}, + body: json.encode({"byte":byte,"cabangId":cabang_id,"company":company})); + print('File send ${file.lengthSync()/1024} KB'); + final Map data = JsonDecoder().convert(_reponse.body); +// print(_reponse.body); +// if(data['STATUS']==1){ +// return {"STATUS":1,"DATA":'File send ${file.lengthSync()/1024} KB'}; +// } +// else { + return data; +// } + } + catch(e){ + print(e); + return {"STATUS":0,"DATA":'Request timeout. Make sure server is up and running'}; + } + } + else{ + return {"STATUS":0,"DATA":'No such file'}; + } + } + + unPackDb(String link,String company,String cabang_id,String dbPath) async{ + try{ + var _reponse = await client.post( + '$link', headers: {'Content-type': 'application/json'}, + body: json.encode({"cabangId":cabang_id,"company":company,"dbPath":dbPath})); + final Map data = JsonDecoder().convert(_reponse.body); + return data; + } + catch(e){ + print(e); + return {"STATUS":0,"DATA":'Upload timeout. Make sure server is up and running'}; + } + } + + submitDb(String link,String company,String stock_id) async{ + try{ + var _reponse = await client.post( + '$link', headers: {'Content-type': 'application/json'}, + body: json.encode({"stockTakingId":stock_id,"company":company})); + final Map data = JsonDecoder().convert(_reponse.body); + return data; + } + catch(e){ + print(e); + return {"STATUS":0,"DATA":'Request timeout. Make sure server is up and running'}; + } + } + + uploadMultipart(String fileName,String link)async{ + StreamedResponse _response; + List _bytes = []; + int _total = 0; + var request = MultipartRequest('POST', Uri.parse(link)); + request.files.add( + await MultipartFile.fromPath( + 'picture', + "${(await getApplicationDocumentsDirectory()).path}/$fileName" + ) + ); + _response = await client.send(request); + _total = File("${(await getApplicationDocumentsDirectory()).path}/$fileName").lengthSync(); + dlulStream = _response.stream.listen((value) { + _bytes.addAll(value); + print('upload ${_bytes.length/_total}'); + _progress.add(((_bytes.length / _total))); + }) + ..onDone(() async { + _progress.add(0.0); + print('Finish Download'); + final file = File( + "${(await getApplicationDocumentsDirectory()).path}/$fileName"); + await file.writeAsBytes(_bytes); + _path = file.path; + }) + ..onError((e) async { + print('Error Download, $e'); + _progress.add(-1.0); + _error = e.toString(); + }); + } + + cancel()async{ + client?.close(); + await dlulStream?.cancel(); + _progress?.close(); + } +} \ No newline at end of file diff --git a/lib/Util/photo_viewer.dart b/lib/Util/photo_viewer.dart new file mode 100644 index 0000000..bc316ee --- /dev/null +++ b/lib/Util/photo_viewer.dart @@ -0,0 +1,85 @@ +import 'dart:io'; +import 'dart:typed_data'; +import 'package:image_picker/image_picker.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:photo_view/photo_view.dart'; +import 'UnitModel.dart'; + +import 'Util.dart'; + +class PhotoViewer extends StatefulWidget { + Uint8List byte; + String id; + List dropMenu; + bool edit; + String jenis; + PhotoViewer(this.byte,{this.id,this.edit= true,this.dropMenu,this.jenis}); +// PhotoViewer({Key key}) : super(key: key); + @override + _PhotoViewerState createState() => _PhotoViewerState(); +} + +class _PhotoViewerState extends State { + Util util = new Util(); + String jenisImages; + @override + Widget build(BuildContext context) { + return Column( + children: [ + Flexible( + flex: 8, + child: Container( + child: Hero( + tag: widget.id, + child: PhotoView( + imageProvider: MemoryImage(widget.byte), + ), + ), + ), + ), + Expanded( + flex: 1, + child: Material( + color: Colors.transparent, + child: Container( + child: Text(widget.jenis,style: TextStyle(color: Colors.white,fontSize: 18),), + ), + ), + ), + (widget.edit)?Flexible( + flex: 1, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + FlatButton( + child: Text('Cancel'), + color: Colors.red, + onPressed: (){Navigator.pop(context);}, + ), + FlatButton( + child: Text('Change'), + color: Colors.green, + onPressed: ()async{ + File temp = await ImagePicker.pickImage(source: ImageSource.camera,maxWidth: 800); + if(temp!=null){ + util.showLoading(context); + widget.byte = temp.readAsBytesSync(); + temp.deleteSync(); + setState(() { + + }); + await Future.delayed(Duration(seconds: 1)); + } + Navigator.pop(context); + if(temp!= null)Navigator.pop(context,{'byte':widget.byte}); + }, + ), + ], + ), + ):Container() + ], + ); + } +} \ No newline at end of file diff --git a/lib/home_page.dart b/lib/home_page.dart new file mode 100644 index 0000000..bbf13a2 --- /dev/null +++ b/lib/home_page.dart @@ -0,0 +1,1065 @@ +import 'dart:async'; +import 'dart:io'; +import 'package:flutter/rendering.dart'; +import 'package:flutter/widgets.dart'; +import 'package:path/path.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:path_provider/path_provider.dart'; +import 'Util/DBHelper.dart'; +import 'Util/Util.dart'; +import 'Util/download_Upload_Handler.dart'; +import 'package:intl/intl.dart'; +import 'main.dart'; +import 'Util/Prefs.dart'; +import 'Util/UnitModel.dart'; + +class HomePage extends StatefulWidget { +// HomePage({Key key}) : super(key: key); + final String title; + HomePage({this.title}); + @override + _HomePageState createState() => _HomePageState(); +} + +class _HomePageState extends State { + Util util = new Util(); + StreamSubscription progressDLStream,progressULStream; + String lastDownload = ''; + String lastUpload = ''; + double progressDL,progressUL; + String timeString = ''; + bool isLoading = false; + String state = ''; + final hostAddress = new TextEditingController(); + + clearData(context)async{ + setState(() { + progressDL = null; + isLoading = false; + }); + String errMsg; + bool result = await showDialog(context: context,builder: (context)=>WillPopScope( + onWillPop: ()async{ + Navigator.pop(context,false); + return false; + }, + child: AlertDialog( + title: Text('Clear Data ?'), + content: Text('Proceed to clear any remaining units data on this device?'), + actions: [ + FlatButton( + child: Text('Proceed'), + onPressed: ()async{ + util.showLoading(context); + await Future.sync(()async{ + await prefs.remove(keyClass.lastDownload); + await prefs.remove(keyClass.lastUpload); + await prefs.remove(keyClass.targetProccess); + await prefs.remove(keyClass.submitProccess); + await prefs.remove(keyClass.stock_id); + setState(() { + lastUpload = ''; + lastDownload = ''; + timeString = ''; + }); +// var result = await DBHelper.database.deleteAll(); +// if(result!=null) { +// await DBHelper.database.closeDb(); +// if(result!=null){ + try{ + Directory documentsDirectory = await getApplicationDocumentsDirectory(); + String path = join(documentsDirectory.path, "UnitStocking.db"); + File db = File(path); + if(db.existsSync()){ + db.deleteSync(); + } + } + catch(e){ + print(e); + util.showFlushbar(context, 'Failed to delete database file',color: Colors.red); + } +// } +// else{ +// errMsg = 'Failed to clear unit data'; +// } +// } +// else{ +// errMsg = 'Failed to clear unit data'; +// } + }); + Navigator.pop(context); + Navigator.pop(context,true); + util.showFlushbar(context,errMsg??'Data Cleared'); + }, + ), + FlatButton( + child: Text('Cancel'), + onPressed: (){Navigator.pop(context,false);}, + ) + ], + ), + )); + return result; + } + + loadState()async{ + String company = prefs.getString(keyClass.company); + String stock_taking_id = prefs.getString(keyClass.stock_id); + + if(company!=null&&stock_taking_id!=null){ + var result = await util.JsonDataPostRaw({"company":company,"stockTakingId":stock_taking_id}, '${prefs.getString(keyClass.hostAddress)??'https://unitstocksbackend.thamringroup.web.id'}/getStateStockUnit'); + print(result); + if(result['STATUS']==1){ + setState(() { + state = result['DATA']['STATE']; + }); + } + } + } + + @override + void initState() { + // TODO: implement initState + super.initState(); + loadState(); + lastDownload = prefs.getString(keyClass.lastDownload)??''; + lastUpload = prefs.getString(keyClass.lastUpload)??''; + } + + changeCabang(context)async{ + util.showLoading(context); + var result = await util.JsonDataPostRaw({"company":prefs.getString(keyClass.company),"User":prefs.getString(keyClass.user_id)}, '${prefs.getString(keyClass.hostAddress)??'https://unitstocksbackend.thamringroup.web.id'}/getCabangByUser'); + Navigator.pop(context); + if(result['STATUS']==1){ + var selected = prefs.getString(keyClass.cabang_id)??result['DATA'][0]["RETURN_VALUE"]; + return await showDialog(context: context,builder: (context)=>StatefulBuilder( + builder:(context,setState)=> + Material( + color: Colors.white.withOpacity(0.9), + child: Center( + child: Container( + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 2, + offset: Offset(0, 0), // changes position of shadow + ), + ], + borderRadius: BorderRadius.circular(5) + ), + height: MediaQuery.of(context).size.height/3.2, + width: MediaQuery.of(context).size.width*0.75, + child: Column( + children: [ + Flexible( + flex:3, + child: Container( + padding: EdgeInsets.only(top:10,left: 10,right: 10), + alignment: Alignment.center, + decoration: BoxDecoration( +// color: Colors.indigo, + borderRadius: BorderRadius.only(topLeft: Radius.circular(5),topRight: Radius.circular(5)) + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Icon(Icons.business,size: 70,color: Colors.indigo,), + SizedBox(height: 5,), + Text('Set Cabang',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16,color: Colors.indigo),) + ], + ), + ), + ), + Flexible( + flex: 1, + child: Container( + padding: EdgeInsets.only(left: 20,right: 20), + alignment: Alignment.centerLeft, + child: Theme( + data: ThemeData( + canvasColor: Colors.white, + primaryColor: Colors.indigo, + accentColor: Colors.indigo, + hintColor: Colors.indigo + ), + child: DropdownButtonFormField( + style: TextStyle(color: Colors.black.withOpacity(0.6),fontWeight: FontWeight.w500,fontSize: 14,), + decoration: InputDecoration( + contentPadding: EdgeInsets.all(8.0), + ), + value: selected, + onChanged: (value){ + setState(() { + selected = value; + }); + }, + items: result['DATA'].map>((item){ + return DropdownMenuItem( + value: item['RETURN_VALUE'], + child: Text(item["DISPLAY_VALUE"]), + ); + }).toList(), + ), + ), + ), + ), + Flexible( + flex: 1, + child: Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + FlatButton( + child: Text('OK',style: TextStyle(color: Colors.indigo),), + onPressed: ()async{ + if(selected!=prefs.getString(keyClass.cabang_id)){ + prefs.setString(keyClass.cabang_id,selected); + await Future.sync(()async{ + await prefs.remove(keyClass.lastDownload); + await prefs.remove(keyClass.lastUpload); + await prefs.remove(keyClass.targetProccess); + await prefs.remove(keyClass.submitProccess); + lastUpload = ''; + lastDownload = ''; + timeString = ''; + try{ + Directory documentsDirectory = await getApplicationDocumentsDirectory(); + String path = join(documentsDirectory.path, "UnitStocking.db"); + File db = File(path); + if(db.existsSync()){ + db.deleteSync(); + } + } + catch(e){ + print(e); + util.showFlushbar(context, 'Failed to delete database file',color: Colors.red); + } + }); + Navigator.pop(context,true); + } + else{ + Navigator.pop(context,false); + } + }, + ), + ], + ), + ), + ) + ], + ), + ), + ), + ), +// AlertDialog( +// title: Text('Set Cabang'), +// content: DropdownButtonFormField( +// value: selected, +// onChanged: (value){ +// setState(() { +// selected = value; +// }); +// }, +// items: result['DATA'].map>((item){ +// return DropdownMenuItem( +// value: item['RETURN_VALUE'], +// child: Text(item["DISPLAY_VALUE"]), +// ); +// }).toList(), +// ), +// actions: [ +// FlatButton( +// child: Text('OK'), +// onPressed: ()async{ +// if(selected!=prefs.getString(keyClass.cabang_id)){ +// prefs.setString(keyClass.cabang_id,selected); +// await Future.sync(()async{ +// await prefs.remove(keyClass.lastDownload); +// await prefs.remove(keyClass.lastUpload); +// await prefs.remove(keyClass.targetProccess); +// await prefs.remove(keyClass.submitProccess); +// lastUpload = ''; +// lastDownload = ''; +// timeString = ''; +//// var result = await DBHelper.database.deleteAll(); +//// if(result!=null) { +//// await DBHelper.database.closeDb(); +//// if(result!=null){ +// try{ +// Directory documentsDirectory = await getApplicationDocumentsDirectory(); +// String path = join(documentsDirectory.path, "UnitStocking.db"); +// File db = File(path); +// if(db.existsSync()){ +// db.deleteSync(); +// } +// } +// catch(e){ +// print(e); +// util.showFlushbar(context, 'Failed to delete database file',color: Colors.red); +// } +//// } +//// else{ +//// errMsg = 'Failed to clear unit data'; +//// } +//// } +//// else{ +//// errMsg = 'Failed to clear unit data'; +//// } +// }); +// Navigator.pop(context,true); +// } +// else{ +// Navigator.pop(context,false); +// } +//// util.showLoading(context); +// +//// Navigator.pop(context); +// }, +// ) +// ], +// ), + )); + } + else{ + util.showFlushbar(context, result['DATA'],color: Colors.red); + return false; + } + } + + @override + Widget build(BuildContext context) { + return WillPopScope( + onWillPop: ()async{ + await showDialog(context: context,builder: (context)=> + Material( + color: Colors.white.withOpacity(0.9), + child: Center( + child: Container( + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 2, + offset: Offset(0, 0), // changes position of shadow + ), + ], + borderRadius: BorderRadius.circular(5) + ), + height: MediaQuery.of(context).size.height/4.8, + width: MediaQuery.of(context).size.width*0.75, + child: Column( + children: [ + Flexible( + flex:3, + child: Container( + padding: EdgeInsets.only(top:10,left: 10,right: 10), + alignment: Alignment.center, + decoration: BoxDecoration( +// color: Colors.indigo, + borderRadius: BorderRadius.only(topLeft: Radius.circular(5),topRight: Radius.circular(5)) + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Icon(Icons.exit_to_app,size: 70,color: Colors.indigo,), + ], + ), + ), + ), + Flexible( + flex: 1, + child: Container( + padding: EdgeInsets.only(left: 20,right: 20), + alignment: Alignment.centerLeft, + child: Text('Keluar dari aplikasi?',style: TextStyle(fontWeight: FontWeight.w500,fontSize: 14,color: Colors.black.withOpacity(0.6)),) + ), + ), + Flexible( + flex: 1, + child: Container( + padding: EdgeInsets.only(bottom:10), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + FlatButton( + child: Text('Exit',style: TextStyle(color: Colors.indigo),), + onPressed: ()async{ + Navigator.pop(context); + await locationStream?.cancel(); + exit(0); + }, + ), + FlatButton( + child: Text('Cancel',style: TextStyle(color: Colors.indigo),), + onPressed: (){ + Navigator.pop(context); + }, + ) + ], + ), + ), + ) + ], + ), + ), + ), + ), + ); + return false; + }, + child: Scaffold( + body: Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Container( + padding: EdgeInsets.only(bottom: 0,left: 15,right: 10,top: 10), + height: MediaQuery.of(context).size.height/13, + width: MediaQuery.of(context).size.width, + alignment: Alignment.bottomLeft, + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('Home',style: TextStyle(color: Colors.indigo.withOpacity(0.8),fontSize: 18,fontWeight: FontWeight.bold),), + PopupMenuButton( + child: Padding( + padding: const EdgeInsets.only(right:2.0), + child: Icon(Icons.menu,color: Colors.indigo.withOpacity(0.8),), + ), + itemBuilder: (context){ + return [ + PopupMenuItem( + value:'hostChange', + child: Row( + children: [ + Icon(Icons.network_wifi,color: Colors.black,), + SizedBox(width: 10,), + Text('Change Ip Address') + ], + ), + ), + PopupMenuItem( + value:'cabangChange', + child: Row( + children: [ + Icon(Icons.business,color: Colors.black,), + SizedBox(width: 10,), + Text('Change Cabang') + ], + ), + ), + PopupMenuItem( + value:'logout', + child: Row( + children: [ + Icon(Icons.exit_to_app,color: Colors.black,), + SizedBox(width: 10,), + Text('Logout') + ], + ), + ), + ]; + }, + onSelected: (value)async{ + if(value == 'hostChange'){ + hostAddress.text = prefs.getString(keyClass.hostAddress)??'https://unitstocksbackend.thamringroup.web.id'; + await showDialog(context: context,builder: (context)=> + Material( + color: Colors.white.withOpacity(0.9), + child: Center( + child: Container( + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 2, + offset: Offset(0, 0), // changes position of shadow + ), + ], + borderRadius: BorderRadius.circular(5) + ), + height: MediaQuery.of(context).size.height/3.2, + width: MediaQuery.of(context).size.width*0.75, + child: Column( + children: [ + Flexible( + flex:3, + child: Container( + padding: EdgeInsets.only(top:10,left: 10,right: 10), + alignment: Alignment.center, + decoration: BoxDecoration( +// color: Colors.indigo, + borderRadius: BorderRadius.only(topLeft: Radius.circular(5),topRight: Radius.circular(5)) + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Icon(Icons.network_wifi,size: 70,color: Colors.indigo,), + SizedBox(height: 5,), + Text('Set Ip Address',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16,color: Colors.indigo),) + ], + ), + ), + ), + Flexible( + flex: 1, + child: Container( + padding: EdgeInsets.only(left: 20,right: 20), + alignment: Alignment.centerLeft, + child: Theme( + data: ThemeData( + canvasColor: Colors.white, + primaryColor: Colors.indigo, + accentColor: Colors.indigo, + hintColor: Colors.indigo + ), + child: TextField( + controller: hostAddress, + decoration: InputDecoration( + contentPadding: EdgeInsets.all(8), + ), + onSubmitted: (value){ + prefs.setString(keyClass.hostAddress,(value=='')?'https://unitstocksbackend.thamringroup.web.id':value); + Navigator.pop(context); + }, + ), + ), + ), + ), + Flexible( + flex: 1, + child: Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + FlatButton( + child: Text('OK',style: TextStyle(color: Colors.indigo),), + onPressed: (){ + prefs.setString(keyClass.hostAddress,(hostAddress.text=='')?'https://unitstocksbackend.thamringroup.web.id':hostAddress.text); + Navigator.pop(context); + }, + ) + ], + ), + ), + ) + ], + ), + ), + ), + ) +// AlertDialog( +// title: Text('Set IP Address'), +// content: TextField( +// controller: hostAddress, +// onSubmitted: (value){ +// prefs.setString(keyClass.hostAddress,(value=='')?'https://unitstocksbackend.thamringroup.web.id':value); +// Navigator.pop(context); +// }, +// ), +// actions: [ +// FlatButton( +// child: Text('OK'), +// onPressed: (){ +// prefs.setString(keyClass.hostAddress,(hostAddress.text=='')?'https://unitstocksbackend.thamringroup.web.id':hostAddress.text); +// Navigator.pop(context); +// }, +// ) +// ], +// ) + ); + } + if(value=="cabangChange") { + var res = await changeCabang(context); + if(res??false){ + setState(() { + }); + } + } + if(value == 'logout'){ + prefs.remove(keyClass.cabang_id); + prefs.remove(keyClass.company); + prefs.remove(keyClass.user_id); + prefs.setBool(keyClass.logged_in, false); + Navigator.pushNamed(context, '/login'); + } + }, + ), + ], + ), + ), + (prefs.getString(keyClass.stock_id)==null)?Container():Padding( + padding: const EdgeInsets.only(top: 8,right: 8), + child: Container( + decoration: BoxDecoration( + color: Colors.indigo.withOpacity(0.9), + borderRadius: BorderRadius.circular(8) +// border: Border.all(), + ), + padding: EdgeInsets.all(8), + child: Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text('Status : ',style: TextStyle(color: Colors.white),), + Text(state??'-',style: TextStyle(fontWeight: FontWeight.bold,color: Colors.white),), + ], + ), + ), + ), + Expanded( + child: Container( + child: + GridView.count( + padding: EdgeInsets.all(10), + crossAxisSpacing: 10, + mainAxisSpacing: 10, + crossAxisCount: 2, + children: [ + AbsorbPointer( + absorbing: isLoading, + child: InkWell( + splashColor: Colors.black, + onTap: ()async{ + bool getData = await showDialog( + context: context, + builder: (context)=>AlertDialog( + title: Text("Get Data Units?"), + content: Text('Fetch data unit for stocking'), + actions: [ + FlatButton( + child: Text('Proceed'), + onPressed: (){ + Navigator.pop(context,true); + }, + ), + FlatButton( + child: Text('Cancel'), + onPressed: (){ + Navigator.pop(context,false); + }, + ) + ], + ) + ); + if(getData??false){ + setState(() { + isLoading = true; + }); + var a = Stopwatch(); + a.start(); + await Future.delayed(Duration(milliseconds: 200)); + bool isclear; + Directory documentsDirectory = await getApplicationDocumentsDirectory(); + String path = join(documentsDirectory.path, "UnitStocking.db"); + File db = File(path); + if(db.existsSync()){ + isclear = await clearData(context); + } + else{ + isclear = true; + } + if(isclear??false){ + print('fetching'); + util.showLoading(context); + file_Trans_Handler trans = new file_Trans_Handler(); + trans.downloadFile('UnitStocking.db',"${prefs.getString(keyClass.hostAddress)??'https://unitstocksbackend.thamringroup.web.id'}/getSqliteDb/${prefs.getString(keyClass.company)}/${prefs.getString(keyClass.cabang_id)}"); + progressDLStream = trans.progress.listen((value)async { + if(progressDL==null) { +// print(['test',value]); + if(value!=null) Navigator.pop(context); + } + setState(() { + progressDL = (value!=-1.0)?value:null; + }); + if(value!=null&&value >= 1.0) { + progressDLStream.cancel(); + progressDL = null; + setState(() { + lastDownload = DateTime.now().toIso8601String(); + }); + await prefs.setString(keyClass.lastDownload, lastDownload); + await DBHelper.database.insertUpdateValue(new valueTab(name: 'TGL_START',value: DateFormat('dd-MM-yyyy HH:mm:ss').format(DateTime.parse(lastDownload)))); + await DBHelper.database.insertUpdateValue(new valueTab(name: 'TGL_STOCK_TAKING',value: DateFormat('dd-MM-yyyy').format(DateTime.parse(lastDownload)))); + await DBHelper.database.closeDb(); + util.showFlushbar(context,'Data downloaded'); + loadState(); + a.stop(); + if(a.elapsed.inSeconds<3){ + await Future.delayed(Duration(seconds: 3-a.elapsed.inSeconds)); + } + setState(() { + isLoading = false; + }); + } + if(value==-1.0){ + setState(() { + isLoading = false; + }); + util.showFlushbar(context,'Data download error',color: Colors.red); + } + }); +// Navigator.popUntil(context, ModalRoute.withName('/home')); + } + } + }, + child: Container( + padding: EdgeInsets.all(5), + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 2, + offset: Offset(0, 0), // changes position of shadow + ), + ], + borderRadius: BorderRadius.all(Radius.circular(5.0)), + color: Colors.green.withAlpha(220).withOpacity(0.7), + ), + child: Stack( + children: [ + Container( + alignment: (progressDL!=null)?Alignment.bottomCenter:Alignment.bottomLeft, + padding: EdgeInsets.only(left: 10,right: 10,top: 10,bottom: 15), + child: (progressDL!=null)?Column( + mainAxisSize: MainAxisSize.min, + children: [ + LinearProgressIndicator( + value: progressDL, + ), + Text('${(progressDL*100).floor()}%',style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold),) + ], + ):(lastDownload=='')?null:Text('Last download : ${DateFormat('dd MMM yyyy HH:mm').format(DateTime.parse(lastDownload))}',style: TextStyle(color: Colors.white,fontSize: 11,fontWeight: FontWeight.bold)), + ), + Positioned.fill( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.file_upload,size: MediaQuery.of(context).size.width/6,color: Colors.white,), + SizedBox(height: 5,), + Text('Get Data Master',style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold,fontSize: 16),), + ], + ), + ), + ], + ), + ), + ), + ), + InkWell( + splashColor: Colors.black, + onTap: ()async{ + await Future.delayed(Duration(milliseconds: 200)); + if(lastDownload!=''){ + Navigator.pushNamed(context, '/stocking'); + } + else{ + util.showFlushbar(context, 'Data Master tidak ditemukan. Get data master dulu.'); + } + }, + child: Container( + padding: EdgeInsets.all(5), + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 2, + offset: Offset(0, 0), // changes position of shadow + ), + ], + borderRadius: BorderRadius.all(Radius.circular(5.0)), + color: Colors.blueGrey.withAlpha(230).withOpacity(0.8), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.receipt,size: MediaQuery.of(context).size.width/6,color: Colors.white,), + SizedBox(height: 5,), + Text('Stocking',style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold,fontSize: 16),) + ], + ), + ), + ), + InkWell( + splashColor: Colors.black, + onTap: ()async{ + if(lastDownload!=''){ + await DBHelper.database.insertUpdateValue(new valueTab(name: 'TGL_SELESAI',value: DateFormat('dd-MM-yyyy HH:mm:ss').format(new DateTime.now()))); + await DBHelper.database.closeDb(); + file_Trans_Handler trans = new file_Trans_Handler(); + bool popped = false; + util.showLoading(context,onwillpop:()async{ + await trans.cancel(); + popped = true; + return true; + }); + var upload = await trans.uploadFile('UnitStocking.db',"${prefs.getString(keyClass.hostAddress)??'https://unitstocksbackend.thamringroup.web.id'}/uploadSqlitedb",prefs.getString(keyClass.company),prefs.getString(keyClass.cabang_id)); + if(!popped){ + Navigator.pop(context); + util.showFlushbar(context, upload['DATA'],color:(upload['STATUS']!=1)?Colors.red:Colors.grey); + if(upload['STATUS']==1){ + setState(() { + lastUpload = new DateTime.now().toIso8601String(); + }); + prefs.setString(keyClass.lastUpload, lastUpload); + prefs.setString(keyClass.targetProccess, upload[keyClass.targetProccess]); + } + } + } + else{ + util.showFlushbar(context, "Belum ada data yang disimpan.",color: Colors.red); + } + }, + child: Container( + padding: EdgeInsets.all(5), + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 2, + offset: Offset(0, 0), // changes position of shadow + ), + ], + borderRadius: BorderRadius.all(Radius.circular(5.0)), + color: Colors.indigo.withAlpha(220).withOpacity(0.7), + ), + child: Stack( + children: [ + Container( + alignment: (progressUL!=null)?Alignment.bottomCenter:Alignment.bottomLeft, + padding: EdgeInsets.only(left: 10,right: 10,top: 10,bottom: 15), + child: (progressUL!=null)?Column( + mainAxisSize: MainAxisSize.min, + children: [ + LinearProgressIndicator( + value: progressUL, + ), + Text('${(progressUL*100).floor()}%',style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold),) + ], + ):(lastUpload=='')?null:Text('Last upload : ${DateFormat('dd MMM yyyy HH:mm').format(DateTime.parse(lastUpload))}\n${(timeString!='')?'Duration: $timeString':''}',style: TextStyle(color: Colors.white,fontSize: 11,fontWeight: FontWeight.bold)), + ), + Positioned.fill( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.file_upload,size: MediaQuery.of(context).size.width/6,color: Colors.white,), + SizedBox(height: 5,), + Text('Send Data Stokan',style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold,fontSize: 16),), + ], + ), + ), + ], + ), + ), + ), + (prefs.getString(keyClass.targetProccess)==null&&prefs.getBool(keyClass.submitProccess)==null)?InkWell( + splashColor: Colors.black, + onTap: ()async{ + await Future.delayed(Duration(milliseconds: 200)); + await clearData(context); + }, + child: Container( + padding: EdgeInsets.all(5), + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 2, + offset: Offset(0, 0), // changes position of shadow + ), + ], + borderRadius: BorderRadius.all(Radius.circular(5.0)), + color: Colors.red.withAlpha(200).withOpacity(0.7), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.restore_from_trash,size: MediaQuery.of(context).size.width/6,color: Colors.white,), + SizedBox(height: 5,), + Text('Clear Data',style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold,fontSize: 16),) + ], + ), + ), + ): + (prefs.getString(keyClass.targetProccess)!=null)?InkWell( + onTap: ()async{ + bool result = await showDialog(context: context,builder: (context)=>WillPopScope( + onWillPop: ()async{ + Navigator.pop(context,false); + return false; + }, + child: AlertDialog( + title: Text('Process Data ?'), + content: Text('Proceed to unpack the uploaded data.'), + actions: [ + FlatButton( + child: Text('Proceed'), + onPressed: ()async{ + Navigator.pop(context,true); + }, + ), + FlatButton( + child: Text('Cancel'), + onPressed: (){Navigator.pop(context,false);}, + ) + ], + ), + )); + if(result){ + util.showLoading(context); + file_Trans_Handler trans = new file_Trans_Handler(); + var upload = await trans.unPackDb("${prefs.getString(keyClass.hostAddress)??'https://unitstocksbackend.thamringroup.web.id'}/unpackDb",prefs.getString(keyClass.company),prefs.getString(keyClass.cabang_id),prefs.getString(keyClass.targetProccess)); + Navigator.pop(context); + util.showFlushbar(context, upload['DATA'],color:(upload['STATUS']!=1)?Colors.red:Colors.grey); + if(upload['STATUS']==1){ + prefs.remove(keyClass.targetProccess); + prefs.setBool(keyClass.submitProccess,true); + } + setState(() { + + }); + } + }, + child: Container( + padding: EdgeInsets.all(5), + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 2, + offset: Offset(0, 0), // changes position of shadow + ), + ], + borderRadius: BorderRadius.all(Radius.circular(5.0)), + color: Colors.orangeAccent.withAlpha(230).withOpacity(0.7), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.arrow_forward,size: MediaQuery.of(context).size.width/6,color: Colors.white,), + SizedBox(height: 5,), + Text('Process Units',style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold,fontSize: 16),) + ], + ), + ), + ): + InkWell( + onTap: ()async{ + bool result = await showDialog(context: context,builder: (context)=>WillPopScope( + onWillPop: ()async{ + Navigator.pop(context,false); + return false; + }, + child: AlertDialog( + title: Text('Submit Data ?'), + content: Text('Submit the uploaded data.'), + actions: [ + FlatButton( + child: Text('Submit'), + onPressed: ()async{ + Navigator.pop(context,true); + }, + ), + FlatButton( + child: Text('Cancel'), + onPressed: (){Navigator.pop(context,false);}, + ) + ], + ), + )); + if(result){ + util.showLoading(context); + file_Trans_Handler trans = new file_Trans_Handler(); + var upload = await trans.submitDb("${prefs.getString(keyClass.hostAddress)??'https://unitstocksbackend.thamringroup.web.id'}/submitStock",prefs.getString(keyClass.company),prefs.getString(keyClass.stock_id)); + Navigator.pop(context); + util.showFlushbar(context, upload['DATA'],color:(upload['STATUS']!=1)?Colors.red:Colors.grey); + if(upload['STATUS']==1){ + loadState(); + prefs.remove(keyClass.submitProccess); + } + setState(() { + }); + } + }, + child: Container( + padding: EdgeInsets.all(5), + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 2, + offset: Offset(0, 0), // changes position of shadow + ), + ], + borderRadius: BorderRadius.all(Radius.circular(5.0)), + color: Colors.lightGreen.withAlpha(230), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.arrow_forward,size: MediaQuery.of(context).size.width/6,color: Colors.white,), + SizedBox(height: 5,), + Text('Submit Process',style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold,fontSize: 16),) + ], + ), + ), + ), + (prefs.getString(keyClass.targetProccess)!=null||(prefs.getBool(keyClass.submitProccess)!=null&&prefs.getBool(keyClass.submitProccess)))?InkWell( + splashColor: Colors.black, + onTap: ()async{ + await Future.delayed(Duration(milliseconds: 200)); + await clearData(context); + }, + child: Container( + padding: EdgeInsets.all(5), + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 2, + offset: Offset(0, 0), // changes position of shadow + ), + ], + borderRadius: BorderRadius.all(Radius.circular(5.0)), + color: Colors.red.withAlpha(200), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.restore_from_trash,size: MediaQuery.of(context).size.width/6,color: Colors.white,), + SizedBox(height: 5,), + Text('Clear Data',style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold,fontSize: 16),) + ], + ), + ), + ):Container(), + ], + )), + ), + ], + ), + bottomSheet: Container(height: 22,alignment: Alignment.bottomRight,child: Opacity(opacity: 0.5,child: Padding(padding: EdgeInsets.all(5),child: Text((lastDownload!='')?'Master Data Downloaded':'No Master Data Found',style: TextStyle(fontSize: 12),)))), + ), + ); + + } +} \ No newline at end of file diff --git a/lib/login_page.dart b/lib/login_page.dart new file mode 100644 index 0000000..6481dc7 --- /dev/null +++ b/lib/login_page.dart @@ -0,0 +1,442 @@ +import 'dart:io'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'main.dart'; +import 'Util/Prefs.dart'; + + +class LoginPage extends StatefulWidget { + LoginPage({Key key}) : super(key: key); + @override + _LoginPageState createState() => _LoginPageState(); +} + +class _LoginPageState extends State { + final userCon = new TextEditingController(); + final passCon = new TextEditingController(); + final hostAddress = new TextEditingController(); + List cabangDrop = []; + String selected; + + + + Login()async{ + util.showLoading(context); + var result = await util.JsonDataPostRaw({"User":userCon.text,"Pass":passCon.text}, '${prefs.getString(keyClass.hostAddress)??'https://unitstocksbackend.thamringroup.web.id'}/login'); + if(result['STATUS']==1){ + prefs.setString(keyClass.user_id, result['DATA'][keyClass.user_id]); + prefs.setString(keyClass.company, result['DATA'][keyClass.company]); + prefs.setBool(keyClass.logged_in, true); + var cabangList = await util.JsonDataPostRaw({"company":prefs.getString(keyClass.company),"User":prefs.getString(keyClass.user_id)}, '${prefs.getString(keyClass.hostAddress)??'https://unitstocksbackend.thamringroup.web.id'}/getCabangByUser'); + Navigator.pop(context); + if(cabangList['STATUS']==1){ + cabangDrop = cabangList['DATA']; + print(cabangList); + selected = cabangDrop[0]['RETURN_VALUE']; + setState(() { + }); + FocusScope.of(context).requestFocus(new FocusNode()); + } + else{ + util.showFlushbar(context, cabangList['DATA'],color: Colors.red); + } + } + else{ + Navigator.pop(context); + util.showFlushbar(context, result['DATA'],color: Colors.red); + } + } + + @override + Widget build(BuildContext context) { +// if(prefs.getBool(keyClass.logged_in)==null||!prefs.getBool(keyClass.logged_in)){ + return Scaffold( + body: WillPopScope( + onWillPop: ()async{ + if(prefs.getBool(keyClass.logged_in)==null||!prefs.getBool(keyClass.logged_in)){ + await showDialog(context: context,builder: (context)=>AlertDialog( + content: Text('Exit the app?'), + actions: [ + FlatButton( + child: Text('Exit'), + onPressed: ()async{ + Navigator.pop(context); + await locationStream?.cancel(); + exit(0); + }, + ), + FlatButton( + child: Text('Cancel'), + onPressed: (){ + Navigator.pop(context); + }, + ) + + ], + )); + } + else{ + setState(() { + prefs.setBool(keyClass.logged_in, false); + prefs.remove(keyClass.cabang_id); + prefs.remove(keyClass.company); + prefs.remove(keyClass.user_id); + }); + } + return false; + }, + child: Container( + decoration: BoxDecoration( + color: Colors.white + ), + child: Stack( + children: [ + Positioned.fill( + child: Column( + children: [ + Expanded( + flex: 1, + child: Container(), + ), + Expanded( + flex: 3, + child: InkWell( + onLongPress: ()async{ + hostAddress.text = prefs.getString(keyClass.hostAddress)??'https://unitstocksbackend.thamringroup.web.id'; + await showDialog(context: context,builder: (context)=>AlertDialog( + title: Text('Set IP Address'), + content: TextField( + controller: hostAddress, + onSubmitted: (value){ + prefs.setString(keyClass.hostAddress,(value=='')?'https://unitstocksbackend.thamringroup.web.id':value); + Navigator.pop(context); + }, + ), + actions: [ + FlatButton( + child: Text('OK'), + onPressed: (){ + prefs.setString(keyClass.hostAddress,(hostAddress.text=='')?'https://unitstocksbackend.thamringroup.web.id':hostAddress.text); + Navigator.pop(context); + }, + ) + ], + )); + }, + child: Column( + children: [ + Container(child: Icon(Icons.input,size: 150,color: Colors.indigo,),), + Text('Login',style: TextStyle(fontSize: 25,color: Colors.indigo,fontWeight: FontWeight.bold),), + ], + ), + ), + ), + Expanded( + flex: 3, + child: Column( + children: [ + Container( + width: MediaQuery.of(context).size.width*0.8, + child: TextFormField( + controller: userCon, + style: TextStyle(color: Colors.indigo,fontSize: 16), + decoration: InputDecoration( + hintText: 'User ID', + contentPadding:EdgeInsets.only(left: 30,right: 30,top: 20,bottom: 20), + hintStyle: TextStyle(fontSize: 16,color: Colors.indigo.withOpacity(0.7)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Colors.indigo, + width: 2), + borderRadius: BorderRadius.circular(100) + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Colors.indigo.withOpacity(0.5), + width: 0.5), + borderRadius: BorderRadius.circular(100) + ) + ), + ), + ), + SizedBox(height: 15,), + Container( + width: MediaQuery.of(context).size.width*0.8, + child: TextFormField( + obscureText: true, + controller: passCon, + style: TextStyle(color: Colors.indigo,fontSize: 16), + decoration: InputDecoration( + contentPadding:EdgeInsets.only(left: 30,right: 30,top: 20,bottom: 20), + hintText: 'Password', + hintStyle: TextStyle(fontSize: 16,color: Colors.indigo.withOpacity(0.7)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Colors.indigo, + width: 2), + borderRadius: BorderRadius.circular(100) + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Colors.indigo.withOpacity(0.5), + width: 0.5), + borderRadius: BorderRadius.circular(100) + ) + ), + ), + ), + SizedBox(height: 30,), + FlatButton( + onPressed: Login, + padding: EdgeInsets.all(15), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(100.0), + side: BorderSide(color: Colors.indigo) + ), + color: Colors.indigo, + child: Container(width: MediaQuery.of(context).size.width*0.7,child: Text('Login',textAlign: TextAlign.center,style: TextStyle(color: Colors.white,fontSize: 21),)), + ) + ], + ), + ), +// Expanded( +// flex: 3, +// child: Container(color: Colors.yellow,), +// ), + ], + ), + ), + (prefs.getBool(keyClass.logged_in)==null||!prefs.getBool(keyClass.logged_in)) + ?Container() + :Positioned.fill( + child: Container( + color: Colors.white.withOpacity(0.9), + child: Center( + child: Container( + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 5, + blurRadius: 7, + offset: Offset(0, 3), // changes position of shadow + ), + ], + borderRadius: BorderRadius.circular(5) + ), + height: MediaQuery.of(context).size.height/3.2, + width: MediaQuery.of(context).size.width*0.75, + child: Column( + children: [ + Flexible( + flex:3, + child: Container( + padding: EdgeInsets.only(top:10,left: 10,right: 10), + alignment: Alignment.center, + decoration: BoxDecoration( +// color: Colors.indigo, + borderRadius: BorderRadius.only(topLeft: Radius.circular(5),topRight: Radius.circular(5)) + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Icon(Icons.business,size: 70,color: Colors.indigo,), + SizedBox(height: 5,), + Text('Pilih Cabang',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16,color: Colors.indigo),) + ], + ), + ), + ), + Flexible( + flex: 1, + child: Container( + padding: EdgeInsets.only(left: 20,right: 20), + alignment: Alignment.centerLeft, + child: Theme( + data: ThemeData( + canvasColor: Colors.white, + primaryColor: Colors.indigo, + accentColor: Colors.indigo, + hintColor: Colors.indigo + ), + child: DropdownButtonFormField( + style: TextStyle(color: Colors.black.withOpacity(0.6),fontWeight: FontWeight.w500,fontSize: 14,), + decoration: InputDecoration( + contentPadding: EdgeInsets.all(8.0), + ), + value: selected, + onChanged: (value){ + setState(() { + selected = value; + }); + }, + items: cabangDrop.map>((item)=>DropdownMenuItem( + value: item['RETURN_VALUE'], + child: Text(item["DISPLAY_VALUE"]), + )).toList(), + ), + ), + ), + ), + Flexible( + flex: 1, + child: Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + ButtonTheme( + minWidth: 10, + child: FlatButton( + onPressed: (){ + prefs.setString(keyClass.cabang_id, selected); + Navigator.pushNamed(context, '/home'); + }, + child: Text('Set',style: TextStyle(color: Colors.indigo),), + ), + ), + FlatButton( + onPressed: (){ + setState(() { + prefs.setBool(keyClass.logged_in, false); + prefs.remove(keyClass.cabang_id); + prefs.remove(keyClass.company); + prefs.remove(keyClass.user_id); + }); + }, + child: Text('Cancel',style: TextStyle(color: Colors.indigo)), + ) + ], + ), + ), + ) + ], + ), + ), + ), + ) + ), + ], + ), + ), + ), + ); +// } +// else{ +// return WillPopScope( +// onWillPop: ()async{ +// setState(() { +// prefs.setBool(keyClass.logged_in, false); +// prefs.remove(keyClass.cabang_id); +// prefs.remove(keyClass.company); +// prefs.remove(keyClass.user_id); +// }); +// return false; +// }, +// child: Material( +// child: Container( +// color: Colors.grey.withOpacity(0.7), +// child: Center( +// child: Container( +// decoration: BoxDecoration( +// color: Colors.white, +// borderRadius: BorderRadius.circular(5) +// ), +// height: MediaQuery.of(context).size.height/3.2, +// width: MediaQuery.of(context).size.width*0.75, +// child: Column( +// children: [ +// Flexible( +// flex:3, +// child: Container( +// padding: EdgeInsets.only(top:10,left: 10,right: 10), +// alignment: Alignment.center, +// decoration: BoxDecoration( +//// color: Colors.indigo, +// borderRadius: BorderRadius.only(topLeft: Radius.circular(5),topRight: Radius.circular(5)) +// ), +// child: Column( +// mainAxisSize: MainAxisSize.min, +// crossAxisAlignment: CrossAxisAlignment.center, +// children: [ +// Icon(Icons.business,size: 70,color: Colors.indigo,), +// SizedBox(height: 5,), +// Text('Pilih Cabang',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16,color: Colors.indigo),) +// ], +// ), +// ), +// ), +// Flexible( +// flex: 1, +// child: Container( +// padding: EdgeInsets.only(left: 20,right: 20), +// alignment: Alignment.centerLeft, +// child: Theme( +// data: ThemeData( +// canvasColor: Colors.white, +// primaryColor: Colors.indigo, +// accentColor: Colors.indigo, +// hintColor: Colors.indigo +// ), +// child: DropdownButtonFormField( +// style: TextStyle(color: Colors.black.withOpacity(0.6),fontWeight: FontWeight.w500,fontSize: 14,), +// decoration: InputDecoration( +// contentPadding: EdgeInsets.all(8.0), +// ), +// value: selected, +// onChanged: (value){ +// setState(() { +// selected = value; +// }); +// }, +// items: cabangDrop.map>((item)=>DropdownMenuItem( +// value: item['RETURN_VALUE'], +// child: Text(item["DISPLAY_VALUE"]), +// )).toList(), +// ), +// ), +// ), +// ), +// Flexible( +// flex: 1, +// child: Container( +// child: Row( +// mainAxisAlignment: MainAxisAlignment.end, +// children: [ +// ButtonTheme( +// minWidth: 10, +// child: FlatButton( +// onPressed: (){ +// prefs.setString(keyClass.cabang_id, selected); +// Navigator.pushNamed(context, '/home'); +// }, +// child: Text('Set',style: TextStyle(color: Colors.indigo),), +// ), +// ), +// FlatButton( +// onPressed: (){ +// setState(() { +// prefs.setBool(keyClass.logged_in, false); +// prefs.remove(keyClass.cabang_id); +// prefs.remove(keyClass.company); +// prefs.remove(keyClass.user_id); +// }); +// }, +// child: Text('Cancel',style: TextStyle(color: Colors.indigo)), +// ) +// ], +// ), +// ), +// ) +// ], +// ), +// ), +// ), +// ), +// ), +// ); +// } + } +} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart new file mode 100644 index 0000000..d5f6bc4 --- /dev/null +++ b/lib/main.dart @@ -0,0 +1,53 @@ +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:unitstocks/Util/Prefs.dart'; +import 'package:unitstocks/login_page.dart'; +import 'home_page.dart'; +import 'stocking.dart'; +import 'unit_details.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:location/location.dart'; +import 'Util/Util.dart'; + +SharedPreferences prefs; +Location location = Location(); +StreamSubscription locationStream; +LocationData currentPosisiton; +Util util = new Util(); +void main() async{ + WidgetsFlutterBinding.ensureInitialized(); + prefs = await SharedPreferences.getInstance(); + location.changeSettings(accuracy: LocationAccuracy.high); + SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]) + .then((_) { + runApp(new MyApp()); + }); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Unit Stock', + theme: ThemeData( + pageTransitionsTheme: PageTransitionsTheme( + builders: { + TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), + } + ), + primarySwatch: Colors.indigo, + ), + debugShowCheckedModeBanner: false, + + home: (prefs.getBool(keyClass.logged_in)??false)?HomePage(title:'Home Page'):LoginPage(), + routes: { + '/home': (context) => new HomePage(title:'Home Page'), + '/stocking' : (context) => new Stocking(), + '/unitdetails' : (context) => new UnitDetails(), + '/login' :(context) => new LoginPage(), + }, + ); + } +} + diff --git a/lib/stocking.dart b/lib/stocking.dart new file mode 100644 index 0000000..56d8f91 --- /dev/null +++ b/lib/stocking.dart @@ -0,0 +1,381 @@ +import 'dart:async'; +import 'dart:typed_data'; +import 'package:flutter/services.dart'; + +import 'main.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:unitstocks/unit_details.dart'; +import 'Util/DBHelper.dart'; +import 'Util/UnitModel.dart'; +import 'Util/Util.dart'; +import 'Util/photo_viewer.dart'; +import 'package:barcode_scan/barcode_scan.dart'; + +class Stocking extends StatefulWidget { + Stocking({Key key}) : super(key: key); + + @override + _StockingState createState() => _StockingState(); +} + +class _StockingState extends State with SingleTickerProviderStateMixin { +// List Units = []; + List unitsRef = []; + List Blobs = []; + List BlobsRef = []; + bool completed = false; + Util util = new Util(); + int totalUnit = 0; + final search_controller = new TextEditingController(); +// TabController _tabBarcontroller; + bool hideAppbar = false; + String search = ''; + + loadUnit()async{ + print('loading units'); + Blobs.clear(); + BlobsRef.clear(); + await DBHelper.database.closeDb(); +// Units = (search=='')?await DBHelper.database.getAllInsertUnits():await DBHelper.database.searchAllInsertUnits(search.toUpperCase()); + unitsRef = (search=='')?await DBHelper.database.getAllUnits(inserted: completed):await DBHelper.database.searchAllUnits(search.toUpperCase(),inserted: completed); +// totalUnit = await DBHelper.database.getCount(); +// for (int i = 0;i _timeouts = {}; + void debounce(Duration timeout, Function target, [List arguments = const []]) { + if (_timeouts.containsKey(target)) { + _timeouts[target].cancel(); + } + + Timer timer = Timer(timeout, () { + Function.apply(target, arguments); + }); + + _timeouts[target] = timer; + } + + void _onChanged(String val)async { + search = search_controller.text; + await loadUnit(); + } + + Future scan() async { + try { + search = ''; + setState(() => search_controller.text = search); + ScanResult result = await BarcodeScanner.scan(); + String barcode = result.rawContent; + setState(() => this.search = barcode); + } on PlatformException catch (e) { + if (e.code == BarcodeScanner.cameraAccessDenied) { + util.showFlushbar(context, 'The user did not grant the camera permission!',color: Colors.red); + setState(() { + this.search = ''; + }); + } else { + util.showFlushbar(context, 'Unknown error: $e',color: Colors.red); + setState(() => this.search = ''); + } + } on FormatException { + setState(() => this.search = + ''); + } catch (e) { + util.showFlushbar(context, 'Unknown error: $e',color: Colors.red); + setState(() => this.search = ''); + } + setState(() => search_controller.text = search); + } + + @override + void initState() { + // TODO: implement initState + super.initState(); +// _tabBarcontroller = new TabController(length: 1, vsync:this); + WidgetsBinding.instance.addPostFrameCallback((_) async { + util.showLoading(context); + await Future.sync(()async{await loadUnit();}); + Navigator.pop(context); + if(locationStream==null)await util.streamLocation(context); + else { + if(locationStream.isPaused) locationStream.resume(); + } +// setState(() { +// unitsRef.add(new Unit(flag: 'False',tipe: "sdasdas",id: 2,mesin: "sdfasdas",kode: "dasdas",rangka: "asdasd",tahun: "2020",warna: "MERAH",state: "OnChanne;")); +// unitsRef.add(new Unit(flag: 'False',tipe: "sdasdas",id: 2,mesin: "sdfasdas",kode: "dasdas",rangka: "asdasd",tahun: "2020",warna: "MERAH",state: "OnChanne;")); +// unitsRef.add(new Unit(flag: 'False',tipe: "sdasdas",id: 2,mesin: "sdfasdas",kode: "dasdas",rangka: "asdasd",tahun: "2020",warna: "MERAH",state: "OnChanne;")); +// unitsRef.add(new Unit(flag: 'False',tipe: "sdasdas",id: 2,mesin: "sdfasdas",kode: "dasdas",rangka: "asdasd",tahun: "2020",warna: "MERAH",state: "OnChanne;")); +// unitsRef.add(new Unit(flag: 'False',tipe: "sdasdas",id: 2,mesin: "sdfasdas",kode: "dasdas",rangka: "asdasd",tahun: "2020",warna: "MERAH",state: "OnChanne;")); +// }); + }); + } + @override + void dispose() { + // TODO: implement dispose + super.dispose(); + print('LocationStream paused'); + if(!locationStream.isPaused)locationStream.pause(); + } + @override + Widget build(BuildContext context) { + return WillPopScope( + onWillPop: ()async{ + if(hideAppbar) { + setState(() { + hideAppbar=false; + search = ''; + search_controller.text = ''; + }); + await loadUnit(); + return false; + } + else { + return true; + } + }, + child: Scaffold( + appBar: (hideAppbar)? + AppBar( + backgroundColor: Colors.white, + leading: GestureDetector( + onTap:()async{ + setState(() { + hideAppbar=false; + search = ''; + search_controller.text = ''; + }); + await loadUnit(); + },child: Container(width: 20,child: Icon(Icons.arrow_back,color:Colors.grey))), + title: Container( + color: Colors.white, + child: TextFormField( + maxLines: 1, + controller: search_controller, + onChanged: (val) => debounce(const Duration(milliseconds: 300), _onChanged, [val]), +// onChanged: (value)async{ +// search = search_controller.text; +// await loadUnit(); +// }, + decoration: InputDecoration.collapsed( + hintText: 'Search..', + ), + ), + ), + actions: [ + FlatButton( + onPressed: ()async{await scan();await loadUnit();}, + child: Icon(Icons.select_all,color:Colors.grey), + ) + ], + ) + :null, +// AppBar( +// backgroundColor: Colors.indigo.withOpacity(0.8), +// title: Text('Unit Stocking'), +// actions: [ +// IconButton( +// icon: Icon(Icons.search,color:Colors.white), +// onPressed: (){ +// setState(() { +// hideAppbar = true; +// }); +// }, +// ), +// ], +// ), + body: Column( + children: [ + (hideAppbar)?Container():SizedBox(height: MediaQuery.of(context).size.height/25,), + Expanded( + child:Stack( + children: [ + Container( + child: ListView.builder( + padding: EdgeInsets.only(bottom: 10), + itemCount: unitsRef.length, + shrinkWrap: false, + itemBuilder: (context,index){ + Uint8List display; + display = unitsRef[index].flag=='FALSE'?null:(BlobsRef.length==unitsRef.length)?BlobsRef[index].blob_file:null; + return Column( + children: [ + (index==0)?Container(padding: EdgeInsets.only(top: 10,left: 10,right: 10),alignment: Alignment.centerRight, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Checkbox( + value: completed, + onChanged: (value)async{ + setState(() { + completed = value; + }); + await loadUnit(); + }, + ), + Text('Completed') + ], + ), + (completed||hideAppbar)?Container():Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text('Unit : ',style: TextStyle(color: Colors.grey,fontSize: 15),), + Text('${(unitsRef.where((element) => element.flag=='TRUE').length==unitsRef.length)?'Done':'${unitsRef.length-unitsRef.where((element) => element.flag=='TRUE').length}'}',style: TextStyle(color: (unitsRef.length==unitsRef.where((element) => element.flag=='TRUE').length)?Colors.green:Colors.black,fontWeight: FontWeight.bold,fontSize: 16),), + Text(!(unitsRef.length==unitsRef.where((element) => element.flag=='TRUE').length)?' of':'',style: TextStyle(color: Colors.grey,fontSize: 15),), + Text(!(unitsRef.length==unitsRef.where((element) => element.flag=='TRUE').length)?' ${unitsRef.length}':'',style: TextStyle(color: Colors.black,fontSize: 16,fontWeight: FontWeight.bold,),), + ], + ), + ], + ),):Container(), + Padding( + padding: const EdgeInsets.only(left:10,right: 10,top: 10), + child: Container( + padding: EdgeInsets.all(5.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.grey, + blurRadius: 5.0, // has the effect of softening the shadow + spreadRadius: 2.0, // has the effect of extending the shadow + offset: Offset( + 00.0, // horizontal, move right 10 + 2.0, // vertical, move down 10 + ), + ) + ], + border: Border.all(color: Colors.grey.withOpacity(0.5)), + ), + child:Row( + children: [ + Expanded( + flex: 3, + child: InkWell( + onTap: ()async{ +// if(display!=null)Navigator.push(context, MaterialPageRoute(builder: (context) => PhotoViewer(Blobs[index].blob_file,id: Blobs[index].blob_id.toString(),edit: false,jenis: Blobs[index].jenis,))); + if(display==null){ + var result = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => UnitDetails(unit: unitsRef[index],), + ), + ); + if(result!=null){ + util.showLoading(context); + await loadUnit(); + Navigator.pop(context); + } + } + else{ + await Navigator.push(context, MaterialPageRoute(builder: (context) => PhotoViewer(display,id: unitsRef[index].id.toString(),jenis: '',edit: false,))); + } + }, + child: Hero(tag: unitsRef[index].id,child: Padding( + padding: EdgeInsets.only(right: 10), + child: Container(width: 100,height: 100,alignment: Alignment.center,child:(display==null)?Icon(Icons.crop_original,color: Colors.white,size: 80,):null, + decoration: BoxDecoration( + color: Colors.grey.withOpacity(0.5), + image: (display!=null)?DecorationImage( + image: MemoryImage(display),fit: BoxFit.cover,):null,)), + )), + )), + Expanded( + flex: 7, + child: InkWell( + onTap: ()async{ + var result; +// if(display!=null) { +// result = await Navigator.push( +// context, +// MaterialPageRoute( +// builder: (context) => UnitDetails(idInsert: unitsRef[index].mesin_id,), +// ), +// ); +// } +// if(display==null){ + result = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => UnitDetails(unit: unitsRef[index],), + ), + ); +// } + if(result!=null){ + util.showLoading(context); + await loadUnit(); + Navigator.pop(context); + } + }, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Rangka : ${unitsRef[index].rangka}'), + Divider(height: 10,), + Text('Tipe : ${unitsRef[index].tipe}'), + Divider(height: 10,), + Row( + children: [ +// Container(width: MediaQuery.of(context).size.width*0.35,child: Text('State : ${unitsRef[index].state}')), +// Container(width: MediaQuery.of(context).size.width*0.5,child: Text('Tipe : ${unitsRef[index].tipe}',style: TextStyle(fontSize: 12),)), + Text('Timestamp : ${unitsRef[index].timestamp}'), + ], + ), + Divider(height: 10,), + Row( + children: [ + Container(width: MediaQuery.of(context).size.width*0.35,child: Text('Warna : ${unitsRef[index].warna}')), + Text('State : ${unitsRef[index].state}'), + ], + ) + ], + ), + ), + )), + ], + )), + ), + ], + ); + }, + ), + ), + ], + ), + ), + ], + ), + floatingActionButton: FloatingActionButton( + backgroundColor: Colors.indigo.withOpacity(0.8), + onPressed: ()async{ + setState(() { + hideAppbar = !(hideAppbar??false); + }); +// var result = await Navigator.push(context, MaterialPageRoute(builder: (context)=>UnitDetails(unit: new Unit(flag: 'FALSE'),))); +// if(result!=null){ +// util.showLoading(context); +// await loadUnit(); +// Navigator.pop(context); +// } + }, + child: Icon(Icons.search,color:Colors.white), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/unit_details.dart b/lib/unit_details.dart new file mode 100644 index 0000000..c6f5a61 --- /dev/null +++ b/lib/unit_details.dart @@ -0,0 +1,951 @@ +import 'dart:io'; +import 'dart:typed_data'; +import 'package:flutter/services.dart'; +import 'Util/UnitModel.dart'; +import 'Util/photo_viewer.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:image_picker/image_picker.dart'; +import 'Util/DBHelper.dart'; +import 'Util/Util.dart'; +import 'main.dart'; +import 'package:intl/intl.dart'; +//import 'package:autocomplete_textfield/autocomplete_textfield.dart'; + +class UnitDetails extends StatefulWidget { + Unit unit; + UnitDetails({this.unit}); + @override + _UnitDetailsState createState() => _UnitDetailsState(); +} + +class _UnitDetailsState extends State { + final tipeController = TextEditingController(); + final rangkaController = TextEditingController(); + final colorController = TextEditingController(); + final kodeController = TextEditingController(); + final mesinController = TextEditingController(); + final tahunController = TextEditingController(); + final stateController = TextEditingController(); + +// insertUnit _unitDetails; + bool isChanged = false; + Util util = new Util(); + List images = []; + List blobIds = []; + List deleteBlobIds = []; + List dropMenu = []; + List jenisImages = []; + int jenisLength=0; + Unit _currentUnit; + List blobList = []; +// List allUnits = []; + + loadUnitDetails(context)async{ +// if(widget.idInsert!=null){ +//// var result = await DBHelper.database.getInsertUnit(widget.idInsert); +//// if(result!=null){ +//// _unitDetails = result; +//// mesinController.text = _unitDetails.mesin; +//// tipeController.text= _unitDetails.tipe; +//// rangkaController.text = _unitDetails.rangka; +//// colorController.text = _unitDetails.warna; +//// tahunController.text = _unitDetails.tahun; +//// kodeController.text = _unitDetails.kode; +//// stateController.text = _unitDetails.state; +//// +//// result = await DBHelper.database.getAllBlobImage(_unitDetails.id); +//// if(result!=null){ +//// for(int i =0; i element.value==jenisImages[i]); +// } +// } + } + } + + @override + void initState() { + // TODO: implement initState + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) async { + util.showLoading(context); + await Future.sync(()async{await loadUnitDetails(context);}); + Navigator.pop(context); + }); + } + @override + Widget build(BuildContext context) { +// if(allUnits.length!=0){ +// print(allUnits[0].tipe); +//// loadTipe(); +// } + return Scaffold( + resizeToAvoidBottomPadding: true, + appBar: AppBar( + backgroundColor: Colors.transparent, + elevation: 0.0, + iconTheme: IconThemeData( + color: Colors.indigo, + ), + title: Text((widget.unit.flag=='FALSE')?'Inserting New Unit':'Editing Unit',style: TextStyle(color: Colors.indigo),), + ), + body: WillPopScope( + onWillPop: ()async{ + if(widget.unit.flag=='TRUE'){ + if(isChanged){ + await showDialog(context: context,builder: (context)=> + Material( + color: Colors.white.withOpacity(0.9), + child: Center( + child: Container( + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 2, + offset: Offset(0, 0), // changes position of shadow + ), + ], + borderRadius: BorderRadius.circular(5) + ), + height: MediaQuery.of(context).size.height/4.8, + width: MediaQuery.of(context).size.width*0.75, + child: Column( + children: [ + Flexible( + flex:3, + child: Container( + padding: EdgeInsets.only(top:10,left: 10,right: 10), + alignment: Alignment.center, + decoration: BoxDecoration( +// color: Colors.indigo, + borderRadius: BorderRadius.only(topLeft: Radius.circular(5),topRight: Radius.circular(5)) + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Icon(Icons.warning,size: 70,color: Colors.indigo,), + ], + ), + ), + ), + Flexible( + flex: 1, + child: Container( + padding: EdgeInsets.only(left: 20,right: 20), + alignment: Alignment.centerLeft, + child: Text('Data belum disimpan. Lanjutkan ?',style: TextStyle(fontWeight: FontWeight.w500,fontSize: 14,color: Colors.black.withOpacity(0.6)),) + ), + ), + Flexible( + flex: 1, + child: Container( + padding: EdgeInsets.only(bottom:10), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + FlatButton( + child: Text('Proceed'), +// color: Colors.red, + onPressed: (){ + Navigator.pop(context); + Navigator.pop(context); + }, + ), + FlatButton( + child: Text('Cancel'), +// color: Colors.grey, + onPressed: (){ + Navigator.pop(context); + }, + ), + ], + ), + ), + ) + ], + ), + ), + ), + ), + ); + } + else Navigator.pop(context); + } + else{ + bool not_empty = (stateController.text!='-'&&mesinController.text!='-'&&tahunController.text!='-'&&kodeController.text!='-'&&colorController.text!='-'&&rangkaController.text!='-'&&tipeController.text!='-'); + if(blobList.where((element) => element.blob_file!=null).length!=0){ + await showDialog(context: context,builder: (context)=> + Material( + color: Colors.white.withOpacity(0.9), + child: Center( + child: Container( + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 2, + offset: Offset(0, 0), // changes position of shadow + ), + ], + borderRadius: BorderRadius.circular(5) + ), + height: MediaQuery.of(context).size.height/4.8, + width: MediaQuery.of(context).size.width*0.75, + child: Column( + children: [ + Flexible( + flex:3, + child: Container( + padding: EdgeInsets.only(top:10,left: 10,right: 10), + alignment: Alignment.center, + decoration: BoxDecoration( +// color: Colors.indigo, + borderRadius: BorderRadius.only(topLeft: Radius.circular(5),topRight: Radius.circular(5)) + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Icon(Icons.warning,size: 70,color: Colors.indigo,), + ], + ), + ), + ), + Flexible( + flex: 1, + child: Container( + padding: EdgeInsets.only(left: 20,right: 20), + alignment: Alignment.centerLeft, + child: Text('Data belum disimpan. Lanjutkan ?',style: TextStyle(fontWeight: FontWeight.w500,fontSize: 14,color: Colors.black.withOpacity(0.6)),) + ), + ), + Flexible( + flex: 1, + child: Container( + padding: EdgeInsets.only(bottom:10), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + FlatButton( + child: Text('Back',style: TextStyle(color: Colors.indigo),), + onPressed: (){ + Navigator.pop(context); + Navigator.pop(context); + }, + ), + FlatButton( + child: Text('Cancel',style: TextStyle(color: Colors.indigo)), + onPressed: (){ + Navigator.pop(context); + }, + ), + ], + ), + ), + ) + ], + ), + ), + ), + ), + ); + } + else Navigator.pop(context); + } + return false; + }, + child: Container( + padding: EdgeInsets.only(left:10,right: 10,bottom: 10), + child: Column( + children: [ +// SizedBox(height: MediaQuery.of(context).size.height/25,), + Expanded( + child: Row( + children: [ + Flexible( + flex: 4, + child: Container( + height: MediaQuery.of(context).size.height, + child: + ListView.builder( +// itemCount: ((images.length+1)>jenisLength)?jenisLength:images.length+1, + itemCount: blobList.length, + itemBuilder: (context, index){ +// Uint8List image = ((images.length==0)||(images.length<(index+1)))?null:images[index]; + Uint8List image = blobList[index].blob_file; + return Padding( + padding: const EdgeInsets.only(top: 10,right: 10), + child: Material( + child: InkWell( + onTap: ()async{ + if(image==null){ +// var selected = await showDialog( +// context: context, +// builder: (context){ +// var selected = dropMenu[0].value; +// return WillPopScope( +// onWillPop: ()async{ +// Navigator.pop(context,false); +// return false; +// }, +// child: AlertDialog( +// content: StatefulBuilder( +// builder: (context,setState){ +// return DropdownButtonFormField( +// decoration: InputDecoration.collapsed(), +// value: selected, +// onChanged: (value){ +// setState(() { +// selected = value; +// }); +// }, +// items: dropMenu.map((item) { +// return new DropdownMenuItem( +// value: item.value, +// child: Row( +// children: [ +// Text(item.value), +//// (item.optional=='TRUE')?Container():Text(' *',style: TextStyle(color: Colors.red),) +// ], +// ), +// ); +// }).toList(), +// ); +// }, +// ), +// actions: [ +// FlatButton( +// child: Text('Done'), +// onPressed: ()async{ +// jenisImages.add(selected); +// +// Navigator.pop(context,true); +// }, +// ), +// FlatButton( +// child: Text('Cancel'), +// onPressed: (){ +// Navigator.pop(context,false); +// }, +// ), +// ], +// ), +// ); +// } +// ); +// if (selected){ + File temp = await ImagePicker.pickImage(source: ImageSource.camera,maxWidth: 800,imageQuality: 80); + if(temp!=null){ + isChanged = true; + blobList[index].blob_file = temp.readAsBytesSync(); + temp.deleteSync(); +// if(widget.idInsert!=null) { +// blobIds.add(null); +// isChanged = true; +// } + setState(() { + }); + } +// else { +// jenisImages.removeLast(); +// } +// await loadDropMenu(); +// } + } + else { +// List dropNewMenu = new List.from(dropMenu); +// dropNewMenu.add(new jenisDrop(value: jenisImages[index])); + var result = await Navigator.push(context, MaterialPageRoute(builder: (context) => PhotoViewer(image,id: widget.unit.id.toString()+'.$index',jenis: blobList[index].jenis,))); + if(result!=null){ + blobList[index] = result['byte']; + isChanged = true; +// images[index] = result['byte']; +// jenisImages[index] = result['jenis']; +// await loadDropMenu(); +// if(widget.idInsert!=null) { +// isChanged = true; +// } + setState(() { + }); + } + } + }, + splashColor: Colors.grey, + child: Column( + children: [ + Container(padding: EdgeInsets.all(5),child: Text(blobList[index].jenis)), + Stack( + children: [ + Container( + decoration: BoxDecoration( + color: Colors.grey.withOpacity(0.7), + image: (image!=null)?DecorationImage( + image: MemoryImage(image), + fit: BoxFit.cover + ):null, + ), + height: MediaQuery.of(context).size.width*0.35, + width: MediaQuery.of(context).size.width*0.35, + child: (image==null)?Icon(Icons.add):null, + ), + (image!=null)?Container( + height: MediaQuery.of(context).size.width*0.35, + width: MediaQuery.of(context).size.width*0.35, + alignment: Alignment.topRight, + child: InkWell( + onTap: ()async{ +// if(widget.idInsert!=null){ +// isChanged = true; +// deleteBlobIds.add(blobIds[index]); +// blobIds.removeAt(index); +// } + setState(() { + blobList[index].blob_file = null; +// images.removeAt(index); +// jenisImages.removeAt(index); + }); +// await loadDropMenu(); + }, + child: Container( + padding: EdgeInsets.all(5), + child: Icon(Icons.cancel,color: Colors.red,)), + ), + ):Container(), + ], + ), + ], + ), + ), + ), + ); + }) + ), + ), + Flexible( + flex: 6, + child: Container( + alignment: Alignment.topLeft, + padding: EdgeInsets.only(top: 10), + child: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ +// Divider(), +// Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// children: [ +// Expanded( +// child: +// textfield??Container(), +// ), +// ], +// ), + Padding( + padding: const EdgeInsets.all(5.0), + child: Text('Units Details',style: TextStyle(fontSize: 18,fontWeight: FontWeight.bold),), + ), + Divider(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('Tipe : '), + Expanded( + child: + TextFormField( + enabled: false, + style: TextStyle(color: Colors.grey), + controller: tipeController, + decoration: InputDecoration.collapsed(hintText: null), + ), + ), + ], + ), + Divider(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('Mesin : '), + Expanded( + child: TextFormField( + enabled: false, + style: TextStyle(color: Colors.grey), + controller: mesinController, + decoration: InputDecoration.collapsed(hintText: null), + ), + ), + ], + ), + Divider(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('Rangka : '), + Expanded( + child: TextFormField( + enabled: false, + style: TextStyle(color: Colors.grey), + controller: rangkaController, + decoration: InputDecoration.collapsed(hintText: null), + ), + ), + ], + ), + Divider(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('Kode : '), + Expanded( + child: TextFormField( + enabled: false, + style: TextStyle(color: Colors.grey), + controller: kodeController, + decoration: InputDecoration.collapsed(hintText: null), + ), + ), + ], + ), + Divider(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('Tahun : '), + Expanded( + child: TextFormField( + enabled: false, + style: TextStyle(color: Colors.grey), + controller: tahunController, + decoration: InputDecoration.collapsed(hintText: null), + ), + ), + ], + ), + Divider(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('Warna : '), + Expanded( + child: TextFormField( + enabled: false, + style: TextStyle(color: Colors.grey), + controller: colorController, + decoration: InputDecoration.collapsed(hintText: null), + ), + ), + ], + ), + Divider(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('State : '), + Expanded( + child: TextFormField( + enabled: false, + style: TextStyle(color: Colors.grey), + controller: stateController, + decoration: InputDecoration.collapsed(hintText: null), + ), + ), + ], + ), + Divider(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + FlatButton( + child: Text((widget.unit.flag=='FALSE')?'Add':'Save'), + onPressed: ()async{ + bool succeed = false; + String errMsg = ''; + util.showLoading(context); + await Future.sync(()async{ + if(currentPosisiton!=null) { + if(blobList.where((element) => element.blob_file!=null).length==blobList.length){ + for(int i = 0 ; i + Material( + color: Colors.white.withOpacity(0.9), + child: Center( + child: Container( + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 2, + offset: Offset(0, 0), // changes position of shadow + ), + ], + borderRadius: BorderRadius.circular(5) + ), + height: MediaQuery.of(context).size.height/4.8, + width: MediaQuery.of(context).size.width*0.75, + child: Column( + children: [ + Flexible( + flex:3, + child: Container( + padding: EdgeInsets.only(top:10,left: 10,right: 10), + alignment: Alignment.center, + decoration: BoxDecoration( +// color: Colors.indigo, + borderRadius: BorderRadius.only(topLeft: Radius.circular(5),topRight: Radius.circular(5)) + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Icon(Icons.warning,size: 70,color: Colors.indigo,), + ], + ), + ), + ), + Flexible( + flex: 1, + child: Container( + padding: EdgeInsets.only(left: 20,right: 20), + alignment: Alignment.centerLeft, + child: Text('Data belum disimpan. Lanjutkan ?',style: TextStyle(fontWeight: FontWeight.w500,fontSize: 14,color: Colors.black.withOpacity(0.6)),) + ), + ), + Flexible( + flex: 1, + child: Container( + padding: EdgeInsets.only(bottom:10), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + FlatButton( + child: Text('Proceed'), + onPressed: (){ + Navigator.pop(context); + Navigator.popUntil(context,ModalRoute.withName('/stocking')); + }, + ), + FlatButton( + child: Text('Cancel'), +// color: Colors.grey, + onPressed: (){ + Navigator.pop(context); + }, + ), + ], + ), + ), + ) + ], + ), + ), + ), + ), + ); + } + else Navigator.pop(context); + } + else { +// bool not_empty = (stateController.text!='-'&&mesinController.text!='-'&&tahunController.text!='-'&&kodeController.text!='-'&&colorController.text!='-'&&rangkaController.text!='-'&&tipeController.text!='-'); + if(blobList.where((element) => element.blob_file!=null).length!=0){ + await showDialog(context: context,builder: (context)=> + Material( + color: Colors.white.withOpacity(0.9), + child: Center( + child: Container( + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 2, + offset: Offset(0, 0), // changes position of shadow + ), + ], + borderRadius: BorderRadius.circular(5) + ), + height: MediaQuery.of(context).size.height/4.8, + width: MediaQuery.of(context).size.width*0.75, + child: Column( + children: [ + Flexible( + flex:3, + child: Container( + padding: EdgeInsets.only(top:10,left: 10,right: 10), + alignment: Alignment.center, + decoration: BoxDecoration( +// color: Colors.indigo, + borderRadius: BorderRadius.only(topLeft: Radius.circular(5),topRight: Radius.circular(5)) + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Icon(Icons.warning,size: 70,color: Colors.indigo,), + ], + ), + ), + ), + Flexible( + flex: 1, + child: Container( + padding: EdgeInsets.only(left: 20,right: 20), + alignment: Alignment.centerLeft, + child: Text('Data belum disimpan. Lanjutkan ?',style: TextStyle(fontWeight: FontWeight.w500,fontSize: 14,color: Colors.black.withOpacity(0.6)),) + ), + ), + Flexible( + flex: 1, + child: Container( + padding: EdgeInsets.only(bottom:10), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + FlatButton( + child: Text('Back'), + onPressed: (){ + Navigator.pop(context); + Navigator.popUntil(context,ModalRoute.withName('/stocking')); + }, + ), + FlatButton( + child: Text('Cancel'), + onPressed: (){ + Navigator.pop(context); + }, + ), + ], + ), + ), + ) + ], + ), + ), + ), + ), + ); + } + else Navigator.pop(context); + } + }, + color: Colors.redAccent, + ) + ], + ) + ], + ), + ), + ), + ) + ], + ), + ), + ], + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/local_plugin/location-3.0.2/.gitignore b/local_plugin/location-3.0.2/.gitignore new file mode 100644 index 0000000..281c6e8 --- /dev/null +++ b/local_plugin/location-3.0.2/.gitignore @@ -0,0 +1,43 @@ +.atom/ +.idea/ +.vscode/ + +.packages +.pub/ +.dart_tool/ +pubspec.lock +flutter_export_environment.sh + +examples/all_plugins/pubspec.yaml + +Podfile +Podfile.lock +Pods/ +.symlinks/ +**/Flutter/App.framework/ +**/Flutter/Flutter.framework/ +**/Flutter/Generated.xcconfig +**/Flutter/flutter_assets/ +ServiceDefinitions.json +xcuserdata/ +*.xcworkspace +**/DerivedData/ + +local.properties +keystore.properties +.gradle/ +gradlew +gradlew.bat +gradle-wrapper.jar +.flutter-plugins-dependencies +*.iml + +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m +GeneratedPluginRegistrant.java +build/ +.flutter-plugins + +.project +.classpath +.settings diff --git a/local_plugin/location-3.0.2/CHANGELOG.md b/local_plugin/location-3.0.2/CHANGELOG.md new file mode 100644 index 0000000..631d71a --- /dev/null +++ b/local_plugin/location-3.0.2/CHANGELOG.md @@ -0,0 +1,162 @@ +## [3.0.2] 3rd April 2020 + +- Improve code coverage +- Fix a bug when requesting permission using an intent (thanks to kennethj) +- Fix a bug when onDetachedFromActivity is called (thanks to creativepsyco) + +## [3.0.1] 27th March 2020 + +- Fix a crash happening during iOS build + +## [3.0.0] 26th March 2020 + +- Add Web and macOS as new supported platforms (huge thanks to long1eu) +- [BREAKING] Enums are now following Dart guidelines. +- [BREAKING] _onLocationChanged_ is now a getter to follow Dart guidelines. + +## [2.5.4] 11st March 2020 + +- Update documentation +- Fix: Airplane mode was preventing location from being requested +- Fix: Not crashing when activity is not set on Android + +## [2.5.3] 26th February 2020 + +- Improve code coverage +- Update documentation + +## [2.5.2] 25th February 2020 + +- Fix crash on pre-1.12 projects +- Align PermissionStatus on iOS with Android + +## [2.5.1] 23rd February 2020 + +- Fix SDK version + +## [2.5.0] 23rd February 2020 + +- [BREAKING] The `requestPermission` and `hasPermission` are now returning PermissionStatus enum. +- Upgrade to Android Embedding V2 (follow https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects if the plugin isn't working after upgrade) +- Resolve getLocation when service is disabled thanks to nicowernli +- Update example app +- Fix bugs leading to non returning code +- `getLocation` now throws properly +- `pub.dev` now states that the plugin is not compatible with Flutter Web (yet) + +## [2.4.0] 14th February 2020 + +- Align timestamp in Android and iOS, previously the iOS timestamp was in seconds instead of milliseconds. Thanks to 781flyingdutchman. + +## [2.3.7] 08th January 2020 + +- Fix bug where requestPermission is called after the user has already denied the system location dialog, then this method call would never return. + +## [2.3.6] 07th January 2020 + +- Fix ClassCastException errors on some Android phones when requesting Location status. + +## [2.3.5] 10th April 2019 + +- Fix incompatibily with headless plugins thanks to ehhc +- Fix error with iOS when permission already given +- Add Google maps example + +## [2.3.4] 8th April 2019 + +- Fix error on Android 21 API thanks to noordawod +- Update Google API version + +## [2.3.3] 31th March 2019 + +- Align altitude on Sea Level when available on Android (matching iOS altitude). + +## [2.3.2] 27th March 2019 + +- Remove GPS limitation on Android + +## [2.3.1] 25th March 2019 + +- Fixes README +- Fixes requestPermission not responding the correct result on iOS + +## [2.3.0] 22nd March 2019 + +- Update example App with proper cancel +- Add possibility to set accuracy, interval and minimum notification ditance of the requests. +- Add LocationAccuracy object + +## [2.2.0] 19th March 2019 + +- Actually updating locatino when using getLocation (not only relying on LastLocation) +- Add timestamp to LocationData +- Add serviceEnabled method to check whether Location Service is enabled. +- Add requestService method to ask the user to activate the location service. +- Fix continuous callback heading + +## [2.1.0] 16th Match 2019 + +- iOS permission should be closer to Android permission behaviour thanks to PerrchicK +- Adding requestPermission(), to manually request permission +- Several feature fixed for less crash when using the plugin +- Code Cleanup +- Update Readme and add a warning for the location bug in iOS simulator + +## [2.0.0] 25th January 2019 + +- Code cleanup +- BREAKING CHANGE: Change Dart API to return structured data rather than a map. + +## [1.4.0] 21st August 2018 + +- Add lazy permission request thanks to yathit +- Add hasPermission() thanks to vagrantrobbie +- Bug correction thanks to jalpedersen +- Add more examples + +## [1.3.4] 4th June 2018 + +- Fix crash for Android API pre 27 thanks to matthewtsmith. + +## [1.3.3] 30th May 2018 + +- Correct implementation of iOS plugin to match Android behaviour. No need to call getLocation + to get permissions for location callbacks. + +## [1.3.2] 30th May 2018 + +- Change implementation to api in build.gradle in order to solve incompatibilities between + GMS versions thanks to luccascorrea + +## [1.3.1] 29th May 2018 + +- Added speed and speed_accuracy (only Android truly discover speed accuracy, so its always 0 for now on iOS) +- Solved a crash + +## [1.3.0] 27th May 2018 + +- Make it compatible with Firebase thanks to quangIO +- Resolve runtime error exception thanks to jharrison902 +- Update gitignore thanks to bcko + +## [1.2.0] 5th April 2018 + +- Permissions denied on Android handled thanks to g123k +- Dart 2 update thanks to efortuna + +## [1.1.6] - 19th Octobre 2017. + +- iOS code from Swift to Objective-C thanks to fluff + +## [1.1.1] - 20th July 2017. + +- Fixes for iOS result's format. + +## [1.1.0] - 17th July 2017. + +- Added permission check for Android 6+ (thanks netdur). Still no callback when permissions granted + so aiming SDK 21 is safer. + +## [1.0.0] - 7th July 2017. + +- Initial Release. diff --git a/local_plugin/location-3.0.2/LICENSE b/local_plugin/location-3.0.2/LICENSE new file mode 100644 index 0000000..5bd7d0a --- /dev/null +++ b/local_plugin/location-3.0.2/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2017, Guillaume Bernos. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/local_plugin/location-3.0.2/README.md b/local_plugin/location-3.0.2/README.md new file mode 100644 index 0000000..43ee055 --- /dev/null +++ b/local_plugin/location-3.0.2/README.md @@ -0,0 +1,156 @@ +# Flutter Location Plugin + +[![pub package](https://img.shields.io/pub/v/location.svg)](https://pub.dartlang.org/packages/location) ![Cirrus CI - Task and Script Build Status](https://img.shields.io/cirrus/github/Lyokone/flutterlocation?task=test) +[![codecov](https://codecov.io/gh/Lyokone/flutterlocation/branch/master/graph/badge.svg)](https://codecov.io/gh/Lyokone/flutterlocation) + +This plugin for [Flutter](https://flutter.io) +handles getting location on Android and iOS. It also provides callbacks when location is changed. + +

+ Demo App +

+ +## Getting Started + +Add this to your package's `pubspec.yaml` file: + +```yaml +dependencies: + location: ^3.0.0 +``` + +### Android + +With Flutter 1.12, all the dependencies are automatically added to your project. +If your project was created before Flutter 1.12, you may need to follow [this](https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects). + +### iOS + +And to use it in iOS, you have to add this permission in Info.plist : + +```xml +NSLocationWhenInUseUsageDescription +NSLocationAlwaysUsageDescription +``` + +### Web + +Nothing to do, the plugin works directly out of box. + +### macOS + +Ensure that the application is properly "sandboxed" and that the location is enabled. You can do this in Xcode with the following steps: + +1. In the project navigator, click on your application's target. This should bring up a view with tabs such as "General", "Capabilities", "Resource Tags", etc. +1. Click on the "Capabilities" tab. This will give you a list of items such as "App Groups", "App Sandbox" and so on. Each item will have an "On/Off" button. +1. Turn on the "App Sandbox" item and press the ">" button on the left to show the sandbox stuff. +1. In the "App Data" section, select "Location". + +Add this permission in Info.plist : + +```xml +NSLocationWhenInUseUsageDescription +NSLocationAlwaysUsageDescription +``` + +## Usage + +Then you just have to import the package with + +```dart +import 'package:location/location.dart'; +``` + +In order to request location, you should always check manually Location Service status and Permission status. + +```dart +Location location = new Location(); + +bool _serviceEnabled; +PermissionStatus _permissionGranted; +LocationData _locationData; + +_serviceEnabled = await location.serviceEnabled(); +if (!_serviceEnabled) { + _serviceEnabled = await location.requestService(); + if (!_serviceEnabled) { + return; + } +} + +_permissionGranted = await location.hasPermission(); +if (_permissionGranted == PermissionStatus.denied) { + _permissionGranted = await location.requestPermission(); + if (_permissionGranted != PermissionStatus.granted) { + return; + } +} + +_locationData = await location.getLocation(); +``` + +You can also get continuous callbacks when your position is changing: + +```dart +location.onLocationChanged.listen((LocationData currentLocation) { + // Use current location +}); +``` + +Be sure to check the example project to get other code samples. + +## Public Methods Summary + +| Return | Description | +| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Future\ | **requestPermission()**
Request the Location permission. Return a PermissionStatus to know if the permission has been granted. | +| Future\ | **hasPermission()**
Return a PermissionStatus to know the state of the location permission. | +| Future\ | **serviceEnabled()**
Return a boolean to know if the Location Service is enabled or if the user manually deactivated it. | +| Future\ | **requestService()**
Show an alert dialog to request the user to activate the Location Service. On iOS, will only display an alert due to Apple Guidelines, the user having to manually go to Settings. Return a boolean to know if the Location Service has been activated (always `false` on iOS). | +| Future\ | **changeSettings(LocationAccuracy accuracy = LocationAccuracy.HIGH, int interval = 1000, double distanceFilter = 0)**
Will change the settings of futur requests. `accuracy`will describe the accuracy of the request (see the LocationAccuracy object). `interval` will set the desired interval for active location updates, in milliseconds (only affects Android). `distanceFilter` set the minimum displacement between location updates in meters. | +| Future\ | **getLocation()**
Allow to get a one time position of the user. It will try to request permission if not granted yet and will throw a `PERMISSION_DENIED` error code if permission still not granted. | +| Stream\ | **onLocationChanged**
Get the stream of the user's location. It will try to request permission if not granted yet and will throw a `PERMISSION_DENIED` error code if permission still not granted. | + +You should try to manage permission manually with `requestPermission()` to avoid error, but plugin will try handle some cases for you. + +## Objects + +```dart +class LocationData { + final double latitude; // Latitude, in degrees + final double longitude; // Longitude, in degrees + final double accuracy; // Estimated horizontal accuracy of this location, radial, in meters + final double altitude; // In meters above the WGS 84 reference ellipsoid + final double speed; // In meters/second + final double speedAccuracy; // In meters/second, always 0 on iOS + final double heading; //Heading is the horizontal direction of travel of this device, in degrees + final double time; //timestamp of the LocationData +} + + +enum LocationAccuracy { + powerSave, // To request best accuracy possible with zero additional power consumption, + low, // To request "city" level accuracy + balanced, // To request "block" level accuracy + high, // To request the most accurate locations available + navigation // To request location for navigation usage (affect only iOS) +} + +// Status of a permission request to use location services. +enum PermissionStatus { + /// The permission to use location services has been granted. + granted, + // The permission to use location services has been denied by the user. May have been denied forever on iOS. + denied, + // The permission to use location services has been denied forever by the user. No dialog will be displayed on permission request. + deniedForever +} + +``` + +Note: you can convert the timestamp into a `DateTime` with: `DateTime.fromMillisecondsSinceEpoch(locationData.time.toInt())` + +## Feedback + +Please feel free to [give me any feedback](https://github.com/Lyokone/flutterlocation/issues) +helping support this plugin ! diff --git a/local_plugin/location-3.0.2/android/build.gradle b/local_plugin/location-3.0.2/android/build.gradle new file mode 100644 index 0000000..c39e5c6 --- /dev/null +++ b/local_plugin/location-3.0.2/android/build.gradle @@ -0,0 +1,42 @@ +group 'com.lyokone.location' +version '1.0-SNAPSHOT' + +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.5.0' + } +} + +rootProject.allprojects { + repositories { + google() + jcenter() + + } +} + + + + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 28 + + defaultConfig { + minSdkVersion 16 + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + lintOptions { + disable 'InvalidPackage' + } +} + +dependencies { + api 'com.google.android.gms:play-services-location:16.+' +} diff --git a/local_plugin/location-3.0.2/android/gradle.properties b/local_plugin/location-3.0.2/android/gradle.properties new file mode 100644 index 0000000..53ae0ae --- /dev/null +++ b/local_plugin/location-3.0.2/android/gradle.properties @@ -0,0 +1,3 @@ +android.enableJetifier=true +android.useAndroidX=true +org.gradle.jvmargs=-Xmx1536M diff --git a/local_plugin/location-3.0.2/android/gradle/wrapper/gradle-wrapper.properties b/local_plugin/location-3.0.2/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..092daf3 --- /dev/null +++ b/local_plugin/location-3.0.2/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Sun Feb 16 18:22:06 CET 2020 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip diff --git a/local_plugin/location-3.0.2/android/settings.gradle b/local_plugin/location-3.0.2/android/settings.gradle new file mode 100644 index 0000000..82139d0 --- /dev/null +++ b/local_plugin/location-3.0.2/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'location' diff --git a/local_plugin/location-3.0.2/android/src/main/AndroidManifest.xml b/local_plugin/location-3.0.2/android/src/main/AndroidManifest.xml new file mode 100644 index 0000000..862aa42 --- /dev/null +++ b/local_plugin/location-3.0.2/android/src/main/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/local_plugin/location-3.0.2/android/src/main/java/com/lyokone/location/FlutterLocation.java b/local_plugin/location-3.0.2/android/src/main/java/com/lyokone/location/FlutterLocation.java new file mode 100644 index 0000000..a06c559 --- /dev/null +++ b/local_plugin/location-3.0.2/android/src/main/java/com/lyokone/location/FlutterLocation.java @@ -0,0 +1,425 @@ +package com.lyokone.location; + +import android.Manifest; +import android.annotation.TargetApi; +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.IntentSender; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationManager; +import android.location.OnNmeaMessageListener; +import android.os.Build; +import android.os.Looper; +import android.util.Log; + +import com.google.android.gms.common.api.ApiException; +import com.google.android.gms.common.api.ResolvableApiException; +import com.google.android.gms.location.FusedLocationProviderClient; +import com.google.android.gms.location.LocationCallback; +import com.google.android.gms.location.LocationRequest; +import com.google.android.gms.location.LocationResult; +import com.google.android.gms.location.LocationServices; +import com.google.android.gms.location.LocationSettingsRequest; +import com.google.android.gms.location.LocationSettingsResponse; +import com.google.android.gms.location.LocationSettingsStatusCodes; +import com.google.android.gms.location.SettingsClient; +import com.google.android.gms.tasks.OnFailureListener; +import com.google.android.gms.tasks.OnSuccessListener; + +import java.util.HashMap; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.app.ActivityCompat; +import io.flutter.plugin.common.EventChannel.EventSink; +import io.flutter.plugin.common.MethodChannel.Result; +import io.flutter.plugin.common.PluginRegistry; + +class FlutterLocation + implements PluginRegistry.RequestPermissionsResultListener, PluginRegistry.ActivityResultListener { + private static final String TAG = "FlutterLocation"; + + private final Context applicationContext; + + @Nullable + public Activity activity; + + private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34; + private static final int REQUEST_CHECK_SETTINGS = 0x1; + + private static final int GPS_ENABLE_REQUEST = 0x1001; + + public FusedLocationProviderClient mFusedLocationClient; + private SettingsClient mSettingsClient; + private static LocationRequest mLocationRequest; + private LocationSettingsRequest mLocationSettingsRequest; + public LocationCallback mLocationCallback; + + @TargetApi(Build.VERSION_CODES.N) + private OnNmeaMessageListener mMessageListener; + + private Double mLastMslAltitude; + + // Parameters of the request + private static long updateIntervalMilliseconds = 5000; + private static long fastestUpdateIntervalMilliseconds = updateIntervalMilliseconds / 2; + private static Integer locationAccuracy = LocationRequest.PRIORITY_HIGH_ACCURACY; + private static float distanceFilter = 0f; + + public EventSink events; + + // Store result until a permission check is resolved + public Result result; + + // Store result until a location is getting resolved + public Result getLocationResult; + + private int locationPermissionState; + + private boolean waitingForPermission = false; + private LocationManager locationManager; + + public HashMap mapFlutterAccuracy = new HashMap() { + { + put(0, LocationRequest.PRIORITY_NO_POWER); + put(1, LocationRequest.PRIORITY_LOW_POWER); + put(2, LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); + put(3, LocationRequest.PRIORITY_HIGH_ACCURACY); + put(4, LocationRequest.PRIORITY_HIGH_ACCURACY); + } + }; + + FlutterLocation(Context applicationContext, @Nullable Activity activity) { + this.applicationContext = applicationContext; + this.activity = activity; + } + + FlutterLocation(PluginRegistry.Registrar registrar) { + this(registrar.context(), registrar.activity()); + registrar.addRequestPermissionsResultListener(this); + } + + void setActivity(@Nullable Activity activity) { + this.activity = activity; + mFusedLocationClient = LocationServices.getFusedLocationProviderClient(activity); + mSettingsClient = LocationServices.getSettingsClient(activity); + locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE); + + createLocationCallback(); + createLocationRequest(); + buildLocationSettingsRequest(); + } + + @Override + public boolean onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + return onRequestPermissionsResultHandler(requestCode, permissions, grantResults); + } + + public boolean onRequestPermissionsResultHandler(int requestCode, String[] permissions, int[] grantResults) { + if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE && permissions.length == 1 + && permissions[0].equals(Manifest.permission.ACCESS_FINE_LOCATION)) { + if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { + // Checks if this permission was automatically triggered by a location request + if (getLocationResult != null || events != null) { + startRequestingLocation(); + } + if (result != null) { + result.success(1); + result = null; + } + } else { + if (!shouldShowRequestPermissionRationale()) { + sendError("PERMISSION_DENIED_NEVER_ASK", + "Location permission denied forever - please open app settings", null); + if (result != null) { + result.success(2); + result = null; + } + } else { + sendError("PERMISSION_DENIED", "Location permission denied", null); + if (result != null) { + result.success(0); + result = null; + } + } + } + return true; + } + return false; + + } + + @Override + public boolean onActivityResult(int requestCode, int resultCode, Intent data) { + if (result == null) { + return false; + } + switch (requestCode) { + case GPS_ENABLE_REQUEST: + if (resultCode == Activity.RESULT_OK) { + result.success(1); + } else { + result.success(0); + } + break; + case REQUEST_CHECK_SETTINGS: + if (resultCode == Activity.RESULT_OK) { + startRequestingLocation(); + return true; + } + + result.error("SERVICE_STATUS_DISABLED", "Failed to get location. Location services disabled", null); + return false; + default: + return false; + } + return true; + } + + public void changeSettings(Integer locationAccuracy, Long updateIntervalMilliseconds, + Long fastestUpdateIntervalMilliseconds, Float distanceFilter) { + this.locationAccuracy = locationAccuracy; + this.updateIntervalMilliseconds = updateIntervalMilliseconds; + this.fastestUpdateIntervalMilliseconds = fastestUpdateIntervalMilliseconds; + this.distanceFilter = distanceFilter; + + createLocationCallback(); + createLocationRequest(); + buildLocationSettingsRequest(); + } + + private void sendError(String errorCode, String errorMessage, Object errorDetails) { + if (getLocationResult != null) { + getLocationResult.error(errorCode, errorMessage, errorDetails); + getLocationResult = null; + } + if (events != null) { + events.error(errorCode, errorMessage, errorDetails); + events = null; + } + } + + /** + * Creates a callback for receiving location events. + */ + private void createLocationCallback() { + mLocationCallback = new LocationCallback() { + @Override + public void onLocationResult(LocationResult locationResult) { + super.onLocationResult(locationResult); + Location location = locationResult.getLastLocation(); + HashMap loc = new HashMap<>(); + loc.put("latitude", location.getLatitude()); + loc.put("longitude", location.getLongitude()); + loc.put("accuracy", (double) location.getAccuracy()); + + // Using NMEA Data to get MSL level altitude + if (mLastMslAltitude == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { + loc.put("altitude", location.getAltitude()); + } else { + loc.put("altitude", mLastMslAltitude); + } + + loc.put("speed", (double) location.getSpeed()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + loc.put("speed_accuracy", (double) location.getSpeedAccuracyMetersPerSecond()); + } + loc.put("heading", (double) location.getBearing()); + loc.put("time", (double) location.getTime()); + + if (getLocationResult != null) { + getLocationResult.success(loc); + getLocationResult = null; + } + if (events != null) { + events.success(loc); + } else { + mFusedLocationClient.removeLocationUpdates(mLocationCallback); + } + } + }; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + mMessageListener = new OnNmeaMessageListener() { + @Override + public void onNmeaMessage(String message, long timestamp) { + if (message.startsWith("$")) { + String[] tokens = message.split(","); + String type = tokens[0]; + + // Parse altitude above sea level, Detailed description of NMEA string here + // http://aprs.gids.nl/nmea/#gga + if (type.startsWith("$GPGGA") && tokens.length > 9) { + if (!tokens[9].isEmpty()) { + mLastMslAltitude = Double.parseDouble(tokens[9]); + } + } + } + } + }; + } + } + + /** + * Sets up the location request. Android has two location request settings: + */ + private void createLocationRequest() { + this.mLocationRequest = LocationRequest.create(); + + this.mLocationRequest.setInterval(this.updateIntervalMilliseconds); + this.mLocationRequest.setFastestInterval(this.fastestUpdateIntervalMilliseconds); + this.mLocationRequest.setPriority(this.locationAccuracy); + this.mLocationRequest.setSmallestDisplacement(this.distanceFilter); + } + + /** + * Uses a + * {@link com.google.android.gms.location.LocationSettingsRequest.Builder} to + * build a {@link com.google.android.gms.location.LocationSettingsRequest} that + * is used for checking if a device has the needed location settings. + */ + private void buildLocationSettingsRequest() { + LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder(); + builder.addLocationRequest(mLocationRequest); + mLocationSettingsRequest = builder.build(); + } + + /** + * Return the current state of the permissions needed. + */ + public boolean checkPermissions() { + this.locationPermissionState = ActivityCompat.checkSelfPermission(activity, + Manifest.permission.ACCESS_FINE_LOCATION); + return this.locationPermissionState == PackageManager.PERMISSION_GRANTED; + } + + public void requestPermissions() { + if (checkPermissions()) { + result.success(1); + return; + } + ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.ACCESS_FINE_LOCATION }, + REQUEST_PERMISSIONS_REQUEST_CODE); + } + + public boolean shouldShowRequestPermissionRationale() { + return ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_FINE_LOCATION); + } + + public boolean checkServiceEnabled(final Result result) { + boolean gps_enabled = false; + boolean network_enabled = false; + + try { + gps_enabled = this.locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); + network_enabled = this.locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); + } catch (Exception ex) { + result.error("SERVICE_STATUS_ERROR", "Location service status couldn't be determined", null); + return false; + } + if (gps_enabled && network_enabled) { + if (result != null) { + result.success(1); + } + return true; + + } else { + if (result != null) { + result.success(0); + } + return false; + } + } + + public void requestService(final Result result) { + if (this.checkServiceEnabled(null)) { + result.success(1); + return; + } + this.result = result; + mSettingsClient.checkLocationSettings(mLocationSettingsRequest).addOnFailureListener(activity, + new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception e) { + if (e instanceof ResolvableApiException) { + ResolvableApiException rae = (ResolvableApiException) e; + int statusCode = rae.getStatusCode(); + switch (statusCode) { + case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: + try { + // Show the dialog by calling startResolutionForResult(), and check the + // result in onActivityResult(). + rae.startResolutionForResult(activity, GPS_ENABLE_REQUEST); + } catch (IntentSender.SendIntentException sie) { + result.error("SERVICE_STATUS_ERROR", "Could not resolve location request", + null); + } + break; + case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE: + result.error("SERVICE_STATUS_DISABLED", + "Failed to get location. Location services disabled", null); + break; + } + } else { + // This should not happen according to Android documentation but it has been + // observed on some phones. + result.error("SERVICE_STATUS_ERROR", "Unexpected error type received", null); + } + } + }); + } + + public void startRequestingLocation() { + mSettingsClient.checkLocationSettings(mLocationSettingsRequest) + .addOnSuccessListener(activity, new OnSuccessListener() { + @Override + public void onSuccess(LocationSettingsResponse locationSettingsResponse) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + locationManager.addNmeaListener(mMessageListener); + } + mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, + Looper.myLooper()); + } + }).addOnFailureListener(activity, new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception e) { + if (e instanceof ResolvableApiException) { + ResolvableApiException rae = (ResolvableApiException) e; + int statusCode = rae.getStatusCode(); + switch (statusCode) { + case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: + try { + // Show the dialog by calling startResolutionForResult(), and check the + // result in onActivityResult(). + rae.startResolutionForResult(activity, REQUEST_CHECK_SETTINGS); + } catch (IntentSender.SendIntentException sie) { + Log.i(TAG, "PendingIntent unable to execute request."); + } + break; + } + } else { + ApiException ae = (ApiException) e; + int statusCode = ae.getStatusCode(); + switch (statusCode) { + case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE: + // This error code happens during AirPlane mode. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + locationManager.addNmeaListener(mMessageListener); + } + mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, + Looper.myLooper()); + break; + default: + // This should not happen according to Android documentation but it has been + // observed on some phones. + sendError("UNEXPECTED_ERROR", e.getMessage(), null); + break; + } + } + } + }); + } + +} diff --git a/local_plugin/location-3.0.2/android/src/main/java/com/lyokone/location/LocationPlugin.java b/local_plugin/location-3.0.2/android/src/main/java/com/lyokone/location/LocationPlugin.java new file mode 100644 index 0000000..18720d5 --- /dev/null +++ b/local_plugin/location-3.0.2/android/src/main/java/com/lyokone/location/LocationPlugin.java @@ -0,0 +1,113 @@ +package com.lyokone.location; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.embedding.engine.plugins.activity.ActivityAware; +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; +import io.flutter.plugin.common.PluginRegistry.Registrar; +import io.flutter.plugin.common.BinaryMessenger; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugin.common.PluginRegistry; + +/** + * LocationPlugin + */ +public class LocationPlugin implements FlutterPlugin, ActivityAware { + private static final String TAG = "LocationPlugin"; + @Nullable + private MethodCallHandlerImpl methodCallHandler; + @Nullable + private StreamHandlerImpl streamHandlerImpl; + + @Nullable + private FlutterLocation location; + + private FlutterPluginBinding pluginBinding; + private ActivityPluginBinding activityBinding; + + public static void registerWith(Registrar registrar) { + FlutterLocation flutterLocation = new FlutterLocation(registrar); + flutterLocation.setActivity(registrar.activity()); + + MethodCallHandlerImpl handler = new MethodCallHandlerImpl(flutterLocation); + handler.startListening(registrar.messenger()); + + StreamHandlerImpl streamHandlerImpl = new StreamHandlerImpl(flutterLocation); + streamHandlerImpl.startListening(registrar.messenger()); + } + + @Override + public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { + pluginBinding = binding; + + location = new FlutterLocation(binding.getApplicationContext(), /* activity= */ null); + methodCallHandler = new MethodCallHandlerImpl(location); + methodCallHandler.startListening(binding.getBinaryMessenger()); + + streamHandlerImpl = new StreamHandlerImpl(location); + streamHandlerImpl.startListening(binding.getBinaryMessenger()); + } + + @Override + public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { + pluginBinding = null; + + if (methodCallHandler != null) { + methodCallHandler.stopListening(); + methodCallHandler = null; + } + + if (streamHandlerImpl != null) { + streamHandlerImpl.stopListening(); + streamHandlerImpl = null; + } + + location = null; + } + + @Override + public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { + location.setActivity(binding.getActivity()); + + activityBinding = binding; + setup(pluginBinding.getBinaryMessenger(), activityBinding.getActivity(), null); + } + + @Override + public void onDetachedFromActivity() { + tearDown(); + } + + @Override + public void onDetachedFromActivityForConfigChanges() { + onDetachedFromActivity(); + } + + @Override + public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) { + onAttachedToActivity(binding); + } + + private void setup(final BinaryMessenger messenger, final Activity activity, + final PluginRegistry.Registrar registrar) { + if (registrar != null) { + // V1 embedding setup for activity listeners. + registrar.addActivityResultListener(location); + registrar.addRequestPermissionsResultListener(location); + } else { + // V2 embedding setup for activity listeners. + activityBinding.addActivityResultListener(location); + activityBinding.addRequestPermissionsResultListener(location); + } + } + + private void tearDown() { + activityBinding.removeActivityResultListener(location); + activityBinding.removeRequestPermissionsResultListener(location); + } +} diff --git a/local_plugin/location-3.0.2/android/src/main/java/com/lyokone/location/MethodCallHandlerImpl.java b/local_plugin/location-3.0.2/android/src/main/java/com/lyokone/location/MethodCallHandlerImpl.java new file mode 100644 index 0000000..fdb0988 --- /dev/null +++ b/local_plugin/location-3.0.2/android/src/main/java/com/lyokone/location/MethodCallHandlerImpl.java @@ -0,0 +1,134 @@ +package com.lyokone.location; + +import android.os.Build; +import android.os.Bundle; +import android.util.Log; +import androidx.annotation.Nullable; +import io.flutter.plugin.common.BinaryMessenger; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugin.common.MethodChannel.MethodCallHandler; +import io.flutter.plugin.common.MethodChannel.Result; + +final class MethodCallHandlerImpl implements MethodCallHandler { + private static final String TAG = "MethodCallHandlerImpl"; + + private final FlutterLocation location; + @Nullable + private MethodChannel channel; + + private static final String METHOD_CHANNEL_NAME = "lyokone/location"; + + MethodCallHandlerImpl(FlutterLocation location) { + this.location = location; + } + + @Override + public void onMethodCall(MethodCall call, Result result) { + if (location.activity == null) { + result.error("NO_ACTIVITY", null, null); + return; + } + + switch (call.method) { + case "changeSettings": + onChangeSettings(call, result); + break; + case "getLocation": + onGetLocation(result); + break; + case "hasPermission": + onHasPermission(result); + break; + case "requestPermission": + onRequestPermission(result); + break; + case "serviceEnabled": + location.checkServiceEnabled(result); + break; + case "requestService": + location.requestService(result); + break; + default: + result.notImplemented(); + break; + } + } + + /** + * Registers this instance as a method call handler on the given + * {@code messenger}. + */ + void startListening(BinaryMessenger messenger) { + if (channel != null) { + Log.wtf(TAG, "Setting a method call handler before the last was disposed."); + stopListening(); + } + + channel = new MethodChannel(messenger, METHOD_CHANNEL_NAME); + channel.setMethodCallHandler(this); + } + + /** + * Clears this instance from listening to method calls. + */ + void stopListening() { + if (channel == null) { + Log.d(TAG, "Tried to stop listening when no MethodChannel had been initialized."); + return; + } + + channel.setMethodCallHandler(null); + channel = null; + } + + private void onChangeSettings(MethodCall call, Result result) { + try { + final Integer locationAccuracy = location.mapFlutterAccuracy.get(call.argument("accuracy")); + final Long updateIntervalMilliseconds = new Long((int) call.argument("interval")); + final Long fastestUpdateIntervalMilliseconds = updateIntervalMilliseconds / 2; + final Float distanceFilter = new Float((double) call.argument("distanceFilter")); + + location.changeSettings(locationAccuracy, updateIntervalMilliseconds, fastestUpdateIntervalMilliseconds, + distanceFilter); + + result.success(1); + } catch (Exception e) { + result.error("CHANGE_SETTINGS_ERROR", + "An unexcepted error happened during location settings change:" + e.getMessage(), null); + } + } + + private void onGetLocation(Result result) { + location.getLocationResult = result; + if (!location.checkPermissions()) { + location.requestPermissions(); + } else { + location.startRequestingLocation(); + } + } + + private void onHasPermission(Result result) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + result.success(1); + return; + } + + if (location.checkPermissions()) { + result.success(1); + } else { + result.success(0); + } + } + + private void onRequestPermission(Result result) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + result.success(1); + return; + } + + location.result = result; + location.requestPermissions(); + } + +} diff --git a/local_plugin/location-3.0.2/android/src/main/java/com/lyokone/location/StreamHandlerImpl.java b/local_plugin/location-3.0.2/android/src/main/java/com/lyokone/location/StreamHandlerImpl.java new file mode 100644 index 0000000..4467d53 --- /dev/null +++ b/local_plugin/location-3.0.2/android/src/main/java/com/lyokone/location/StreamHandlerImpl.java @@ -0,0 +1,69 @@ +package com.lyokone.location; + +import android.util.Log; +import io.flutter.plugin.common.BinaryMessenger; +import io.flutter.plugin.common.EventChannel; +import io.flutter.plugin.common.EventChannel.StreamHandler; +import io.flutter.plugin.common.EventChannel.EventSink; + +class StreamHandlerImpl implements StreamHandler { + private static final String TAG = "StreamHandlerImpl"; + + private final FlutterLocation location; + private EventChannel channel; + + private static final String STREAM_CHANNEL_NAME = "lyokone/locationstream"; + + StreamHandlerImpl(FlutterLocation location) { + this.location = location; + } + + /** + * Registers this instance as a stream events handler on the given + * {@code messenger}. + */ + void startListening(BinaryMessenger messenger) { + if (channel != null) { + Log.wtf(TAG, "Setting a method call handler before the last was disposed."); + stopListening(); + } + + channel = new EventChannel(messenger, STREAM_CHANNEL_NAME); + channel.setStreamHandler(this); + } + + /** + * Clears this instance from listening to stream events. + */ + void stopListening() { + if (channel == null) { + Log.d(TAG, "Tried to stop listening when no MethodChannel had been initialized."); + return; + } + + channel.setStreamHandler(null); + channel = null; + } + + @Override + public void onListen(Object arguments, final EventSink eventsSink) { + location.events = eventsSink; + if (location.activity == null) { + eventsSink.error("NO_ACTIVITY", null, null); + return; + } + + if (!location.checkPermissions()) { + location.requestPermissions(); + return; + } + location.startRequestingLocation(); + } + + @Override + public void onCancel(Object arguments) { + location.mFusedLocationClient.removeLocationUpdates(location.mLocationCallback); + location.events = null; + } + +} diff --git a/local_plugin/location-3.0.2/darwin/Classes/LocationPlugin.h b/local_plugin/location-3.0.2/darwin/Classes/LocationPlugin.h new file mode 100644 index 0000000..42cb7eb --- /dev/null +++ b/local_plugin/location-3.0.2/darwin/Classes/LocationPlugin.h @@ -0,0 +1,4 @@ +#import + +@interface LocationPlugin : NSObject +@end diff --git a/local_plugin/location-3.0.2/darwin/Classes/LocationPlugin.m b/local_plugin/location-3.0.2/darwin/Classes/LocationPlugin.m new file mode 100644 index 0000000..6ae7ca8 --- /dev/null +++ b/local_plugin/location-3.0.2/darwin/Classes/LocationPlugin.m @@ -0,0 +1,321 @@ +#import "LocationPlugin.h" + +#ifdef COCOAPODS +@import CoreLocation; +#else +#import +#endif + +@interface LocationPlugin() +@property (strong, nonatomic) CLLocationManager *clLocationManager; +@property (copy, nonatomic) FlutterResult flutterResult; +@property (assign, nonatomic) BOOL locationWanted; +@property (assign, nonatomic) BOOL permissionWanted; + +@property (copy, nonatomic) FlutterEventSink flutterEventSink; +@property (assign, nonatomic) BOOL flutterListening; +@property (assign, nonatomic) BOOL hasInit; +@end + +@implementation LocationPlugin + ++(void)registerWithRegistrar:(NSObject*)registrar { + FlutterMethodChannel *channel = + [FlutterMethodChannel methodChannelWithName:@"lyokone/location" + binaryMessenger:registrar.messenger]; + FlutterEventChannel *stream = + [FlutterEventChannel eventChannelWithName:@"lyokone/locationstream" + binaryMessenger:registrar.messenger]; + + LocationPlugin *instance = [[LocationPlugin alloc] init]; + [registrar addMethodCallDelegate:instance channel:channel]; + [stream setStreamHandler:instance]; +} + +-(instancetype)init { + self = [super init]; + + if (self) { + self.locationWanted = NO; + self.permissionWanted = NO; + self.flutterListening = NO; + self.hasInit = NO; + } + return self; +} + +-(void)initLocation { + if (!(self.hasInit)) { + self.hasInit = YES; + + if ([CLLocationManager locationServicesEnabled]) { + self.clLocationManager = [[CLLocationManager alloc] init]; + self.clLocationManager.delegate = self; + self.clLocationManager.desiredAccuracy = kCLLocationAccuracyBest; + } + } +} + +-(void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { + [self initLocation]; + if ([call.method isEqualToString:@"changeSettings"]) { + if ([CLLocationManager locationServicesEnabled]) { + NSDictionary *dictionary = @{ + @"0" : @(kCLLocationAccuracyKilometer), + @"1" : @(kCLLocationAccuracyHundredMeters), + @"2" : @(kCLLocationAccuracyNearestTenMeters), + @"3" : @(kCLLocationAccuracyBest), + @"4" : @(kCLLocationAccuracyBestForNavigation) + }; + + self.clLocationManager.desiredAccuracy = + [dictionary[call.arguments[@"accuracy"]] doubleValue]; + double distanceFilter = [call.arguments[@"distanceFilter"] doubleValue]; + if (distanceFilter == 0){ + distanceFilter = kCLDistanceFilterNone; + } + self.clLocationManager.distanceFilter = distanceFilter; + result(@1); + } + } else if ([call.method isEqualToString:@"getLocation"]) { + if (![CLLocationManager locationServicesEnabled]) { + result([FlutterError errorWithCode:@"SERVICE_STATUS_DISABLED" message:@"Failed to get location. Location services disabled" details:nil]); + return; + } + if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) { + // Location services are requested but user has denied + NSString *message = @"The user explicitly denied the use of location services for this " + "app or location services are currently disabled in Settings."; + result([FlutterError errorWithCode:@"PERMISSION_DENIED" + message:message + details:nil]); + return; + } + + self.flutterResult = result; + self.locationWanted = YES; + + if ([self isPermissionGranted]) { + [self.clLocationManager startUpdatingLocation]; + } else { + [self requestPermission]; + if ([self isPermissionGranted]) { + [self.clLocationManager startUpdatingLocation]; + } + } + } else if ([call.method isEqualToString:@"hasPermission"]) { + if ([self isPermissionGranted]) { + result(@1); + } else { + result(@0); + } + } else if ([call.method isEqualToString:@"requestPermission"]) { + if ([self isPermissionGranted]) { + result(@1); + } else if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) { + self.flutterResult = result; + self.permissionWanted = YES; + [self requestPermission]; + } else { + result(@2); + } + } else if ([call.method isEqualToString:@"serviceEnabled"]) { + if ([CLLocationManager locationServicesEnabled]) { + result(@1); + } else { + result(@0); + } + } else if ([call.method isEqualToString:@"requestService"]) { + if ([CLLocationManager locationServicesEnabled]) { + result(@1); + } else { +#if TARGET_OS_OSX + NSAlert *alert = [[NSAlert alloc] init]; + [alert setMessageText:@"Location is Disabled"]; + [alert setInformativeText:@"To use location, go to your System Preferences > Security & Privacy > Privacy > Location Services."]; + [alert addButtonWithTitle:@"Open"]; + [alert addButtonWithTitle:@"Cancel"]; + [alert beginSheetModalForWindow:NSApplication.sharedApplication.mainWindow + completionHandler:^(NSModalResponse returnCode) { + if (returnCode == NSAlertFirstButtonReturn) { + NSString *urlString = @"x-apple.systempreferences:com.apple.preference.security?Privacy_LocationServices"; + [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:urlString]]; + } else { + NSLog(@"Cancel"); + } + }]; +#else + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Location is Disabled" + message:@"To use location, go to your Settings App > Privacy > Location Services." + delegate:self + cancelButtonTitle:@"Cancel" + otherButtonTitles:nil]; + [alert show]; +#endif + result(@0); + } + } else { + result(FlutterMethodNotImplemented); + } +} + + +-(void) requestPermission { +#if TARGET_OS_OSX + if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"] != nil) { + if (@available(macOS 10.15, *)) { + [self.clLocationManager requestAlwaysAuthorization]; + } + } +#else + if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"] != nil) { + [self.clLocationManager requestWhenInUseAuthorization]; + } + else if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"] != nil) { + [self.clLocationManager requestAlwaysAuthorization]; + } +#endif + else { + [NSException raise:NSInternalInconsistencyException format: + @"To use location in iOS8 and above you need to define either " + "NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription in the app " + "bundle's Info.plist file"]; + } +} + +-(BOOL) isPermissionGranted { + BOOL isPermissionGranted = NO; + CLAuthorizationStatus status = [CLLocationManager authorizationStatus]; + +#if TARGET_OS_OSX + if (status == kCLAuthorizationStatusAuthorized) { + // Location services are available + isPermissionGranted = YES; + } else if (@available(macOS 10.12, *)) { + if (status == kCLAuthorizationStatusAuthorizedAlways) { + // Location services are available + isPermissionGranted = YES; + } + } +#else //if TARGET_OS_IOS + if (status == kCLAuthorizationStatusAuthorizedWhenInUse || + status == kCLAuthorizationStatusAuthorizedAlways) { + // Location services are available + isPermissionGranted = YES; + } +#endif + else if (status == kCLAuthorizationStatusDenied || + status == kCLAuthorizationStatusRestricted) { + // Location services are requested but user has denied / the app is restricted from + // getting location + isPermissionGranted = NO; + } else if (status == kCLAuthorizationStatusNotDetermined) { + // Location services never requested / the user still haven't decide + isPermissionGranted = NO; + } else { + isPermissionGranted = NO; + } + + return isPermissionGranted; +} + +-(FlutterError*)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events { + self.flutterEventSink = events; + self.flutterListening = YES; + + if ([self isPermissionGranted]) { + [self.clLocationManager startUpdatingLocation]; + } else { + [self requestPermission]; + } + + return nil; +} + +-(FlutterError*)onCancelWithArguments:(id)arguments { + self.flutterListening = NO; + [self.clLocationManager stopUpdatingLocation]; + return nil; +} + +#pragma mark - CLLocationManagerDelegate Methods + +-(void)locationManager:(CLLocationManager*)manager + didUpdateLocations:(NSArray*)locations { + CLLocation *location = locations.firstObject; + NSTimeInterval timeInSeconds = [location.timestamp timeIntervalSince1970]; + NSDictionary* coordinatesDict = + @{ + @"latitude": @(location.coordinate.latitude), + @"longitude": @(location.coordinate.longitude), + @"accuracy": @(location.horizontalAccuracy), + @"altitude": @(location.altitude), + @"speed": @(location.speed), + @"speed_accuracy": @0.0, + @"heading": @(location.course), + @"time": @(((double) timeInSeconds) * 1000.0) // in milliseconds since the epoch + }; + + if (self.locationWanted) { + self.locationWanted = NO; + self.flutterResult(coordinatesDict); + } + if (self.flutterListening) { + self.flutterEventSink(coordinatesDict); + } else { + [self.clLocationManager stopUpdatingLocation]; + } +} + +- (void)locationManager:(CLLocationManager *)manager + didChangeAuthorizationStatus:(CLAuthorizationStatus)status { + if (status == kCLAuthorizationStatusDenied) { + // The user denied authorization + NSLog(@"User denied permissions"); + if (self.permissionWanted) { + self.permissionWanted = NO; + self.flutterResult(@0); + } + } +#if TARGET_OS_OSX + else if (status == kCLAuthorizationStatusAuthorized) { + NSLog(@"User granted permissions"); + if (self.permissionWanted) { + self.permissionWanted = NO; + self.flutterResult(@1); + } + + if (self.locationWanted || self.flutterListening) { + [self.clLocationManager startUpdatingLocation]; + } + } else if (@available(macOS 10.12, *)) { + if (status == kCLAuthorizationStatusAuthorizedAlways) { + NSLog(@"User granted permissions"); + if (self.permissionWanted) { + self.permissionWanted = NO; + self.flutterResult(@1); + } + + if (self.locationWanted || self.flutterListening) { + [self.clLocationManager startUpdatingLocation]; + } + } + } +#else //if TARGET_OS_IOS + else if (status == kCLAuthorizationStatusAuthorizedWhenInUse || + status == kCLAuthorizationStatusAuthorizedAlways) { + NSLog(@"User granted permissions"); + if (self.permissionWanted) { + self.permissionWanted = NO; + self.flutterResult(@1); + } + + if (self.locationWanted || self.flutterListening) { + [self.clLocationManager startUpdatingLocation]; + } + } +#endif +} + + +@end diff --git a/local_plugin/location-3.0.2/example/.gitignore b/local_plugin/location-3.0.2/example/.gitignore new file mode 100644 index 0000000..1ba9c33 --- /dev/null +++ b/local_plugin/location-3.0.2/example/.gitignore @@ -0,0 +1,43 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Exceptions to above rules. +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/local_plugin/location-3.0.2/example/.metadata b/local_plugin/location-3.0.2/example/.metadata new file mode 100644 index 0000000..01d2dcb --- /dev/null +++ b/local_plugin/location-3.0.2/example/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 0b8abb4724aa590dd0f429683339b1e045a1594d + channel: stable + +project_type: app diff --git a/local_plugin/location-3.0.2/example/README.md b/local_plugin/location-3.0.2/example/README.md new file mode 100644 index 0000000..0c452d1 --- /dev/null +++ b/local_plugin/location-3.0.2/example/README.md @@ -0,0 +1,16 @@ +# location_example + +Demonstrates how to use the location plugin. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/local_plugin/location-3.0.2/example/android/.gitignore b/local_plugin/location-3.0.2/example/android/.gitignore new file mode 100644 index 0000000..bc2100d --- /dev/null +++ b/local_plugin/location-3.0.2/example/android/.gitignore @@ -0,0 +1,7 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java diff --git a/local_plugin/location-3.0.2/example/android/app/build.gradle b/local_plugin/location-3.0.2/example/android/app/build.gradle new file mode 100644 index 0000000..4bc81ab --- /dev/null +++ b/local_plugin/location-3.0.2/example/android/app/build.gradle @@ -0,0 +1,60 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + applicationId "com.lyokone.locationexample" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' +} diff --git a/local_plugin/location-3.0.2/example/android/app/src/androidTest/java/com/lyokone/locationexample/EmbedderV1ActivityTest.java b/local_plugin/location-3.0.2/example/android/app/src/androidTest/java/com/lyokone/locationexample/EmbedderV1ActivityTest.java new file mode 100644 index 0000000..5e50690 --- /dev/null +++ b/local_plugin/location-3.0.2/example/android/app/src/androidTest/java/com/lyokone/locationexample/EmbedderV1ActivityTest.java @@ -0,0 +1,12 @@ +package com.lyokone.locationexample; + +import androidx.test.rule.ActivityTestRule; +import dev.flutter.plugins.e2e.FlutterRunner; +import org.junit.Rule; +import org.junit.runner.RunWith; + +@RunWith(FlutterRunner.class) +public class EmbedderV1ActivityTest { + @Rule + public ActivityTestRule rule = new ActivityTestRule<>(EmbedderV1Activity.class); +} diff --git a/local_plugin/location-3.0.2/example/android/app/src/androidTest/java/com/lyokone/locationexample/FlutterActivityTest.java b/local_plugin/location-3.0.2/example/android/app/src/androidTest/java/com/lyokone/locationexample/FlutterActivityTest.java new file mode 100644 index 0000000..7096d93 --- /dev/null +++ b/local_plugin/location-3.0.2/example/android/app/src/androidTest/java/com/lyokone/locationexample/FlutterActivityTest.java @@ -0,0 +1,13 @@ +package com.lyokone.locationexample; + +import androidx.test.rule.ActivityTestRule; +import dev.flutter.plugins.e2e.FlutterRunner; +import io.flutter.embedding.android.FlutterActivity; +import org.junit.Rule; +import org.junit.runner.RunWith; + +@RunWith(FlutterRunner.class) +public class FlutterActivityTest { + @Rule + public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); +} diff --git a/local_plugin/location-3.0.2/example/android/app/src/debug/AndroidManifest.xml b/local_plugin/location-3.0.2/example/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..9895bb2 --- /dev/null +++ b/local_plugin/location-3.0.2/example/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/local_plugin/location-3.0.2/example/android/app/src/main/AndroidManifest.xml b/local_plugin/location-3.0.2/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..4f4ab61 --- /dev/null +++ b/local_plugin/location-3.0.2/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + diff --git a/local_plugin/location-3.0.2/example/android/app/src/main/java/com/lyokone/locationexample/EmbedderV1Activity.java b/local_plugin/location-3.0.2/example/android/app/src/main/java/com/lyokone/locationexample/EmbedderV1Activity.java new file mode 100644 index 0000000..362c106 --- /dev/null +++ b/local_plugin/location-3.0.2/example/android/app/src/main/java/com/lyokone/locationexample/EmbedderV1Activity.java @@ -0,0 +1,15 @@ +package com.lyokone.locationexample; + +import android.os.Bundle; +import dev.flutter.plugins.e2e.E2EPlugin; +import io.flutter.app.FlutterActivity; +import com.lyokone.location.LocationPlugin; + +public class EmbedderV1Activity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + LocationPlugin.registerWith(registrarFor("com.lyokone.location.LocationPlugin")); + E2EPlugin.registerWith(registrarFor("dev.flutter.plugins.e2e.E2EPlugin")); + } +} diff --git a/local_plugin/location-3.0.2/example/android/app/src/main/res/drawable/launch_background.xml b/local_plugin/location-3.0.2/example/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/local_plugin/location-3.0.2/example/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/local_plugin/location-3.0.2/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/local_plugin/location-3.0.2/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..db77bb4 Binary files /dev/null and b/local_plugin/location-3.0.2/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/local_plugin/location-3.0.2/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/local_plugin/location-3.0.2/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 Binary files /dev/null and b/local_plugin/location-3.0.2/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/local_plugin/location-3.0.2/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/local_plugin/location-3.0.2/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 Binary files /dev/null and b/local_plugin/location-3.0.2/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/local_plugin/location-3.0.2/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/local_plugin/location-3.0.2/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d Binary files /dev/null and b/local_plugin/location-3.0.2/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/local_plugin/location-3.0.2/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/local_plugin/location-3.0.2/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e Binary files /dev/null and b/local_plugin/location-3.0.2/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/local_plugin/location-3.0.2/example/android/app/src/main/res/values/styles.xml b/local_plugin/location-3.0.2/example/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..00fa441 --- /dev/null +++ b/local_plugin/location-3.0.2/example/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/local_plugin/location-3.0.2/example/android/app/src/profile/AndroidManifest.xml b/local_plugin/location-3.0.2/example/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..9895bb2 --- /dev/null +++ b/local_plugin/location-3.0.2/example/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/local_plugin/location-3.0.2/example/android/build.gradle b/local_plugin/location-3.0.2/example/android/build.gradle new file mode 100644 index 0000000..e0d7ae2 --- /dev/null +++ b/local_plugin/location-3.0.2/example/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.5.0' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/local_plugin/location-3.0.2/example/android/gradle.properties b/local_plugin/location-3.0.2/example/android/gradle.properties new file mode 100644 index 0000000..38c8d45 --- /dev/null +++ b/local_plugin/location-3.0.2/example/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx1536M +android.enableR8=true +android.useAndroidX=true +android.enableJetifier=true diff --git a/local_plugin/location-3.0.2/example/android/gradle/wrapper/gradle-wrapper.properties b/local_plugin/location-3.0.2/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..296b146 --- /dev/null +++ b/local_plugin/location-3.0.2/example/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip diff --git a/local_plugin/location-3.0.2/example/android/settings.gradle b/local_plugin/location-3.0.2/example/android/settings.gradle new file mode 100644 index 0000000..5a2f14f --- /dev/null +++ b/local_plugin/location-3.0.2/example/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/local_plugin/location-3.0.2/example/ios/.gitignore b/local_plugin/location-3.0.2/example/ios/.gitignore new file mode 100644 index 0000000..e96ef60 --- /dev/null +++ b/local_plugin/location-3.0.2/example/ios/.gitignore @@ -0,0 +1,32 @@ +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/local_plugin/location-3.0.2/example/ios/Flutter/AppFrameworkInfo.plist b/local_plugin/location-3.0.2/example/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..6b4c0f7 --- /dev/null +++ b/local_plugin/location-3.0.2/example/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/local_plugin/location-3.0.2/example/ios/Flutter/Debug.xcconfig b/local_plugin/location-3.0.2/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..e8efba1 --- /dev/null +++ b/local_plugin/location-3.0.2/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/local_plugin/location-3.0.2/example/ios/Flutter/Release.xcconfig b/local_plugin/location-3.0.2/example/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..399e934 --- /dev/null +++ b/local_plugin/location-3.0.2/example/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/local_plugin/location-3.0.2/example/ios/Runner.xcodeproj/project.pbxproj b/local_plugin/location-3.0.2/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..bc72e0f --- /dev/null +++ b/local_plugin/location-3.0.2/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,571 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + DD112F2E4CE857F9EAC8D7C0 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7407592F4879066EE06C4B6F /* Pods_Runner.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3FBE85D93EBCD2C647CC5C16 /* 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 = ""; }; + 525F09DDB3B227C2EB11FBA0 /* 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 = ""; }; + 7407592F4879066EE06C4B6F /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + FEA6CE46ED74487826D4931D /* 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 = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DD112F2E4CE857F9EAC8D7C0 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 09889A7DB8497209299B2D08 /* Pods */ = { + isa = PBXGroup; + children = ( + FEA6CE46ED74487826D4931D /* Pods-Runner.debug.xcconfig */, + 525F09DDB3B227C2EB11FBA0 /* Pods-Runner.release.xcconfig */, + 3FBE85D93EBCD2C647CC5C16 /* Pods-Runner.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + 51D5215045614C3EC62B9174 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 7407592F4879066EE06C4B6F /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 09889A7DB8497209299B2D08 /* Pods */, + 51D5215045614C3EC62B9174 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 728928C3FAAC2B1379F26C61 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 820D6D96D117B3695A942791 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin\n"; + }; + 728928C3FAAC2B1379F26C61 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + 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"; + showEnvVarsInLog = 0; + }; + 820D6D96D117B3695A942791 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.lyokone.location_example; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.lyokone.location_example; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.lyokone.location_example; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/local_plugin/location-3.0.2/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/local_plugin/location-3.0.2/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..fb2dffc --- /dev/null +++ b/local_plugin/location-3.0.2/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/local_plugin/location-3.0.2/example/ios/Runner/AppDelegate.swift b/local_plugin/location-3.0.2/example/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..70693e4 --- /dev/null +++ b/local_plugin/location-3.0.2/example/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..dc9ada4 Binary files /dev/null and b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..28c6bf0 Binary files /dev/null and b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..2ccbfd9 Binary files /dev/null and b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..f091b6b Binary files /dev/null and b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..4cde121 Binary files /dev/null and b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..d0ef06e Binary files /dev/null and b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..dcdc230 Binary files /dev/null and b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..2ccbfd9 Binary files /dev/null and b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..c8f9ed8 Binary files /dev/null and b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..a6d6b86 Binary files /dev/null and b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..a6d6b86 Binary files /dev/null and b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..75b2d16 Binary files /dev/null and b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..c4df70d Binary files /dev/null and b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..6a84f41 Binary files /dev/null and b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..d0e1f58 Binary files /dev/null and b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/local_plugin/location-3.0.2/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +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. \ No newline at end of file diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/local_plugin/location-3.0.2/example/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/local_plugin/location-3.0.2/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Base.lproj/Main.storyboard b/local_plugin/location-3.0.2/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/local_plugin/location-3.0.2/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Info.plist b/local_plugin/location-3.0.2/example/ios/Runner/Info.plist new file mode 100644 index 0000000..331a83f --- /dev/null +++ b/local_plugin/location-3.0.2/example/ios/Runner/Info.plist @@ -0,0 +1,49 @@ + + + + + NSLocationAlwaysUsageDescription + I need it + NSLocationWhenInUseUsageDescription + Because + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + location_example + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/local_plugin/location-3.0.2/example/ios/Runner/Runner-Bridging-Header.h b/local_plugin/location-3.0.2/example/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..7335fdf --- /dev/null +++ b/local_plugin/location-3.0.2/example/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" \ No newline at end of file diff --git a/local_plugin/location-3.0.2/example/lib/get_location.dart b/local_plugin/location-3.0.2/example/lib/get_location.dart new file mode 100644 index 0000000..ff30447 --- /dev/null +++ b/local_plugin/location-3.0.2/example/lib/get_location.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:location/location.dart'; + +class GetLocationWidget extends StatefulWidget { + const GetLocationWidget({Key key}) : super(key: key); + + @override + _GetLocationState createState() => _GetLocationState(); +} + +class _GetLocationState extends State { + final Location location = Location(); + + LocationData _location; + String _error; + + Future _getLocation() async { + setState(() { + _error = null; + }); + try { + final LocationData _locationResult = await location.getLocation(); + setState(() { + _location = _locationResult; + }); + } on PlatformException catch (err) { + setState(() { + _error = err.code; + }); + } + } + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Location: ' + (_error ?? '${_location ?? "unknown"}'), + style: Theme.of(context).textTheme.body2, + ), + Row( + children: [ + RaisedButton( + child: const Text('Get'), + onPressed: _getLocation, + ) + ], + ), + ], + ); + } +} diff --git a/local_plugin/location-3.0.2/example/lib/listen_location.dart b/local_plugin/location-3.0.2/example/lib/listen_location.dart new file mode 100644 index 0000000..7230600 --- /dev/null +++ b/local_plugin/location-3.0.2/example/lib/listen_location.dart @@ -0,0 +1,67 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:location/location.dart'; + +class ListenLocationWidget extends StatefulWidget { + const ListenLocationWidget({Key key}) : super(key: key); + + @override + _ListenLocationState createState() => _ListenLocationState(); +} + +class _ListenLocationState extends State { + final Location location = Location(); + + LocationData _location; + StreamSubscription _locationSubscription; + String _error; + + Future _listenLocation() async { + _locationSubscription = + location.onLocationChanged.handleError((dynamic err) { + setState(() { + _error = err.code; + }); + _locationSubscription.cancel(); + }).listen((LocationData currentLocation) { + setState(() { + _error = null; + + _location = currentLocation; + }); + }); + } + + Future _stopListen() async { + _locationSubscription.cancel(); + } + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Listen location: ' + (_error ?? '${_location ?? "unknown"}'), + style: Theme.of(context).textTheme.body2, + ), + Row( + children: [ + Container( + margin: const EdgeInsets.only(right: 42), + child: RaisedButton( + child: const Text('Listen'), + onPressed: _listenLocation, + ), + ), + RaisedButton( + child: const Text('Stop'), + onPressed: _stopListen, + ) + ], + ), + ], + ); + } +} diff --git a/local_plugin/location-3.0.2/example/lib/main.dart b/local_plugin/location-3.0.2/example/lib/main.dart new file mode 100644 index 0000000..e0aa97f --- /dev/null +++ b/local_plugin/location-3.0.2/example/lib/main.dart @@ -0,0 +1,101 @@ +import 'package:flutter/material.dart'; +import 'package:location/location.dart'; +import 'package:url_launcher/url_launcher.dart'; + +import 'get_location.dart'; +import 'listen_location.dart'; +import 'permission_status.dart'; +import 'service_enabled.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Location', + theme: ThemeData( + primarySwatch: Colors.amber, + ), + home: const MyHomePage(title: 'Flutter Location Demo'), + ); + } +} + +class MyHomePage extends StatefulWidget { + const MyHomePage({Key key, this.title}) : super(key: key); + final String title; + + @override + _MyHomePageState createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + final Location location = Location(); + + Future _showInfoDialog() { + return showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Demo Application'), + content: SingleChildScrollView( + child: ListBody( + children: [ + const Text('Created by Guillaume Bernos'), + InkWell( + child: Text( + 'https://github.com/Lyokone/flutterlocation', + style: TextStyle( + decoration: TextDecoration.underline, + ), + ), + onTap: () => + launch('https://github.com/Lyokone/flutterlocation'), + ), + ], + ), + ), + actions: [ + FlatButton( + child: const Text('Ok'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.title), + actions: [ + IconButton( + icon: Icon(Icons.info_outline), + onPressed: _showInfoDialog, + ) + ], + ), + body: Container( + padding: const EdgeInsets.all(32), + child: Column( + children: const [ + PermissionStatusWidget(), + Divider(height: 32), + ServiceEnabledWidget(), + Divider(height: 32), + GetLocationWidget(), + Divider(height: 32), + ListenLocationWidget() + ], + ), + ), + ); + } +} diff --git a/local_plugin/location-3.0.2/example/lib/permission_status.dart b/local_plugin/location-3.0.2/example/lib/permission_status.dart new file mode 100644 index 0000000..3723b2b --- /dev/null +++ b/local_plugin/location-3.0.2/example/lib/permission_status.dart @@ -0,0 +1,66 @@ +import 'package:flutter/material.dart'; +import 'package:location/location.dart'; + +class PermissionStatusWidget extends StatefulWidget { + const PermissionStatusWidget({Key key}) : super(key: key); + + @override + _PermissionStatusState createState() => _PermissionStatusState(); +} + +class _PermissionStatusState extends State { + final Location location = Location(); + + PermissionStatus _permissionGranted; + + Future _checkPermissions() async { + final PermissionStatus permissionGrantedResult = + await location.hasPermission(); + setState(() { + _permissionGranted = permissionGrantedResult; + }); + } + + Future _requestPermission() async { + if (_permissionGranted != PermissionStatus.granted) { + final PermissionStatus permissionRequestedResult = + await location.requestPermission(); + setState(() { + _permissionGranted = permissionRequestedResult; + }); + if (permissionRequestedResult != PermissionStatus.granted) { + return; + } + } + } + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Permission status: ${_permissionGranted ?? "unknown"}', + style: Theme.of(context).textTheme.body2, + ), + Row( + children: [ + Container( + margin: const EdgeInsets.only(right: 42), + child: RaisedButton( + child: const Text('Check'), + onPressed: _checkPermissions, + ), + ), + RaisedButton( + child: const Text('Request'), + onPressed: _permissionGranted == PermissionStatus.granted + ? null + : _requestPermission, + ) + ], + ) + ], + ); + } +} diff --git a/local_plugin/location-3.0.2/example/lib/service_enabled.dart b/local_plugin/location-3.0.2/example/lib/service_enabled.dart new file mode 100644 index 0000000..678460b --- /dev/null +++ b/local_plugin/location-3.0.2/example/lib/service_enabled.dart @@ -0,0 +1,60 @@ +import 'package:flutter/material.dart'; +import 'package:location/location.dart'; + +class ServiceEnabledWidget extends StatefulWidget { + const ServiceEnabledWidget({Key key}) : super(key: key); + + @override + _ServiceEnabledState createState() => _ServiceEnabledState(); +} + +class _ServiceEnabledState extends State { + final Location location = Location(); + + bool _serviceEnabled; + + Future _checkService() async { + final bool serviceEnabledResult = await location.serviceEnabled(); + setState(() { + _serviceEnabled = serviceEnabledResult; + }); + } + + Future _requestService() async { + if (_serviceEnabled == null || !_serviceEnabled) { + final bool serviceRequestedResult = await location.requestService(); + setState(() { + _serviceEnabled = serviceRequestedResult; + }); + if (!serviceRequestedResult) { + return; + } + } + } + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Service enabled: ${_serviceEnabled ?? "unknown"}', + style: Theme.of(context).textTheme.body2), + Row( + children: [ + Container( + margin: const EdgeInsets.only(right: 42), + child: RaisedButton( + child: const Text('Check'), + onPressed: _checkService, + ), + ), + RaisedButton( + child: const Text('Request'), + onPressed: _serviceEnabled == true ? null : _requestService, + ) + ], + ) + ], + ); + } +} diff --git a/local_plugin/location-3.0.2/example/macos/.gitignore b/local_plugin/location-3.0.2/example/macos/.gitignore new file mode 100644 index 0000000..d2fd377 --- /dev/null +++ b/local_plugin/location-3.0.2/example/macos/.gitignore @@ -0,0 +1,6 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/xcuserdata/ diff --git a/local_plugin/location-3.0.2/example/macos/Flutter/Flutter-Debug.xcconfig b/local_plugin/location-3.0.2/example/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 0000000..785633d --- /dev/null +++ b/local_plugin/location-3.0.2/example/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/local_plugin/location-3.0.2/example/macos/Flutter/Flutter-Release.xcconfig b/local_plugin/location-3.0.2/example/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 0000000..5fba960 --- /dev/null +++ b/local_plugin/location-3.0.2/example/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/local_plugin/location-3.0.2/example/macos/Flutter/GeneratedPluginRegistrant.swift b/local_plugin/location-3.0.2/example/macos/Flutter/GeneratedPluginRegistrant.swift new file mode 100644 index 0000000..d151654 --- /dev/null +++ b/local_plugin/location-3.0.2/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -0,0 +1,14 @@ +// +// Generated file. Do not edit. +// + +import FlutterMacOS +import Foundation + +import location +import url_launcher_macos + +func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + LocationPlugin.register(with: registry.registrar(forPlugin: "LocationPlugin")) + UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) +} diff --git a/local_plugin/location-3.0.2/example/macos/Runner.xcodeproj/project.pbxproj b/local_plugin/location-3.0.2/example/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..6dd4fc8 --- /dev/null +++ b/local_plugin/location-3.0.2/example/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,654 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; }; + 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 4FB8C74EE0088E7128613769 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC7B042DEA397098CB37A9C3 /* Pods_Runner.framework */; }; + D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; }; + D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */, + 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */, + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 02248394EE7A7894B28455D5 /* 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 = ""; }; + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* location_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = location_example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 886143E057BF0B12C17B4AF1 /* 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 = ""; }; + 8E274D018AB43327BF074F7F /* 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 = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + BC7B042DEA397098CB37A9C3 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D73912F022F37F9E000D13A0 /* App.framework in Frameworks */, + 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */, + 4FB8C74EE0088E7128613769 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 290C5E9AF56BE501A7F19E71 /* Pods */ = { + isa = PBXGroup; + children = ( + 886143E057BF0B12C17B4AF1 /* Pods-Runner.debug.xcconfig */, + 02248394EE7A7894B28455D5 /* Pods-Runner.release.xcconfig */, + 8E274D018AB43327BF074F7F /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + 290C5E9AF56BE501A7F19E71 /* Pods */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* location_example.app */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + D73912EF22F37F9E000D13A0 /* App.framework */, + 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + BC7B042DEA397098CB37A9C3 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + F031A4248658C5B8E1F56F23 /* [CP] Check Pods Manifest.lock */, + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + 53011F24DAEC196906F70E4A /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* location_example.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = "The Flutter Authors"; + TargetAttributes = { + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh\ntouch Flutter/ephemeral/tripwire\n"; + }; + 53011F24DAEC196906F70E4A /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + F031A4248658C5B8E1F56F23 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + 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"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter/ephemeral", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter/ephemeral", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter/ephemeral", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/local_plugin/location-3.0.2/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/local_plugin/location-3.0.2/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..75a2c33 --- /dev/null +++ b/local_plugin/location-3.0.2/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/local_plugin/location-3.0.2/example/macos/Runner/AppDelegate.swift b/local_plugin/location-3.0.2/example/macos/Runner/AppDelegate.swift new file mode 100644 index 0000000..d53ef64 --- /dev/null +++ b/local_plugin/location-3.0.2/example/macos/Runner/AppDelegate.swift @@ -0,0 +1,9 @@ +import Cocoa +import FlutterMacOS + +@NSApplicationMain +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } +} diff --git a/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..a2ec33f --- /dev/null +++ b/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 0000000..3c4935a Binary files /dev/null and b/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 0000000..ed4cc16 Binary files /dev/null and b/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 0000000..483be61 Binary files /dev/null and b/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 0000000..bcbf36d Binary files /dev/null and b/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 0000000..9c0a652 Binary files /dev/null and b/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 0000000..e71a726 Binary files /dev/null and b/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 0000000..8a31fe2 Binary files /dev/null and b/local_plugin/location-3.0.2/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/local_plugin/location-3.0.2/example/macos/Runner/Base.lproj/MainMenu.xib b/local_plugin/location-3.0.2/example/macos/Runner/Base.lproj/MainMenu.xib new file mode 100644 index 0000000..537341a --- /dev/null +++ b/local_plugin/location-3.0.2/example/macos/Runner/Base.lproj/MainMenu.xib @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/local_plugin/location-3.0.2/example/macos/Runner/Configs/AppInfo.xcconfig b/local_plugin/location-3.0.2/example/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 0000000..99943a9 --- /dev/null +++ b/local_plugin/location-3.0.2/example/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = location_example + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = com.lyokone.location.testLocation + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2020 com.lyokone.location. All rights reserved. diff --git a/local_plugin/location-3.0.2/example/macos/Runner/Configs/Debug.xcconfig b/local_plugin/location-3.0.2/example/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 0000000..36b0fd9 --- /dev/null +++ b/local_plugin/location-3.0.2/example/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/local_plugin/location-3.0.2/example/macos/Runner/Configs/Release.xcconfig b/local_plugin/location-3.0.2/example/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 0000000..dff4f49 --- /dev/null +++ b/local_plugin/location-3.0.2/example/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/local_plugin/location-3.0.2/example/macos/Runner/Configs/Warnings.xcconfig b/local_plugin/location-3.0.2/example/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 0000000..42bcbf4 --- /dev/null +++ b/local_plugin/location-3.0.2/example/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/local_plugin/location-3.0.2/example/macos/Runner/DebugProfile.entitlements b/local_plugin/location-3.0.2/example/macos/Runner/DebugProfile.entitlements new file mode 100644 index 0000000..308e7d2 --- /dev/null +++ b/local_plugin/location-3.0.2/example/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + com.apple.security.personal-information.location + + + diff --git a/local_plugin/location-3.0.2/example/macos/Runner/Info.plist b/local_plugin/location-3.0.2/example/macos/Runner/Info.plist new file mode 100644 index 0000000..3e7b52b --- /dev/null +++ b/local_plugin/location-3.0.2/example/macos/Runner/Info.plist @@ -0,0 +1,36 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + NSLocationAlwaysUsageDescription + I need it + NSLocationWhenInUseUsageDescription + Because + + diff --git a/local_plugin/location-3.0.2/example/macos/Runner/MainFlutterWindow.swift b/local_plugin/location-3.0.2/example/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 0000000..2722837 --- /dev/null +++ b/local_plugin/location-3.0.2/example/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController.init() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/local_plugin/location-3.0.2/example/macos/Runner/Release.entitlements b/local_plugin/location-3.0.2/example/macos/Runner/Release.entitlements new file mode 100644 index 0000000..9148921 --- /dev/null +++ b/local_plugin/location-3.0.2/example/macos/Runner/Release.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.personal-information.location + + + diff --git a/local_plugin/location-3.0.2/example/pubspec.yaml b/local_plugin/location-3.0.2/example/pubspec.yaml new file mode 100644 index 0000000..594c237 --- /dev/null +++ b/local_plugin/location-3.0.2/example/pubspec.yaml @@ -0,0 +1,17 @@ +name: location_example +description: Demonstrates how to use the location plugin. + +dependencies: + flutter: + sdk: flutter + location: + path: ../ + url_launcher: ^5.4.2 + +dev_dependencies: + flutter_driver: + sdk: flutter + e2e: ^0.2.1 + +flutter: + uses-material-design: true diff --git a/local_plugin/location-3.0.2/example/web/favicon.png b/local_plugin/location-3.0.2/example/web/favicon.png new file mode 100644 index 0000000..8aaa46a Binary files /dev/null and b/local_plugin/location-3.0.2/example/web/favicon.png differ diff --git a/local_plugin/location-3.0.2/example/web/icons/Icon-192.png b/local_plugin/location-3.0.2/example/web/icons/Icon-192.png new file mode 100644 index 0000000..b749bfe Binary files /dev/null and b/local_plugin/location-3.0.2/example/web/icons/Icon-192.png differ diff --git a/local_plugin/location-3.0.2/example/web/icons/Icon-512.png b/local_plugin/location-3.0.2/example/web/icons/Icon-512.png new file mode 100644 index 0000000..88cfd48 Binary files /dev/null and b/local_plugin/location-3.0.2/example/web/icons/Icon-512.png differ diff --git a/local_plugin/location-3.0.2/example/web/index.html b/local_plugin/location-3.0.2/example/web/index.html new file mode 100644 index 0000000..4ddab97 --- /dev/null +++ b/local_plugin/location-3.0.2/example/web/index.html @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + location_example + + + + + + + + diff --git a/local_plugin/location-3.0.2/example/web/manifest.json b/local_plugin/location-3.0.2/example/web/manifest.json new file mode 100644 index 0000000..abe4830 --- /dev/null +++ b/local_plugin/location-3.0.2/example/web/manifest.json @@ -0,0 +1,23 @@ +{ + "name": "location_example", + "short_name": "location_example", + "start_url": ".", + "display": "minimal-ui", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "Demonstrates how to use the location plugin.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +} diff --git a/local_plugin/location-3.0.2/ios/Assets/.gitkeep b/local_plugin/location-3.0.2/ios/Assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/local_plugin/location-3.0.2/ios/Classes/LocationPlugin.h b/local_plugin/location-3.0.2/ios/Classes/LocationPlugin.h new file mode 100644 index 0000000..42cb7eb --- /dev/null +++ b/local_plugin/location-3.0.2/ios/Classes/LocationPlugin.h @@ -0,0 +1,4 @@ +#import + +@interface LocationPlugin : NSObject +@end diff --git a/local_plugin/location-3.0.2/ios/Classes/LocationPlugin.m b/local_plugin/location-3.0.2/ios/Classes/LocationPlugin.m new file mode 100644 index 0000000..6ae7ca8 --- /dev/null +++ b/local_plugin/location-3.0.2/ios/Classes/LocationPlugin.m @@ -0,0 +1,321 @@ +#import "LocationPlugin.h" + +#ifdef COCOAPODS +@import CoreLocation; +#else +#import +#endif + +@interface LocationPlugin() +@property (strong, nonatomic) CLLocationManager *clLocationManager; +@property (copy, nonatomic) FlutterResult flutterResult; +@property (assign, nonatomic) BOOL locationWanted; +@property (assign, nonatomic) BOOL permissionWanted; + +@property (copy, nonatomic) FlutterEventSink flutterEventSink; +@property (assign, nonatomic) BOOL flutterListening; +@property (assign, nonatomic) BOOL hasInit; +@end + +@implementation LocationPlugin + ++(void)registerWithRegistrar:(NSObject*)registrar { + FlutterMethodChannel *channel = + [FlutterMethodChannel methodChannelWithName:@"lyokone/location" + binaryMessenger:registrar.messenger]; + FlutterEventChannel *stream = + [FlutterEventChannel eventChannelWithName:@"lyokone/locationstream" + binaryMessenger:registrar.messenger]; + + LocationPlugin *instance = [[LocationPlugin alloc] init]; + [registrar addMethodCallDelegate:instance channel:channel]; + [stream setStreamHandler:instance]; +} + +-(instancetype)init { + self = [super init]; + + if (self) { + self.locationWanted = NO; + self.permissionWanted = NO; + self.flutterListening = NO; + self.hasInit = NO; + } + return self; +} + +-(void)initLocation { + if (!(self.hasInit)) { + self.hasInit = YES; + + if ([CLLocationManager locationServicesEnabled]) { + self.clLocationManager = [[CLLocationManager alloc] init]; + self.clLocationManager.delegate = self; + self.clLocationManager.desiredAccuracy = kCLLocationAccuracyBest; + } + } +} + +-(void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { + [self initLocation]; + if ([call.method isEqualToString:@"changeSettings"]) { + if ([CLLocationManager locationServicesEnabled]) { + NSDictionary *dictionary = @{ + @"0" : @(kCLLocationAccuracyKilometer), + @"1" : @(kCLLocationAccuracyHundredMeters), + @"2" : @(kCLLocationAccuracyNearestTenMeters), + @"3" : @(kCLLocationAccuracyBest), + @"4" : @(kCLLocationAccuracyBestForNavigation) + }; + + self.clLocationManager.desiredAccuracy = + [dictionary[call.arguments[@"accuracy"]] doubleValue]; + double distanceFilter = [call.arguments[@"distanceFilter"] doubleValue]; + if (distanceFilter == 0){ + distanceFilter = kCLDistanceFilterNone; + } + self.clLocationManager.distanceFilter = distanceFilter; + result(@1); + } + } else if ([call.method isEqualToString:@"getLocation"]) { + if (![CLLocationManager locationServicesEnabled]) { + result([FlutterError errorWithCode:@"SERVICE_STATUS_DISABLED" message:@"Failed to get location. Location services disabled" details:nil]); + return; + } + if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) { + // Location services are requested but user has denied + NSString *message = @"The user explicitly denied the use of location services for this " + "app or location services are currently disabled in Settings."; + result([FlutterError errorWithCode:@"PERMISSION_DENIED" + message:message + details:nil]); + return; + } + + self.flutterResult = result; + self.locationWanted = YES; + + if ([self isPermissionGranted]) { + [self.clLocationManager startUpdatingLocation]; + } else { + [self requestPermission]; + if ([self isPermissionGranted]) { + [self.clLocationManager startUpdatingLocation]; + } + } + } else if ([call.method isEqualToString:@"hasPermission"]) { + if ([self isPermissionGranted]) { + result(@1); + } else { + result(@0); + } + } else if ([call.method isEqualToString:@"requestPermission"]) { + if ([self isPermissionGranted]) { + result(@1); + } else if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) { + self.flutterResult = result; + self.permissionWanted = YES; + [self requestPermission]; + } else { + result(@2); + } + } else if ([call.method isEqualToString:@"serviceEnabled"]) { + if ([CLLocationManager locationServicesEnabled]) { + result(@1); + } else { + result(@0); + } + } else if ([call.method isEqualToString:@"requestService"]) { + if ([CLLocationManager locationServicesEnabled]) { + result(@1); + } else { +#if TARGET_OS_OSX + NSAlert *alert = [[NSAlert alloc] init]; + [alert setMessageText:@"Location is Disabled"]; + [alert setInformativeText:@"To use location, go to your System Preferences > Security & Privacy > Privacy > Location Services."]; + [alert addButtonWithTitle:@"Open"]; + [alert addButtonWithTitle:@"Cancel"]; + [alert beginSheetModalForWindow:NSApplication.sharedApplication.mainWindow + completionHandler:^(NSModalResponse returnCode) { + if (returnCode == NSAlertFirstButtonReturn) { + NSString *urlString = @"x-apple.systempreferences:com.apple.preference.security?Privacy_LocationServices"; + [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:urlString]]; + } else { + NSLog(@"Cancel"); + } + }]; +#else + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Location is Disabled" + message:@"To use location, go to your Settings App > Privacy > Location Services." + delegate:self + cancelButtonTitle:@"Cancel" + otherButtonTitles:nil]; + [alert show]; +#endif + result(@0); + } + } else { + result(FlutterMethodNotImplemented); + } +} + + +-(void) requestPermission { +#if TARGET_OS_OSX + if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"] != nil) { + if (@available(macOS 10.15, *)) { + [self.clLocationManager requestAlwaysAuthorization]; + } + } +#else + if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"] != nil) { + [self.clLocationManager requestWhenInUseAuthorization]; + } + else if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"] != nil) { + [self.clLocationManager requestAlwaysAuthorization]; + } +#endif + else { + [NSException raise:NSInternalInconsistencyException format: + @"To use location in iOS8 and above you need to define either " + "NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription in the app " + "bundle's Info.plist file"]; + } +} + +-(BOOL) isPermissionGranted { + BOOL isPermissionGranted = NO; + CLAuthorizationStatus status = [CLLocationManager authorizationStatus]; + +#if TARGET_OS_OSX + if (status == kCLAuthorizationStatusAuthorized) { + // Location services are available + isPermissionGranted = YES; + } else if (@available(macOS 10.12, *)) { + if (status == kCLAuthorizationStatusAuthorizedAlways) { + // Location services are available + isPermissionGranted = YES; + } + } +#else //if TARGET_OS_IOS + if (status == kCLAuthorizationStatusAuthorizedWhenInUse || + status == kCLAuthorizationStatusAuthorizedAlways) { + // Location services are available + isPermissionGranted = YES; + } +#endif + else if (status == kCLAuthorizationStatusDenied || + status == kCLAuthorizationStatusRestricted) { + // Location services are requested but user has denied / the app is restricted from + // getting location + isPermissionGranted = NO; + } else if (status == kCLAuthorizationStatusNotDetermined) { + // Location services never requested / the user still haven't decide + isPermissionGranted = NO; + } else { + isPermissionGranted = NO; + } + + return isPermissionGranted; +} + +-(FlutterError*)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events { + self.flutterEventSink = events; + self.flutterListening = YES; + + if ([self isPermissionGranted]) { + [self.clLocationManager startUpdatingLocation]; + } else { + [self requestPermission]; + } + + return nil; +} + +-(FlutterError*)onCancelWithArguments:(id)arguments { + self.flutterListening = NO; + [self.clLocationManager stopUpdatingLocation]; + return nil; +} + +#pragma mark - CLLocationManagerDelegate Methods + +-(void)locationManager:(CLLocationManager*)manager + didUpdateLocations:(NSArray*)locations { + CLLocation *location = locations.firstObject; + NSTimeInterval timeInSeconds = [location.timestamp timeIntervalSince1970]; + NSDictionary* coordinatesDict = + @{ + @"latitude": @(location.coordinate.latitude), + @"longitude": @(location.coordinate.longitude), + @"accuracy": @(location.horizontalAccuracy), + @"altitude": @(location.altitude), + @"speed": @(location.speed), + @"speed_accuracy": @0.0, + @"heading": @(location.course), + @"time": @(((double) timeInSeconds) * 1000.0) // in milliseconds since the epoch + }; + + if (self.locationWanted) { + self.locationWanted = NO; + self.flutterResult(coordinatesDict); + } + if (self.flutterListening) { + self.flutterEventSink(coordinatesDict); + } else { + [self.clLocationManager stopUpdatingLocation]; + } +} + +- (void)locationManager:(CLLocationManager *)manager + didChangeAuthorizationStatus:(CLAuthorizationStatus)status { + if (status == kCLAuthorizationStatusDenied) { + // The user denied authorization + NSLog(@"User denied permissions"); + if (self.permissionWanted) { + self.permissionWanted = NO; + self.flutterResult(@0); + } + } +#if TARGET_OS_OSX + else if (status == kCLAuthorizationStatusAuthorized) { + NSLog(@"User granted permissions"); + if (self.permissionWanted) { + self.permissionWanted = NO; + self.flutterResult(@1); + } + + if (self.locationWanted || self.flutterListening) { + [self.clLocationManager startUpdatingLocation]; + } + } else if (@available(macOS 10.12, *)) { + if (status == kCLAuthorizationStatusAuthorizedAlways) { + NSLog(@"User granted permissions"); + if (self.permissionWanted) { + self.permissionWanted = NO; + self.flutterResult(@1); + } + + if (self.locationWanted || self.flutterListening) { + [self.clLocationManager startUpdatingLocation]; + } + } + } +#else //if TARGET_OS_IOS + else if (status == kCLAuthorizationStatusAuthorizedWhenInUse || + status == kCLAuthorizationStatusAuthorizedAlways) { + NSLog(@"User granted permissions"); + if (self.permissionWanted) { + self.permissionWanted = NO; + self.flutterResult(@1); + } + + if (self.locationWanted || self.flutterListening) { + [self.clLocationManager startUpdatingLocation]; + } + } +#endif +} + + +@end diff --git a/local_plugin/location-3.0.2/ios/location.podspec b/local_plugin/location-3.0.2/ios/location.podspec new file mode 100644 index 0000000..2f4be91 --- /dev/null +++ b/local_plugin/location-3.0.2/ios/location.podspec @@ -0,0 +1,21 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# +Pod::Spec.new do |s| + s.name = 'location' + s.version = '0.0.1' + s.summary = 'A new flutter plugin project.' + s.description = <<-DESC +A new flutter plugin project. + DESC + s.homepage = 'http://example.com' + s.license = { :file => '../LICENSE' } + s.author = { 'Your Company' => 'email@example.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.public_header_files = 'Classes/**/*.h' + s.dependency 'Flutter' + + s.ios.deployment_target = '8.0' +end + diff --git a/local_plugin/location-3.0.2/lib/location.dart b/local_plugin/location-3.0.2/lib/location.dart new file mode 100644 index 0000000..a1658e7 --- /dev/null +++ b/local_plugin/location-3.0.2/lib/location.dart @@ -0,0 +1,79 @@ +import 'dart:async'; + +import 'package:location_platform_interface/location_platform_interface.dart'; + +export 'package:location_platform_interface/location_platform_interface.dart' + show PermissionStatus, LocationAccuracy, LocationData; + +class Location { + /// Initializes the plugin and starts listening for potential platform events. + factory Location() => instance; + + Location._(); + + static final Location instance = Location._(); + + /// Change settings of the location request. + /// + /// The [accuracy] argument is controlling the precision of the + /// [LocationData]. The [interval] and [distanceFilter] are controlling how + /// often a new location is sent through [onLocationChanged]. + /// + /// [interval] and [distanceFilter] are not used on web. + Future changeSettings({ + LocationAccuracy accuracy = LocationAccuracy.high, + int interval = 1000, + double distanceFilter = 0, + }) { + return LocationPlatform.instance.changeSettings( + accuracy: accuracy, + interval: interval, + distanceFilter: distanceFilter, + ); + } + + /// Gets the current location of the user. + /// + /// Throws an error if the app has no permission to access location. + /// Returns a [LocationData] object. + Future getLocation() async { + return LocationPlatform.instance.getLocation(); + } + + /// Checks if the app has permission to access location. + /// + /// If the result is [PermissionStatus.deniedForever], no dialog will be + /// shown on [requestPermission]. + /// Returns a [PermissionStatus] object. + Future hasPermission() { + return LocationPlatform.instance.hasPermission(); + } + + /// Checks if the app has permission to access location. + /// + /// If the result is [PermissionStatus.deniedForever], no dialog will be + /// shown on [requestPermission]. + /// Returns a [PermissionStatus] object. + Future requestPermission() { + return LocationPlatform.instance.requestPermission(); + } + + /// Checks if the location service is enabled. + Future serviceEnabled() { + return LocationPlatform.instance.serviceEnabled(); + } + + /// Request the activation of the location service. + Future requestService() { + return LocationPlatform.instance.requestService(); + } + + /// Returns a stream of [LocationData] objects. + /// The frequency and accuracy of this stream can be changed with + /// [changeSettings] + /// + /// Throws an error if the app has no permission to access location. + Stream get onLocationChanged { + return LocationPlatform.instance.onLocationChanged; + } +} diff --git a/local_plugin/location-3.0.2/macos/Classes/LocationPlugin.h b/local_plugin/location-3.0.2/macos/Classes/LocationPlugin.h new file mode 100644 index 0000000..2f17530 --- /dev/null +++ b/local_plugin/location-3.0.2/macos/Classes/LocationPlugin.h @@ -0,0 +1,4 @@ +#import + +@interface LocationPlugin : NSObject +@end diff --git a/local_plugin/location-3.0.2/macos/location.podspec b/local_plugin/location-3.0.2/macos/location.podspec new file mode 100644 index 0000000..7f5a33f --- /dev/null +++ b/local_plugin/location-3.0.2/macos/location.podspec @@ -0,0 +1,22 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. +# Run `pod lib lint test_location.podspec' to validate before publishing. +# +Pod::Spec.new do |s| + s.name = 'location' + s.version = '0.0.1' + s.summary = 'A new Flutter project.' + s.description = <<-DESC +A new Flutter project. + DESC + s.homepage = 'http://example.com' + s.license = { :file => '../LICENSE' } + s.author = { 'Your Company' => 'email@example.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.dependency 'FlutterMacOS' + + s.platform = :osx, '10.11' + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } + s.swift_version = '5.0' +end diff --git a/local_plugin/location-3.0.2/pubspec.yaml b/local_plugin/location-3.0.2/pubspec.yaml new file mode 100644 index 0000000..d7a6252 --- /dev/null +++ b/local_plugin/location-3.0.2/pubspec.yaml @@ -0,0 +1,37 @@ +name: location +description: A Flutter plugin to easily handle realtime location in iOS and Android. Provides settings for optimizing performance or battery. +version: 3.0.2 +author: Guillaume Bernos +homepage: https://github.com/Lyokone/flutterlocation + +environment: + sdk: ">=2.0.0 <3.0.0" + flutter: ">=1.12.13+hotfix.5 <2.0.0" + +flutter: + plugin: + platforms: + android: + package: com.lyokone.location + pluginClass: LocationPlugin + ios: + pluginClass: LocationPlugin + macos: + pluginClass: LocationPlugin + web: + default_package: location_web + +dependencies: + flutter: + sdk: flutter + meta: ^1.0.5 + location_platform_interface: ^1.0.0 + location_web: ^1.0.0 + +dev_dependencies: + async: ^2.0.8 + test: ^1.3.0 + mockito: 3.0.0 + flutter_test: + sdk: flutter + e2e: ^0.2.4+1 diff --git a/local_plugin/location-3.0.2/src/demo_readme.gif b/local_plugin/location-3.0.2/src/demo_readme.gif new file mode 100644 index 0000000..df566fc Binary files /dev/null and b/local_plugin/location-3.0.2/src/demo_readme.gif differ diff --git a/local_plugin/location-3.0.2/test/location_e2e.dart b/local_plugin/location-3.0.2/test/location_e2e.dart new file mode 100644 index 0000000..2199224 --- /dev/null +++ b/local_plugin/location-3.0.2/test/location_e2e.dart @@ -0,0 +1,12 @@ +import 'package:e2e/e2e.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:location/location.dart'; + +void main() { + E2EWidgetsFlutterBinding.ensureInitialized(); + + testWidgets('Can instantiate Location object', (WidgetTester tester) async { + final Location location = Location(); + expect(location, isNotNull); + }); +} diff --git a/local_plugin/location-3.0.2/test/location_test.dart b/local_plugin/location-3.0.2/test/location_test.dart new file mode 100644 index 0000000..dabb37e --- /dev/null +++ b/local_plugin/location-3.0.2/test/location_test.dart @@ -0,0 +1,132 @@ +import 'dart:async'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:location/location.dart'; +import 'package:location_platform_interface/location_platform_interface.dart'; +import 'package:mockito/mockito.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + final Location location = Location(); + final LocationPlatformMock platform = LocationPlatformMock(); + LocationPlatform.instance = platform; + + tearDown(resetMockitoState); + + group('getLocation', () { + when(platform.getLocation()).thenAnswer((_) async { + return LocationData.fromMap({ + 'latitude': 48.8534, + 'longitude': 2.3488, + }); + }); + + test('getLocation should convert results correctly', () async { + final LocationData receivedLocation = await location.getLocation(); + expect(receivedLocation.latitude, 48.8534); + expect(receivedLocation.longitude, 2.3488); + }); + + test('getLocation should convert to string correctly', () async { + final LocationData receivedLocation = await location.getLocation(); + + expect(receivedLocation.toString(), + 'LocationData'); + }); + }); + + test('changeSettings', () async { + when(platform.changeSettings( + accuracy: captureAnyNamed('accuracy'), + interval: captureAnyNamed('interval'), + distanceFilter: captureAnyNamed('distanceFilter'), + )); + + await location.changeSettings(); + final VerificationResult result = verify(platform.changeSettings( + accuracy: captureAnyNamed('accuracy'), + interval: captureAnyNamed('interval'), + distanceFilter: captureAnyNamed('distanceFilter'), + )); + + expect(result.callCount, 1); + expect(result.captured[0], LocationAccuracy.high); + expect(result.captured[1], 1000); + expect(result.captured[2], 0); + }); + + group('serviceEnabled-requestService', () { + when(platform.serviceEnabled()).thenAnswer((_) async => true); + when(platform.requestService()).thenAnswer((_) async => true); + + test('serviceEnabled', () async { + final bool result = await location.serviceEnabled(); + expect(result, isTrue); + }); + + test('requestService', () async { + final bool result = await location.requestService(); + expect(result, isTrue); + }); + }); + + test('hasPermission', () async { + when(platform.hasPermission()) + .thenAnswer((_) async => PermissionStatus.denied); + when(platform.requestPermission()) + .thenAnswer((_) async => PermissionStatus.denied); + + PermissionStatus receivedPermission = await location.hasPermission(); + expect(receivedPermission, PermissionStatus.denied); + + receivedPermission = await location.requestPermission(); + expect(receivedPermission, PermissionStatus.denied); + }); + + group('onLocationChanged', () { + StreamController controller; + + setUp(() { + controller = StreamController(); + when(platform.onLocationChanged) + .thenAnswer((Invocation invoke) => controller.stream); + }); + + tearDown(() => controller.close()); + + test('should receive values', () async { + controller.add(LocationData.fromMap({ + 'latitude': 48.8534, + 'longitude': 2.3488, + })); + controller.add(LocationData.fromMap({ + 'latitude': 42.8534, + 'longitude': 23.3488, + })); + controller.close(); + + await expectLater( + location.onLocationChanged, + emitsInOrder( + [ + LocationData.fromMap({ + 'latitude': 48.8534, + 'longitude': 2.3488, + }), + LocationData.fromMap({ + 'latitude': 42.8534, + 'longitude': 23.3488, + }), + emitsDone, + ], + ), + ); + }); + }); +} + +class LocationPlatformMock extends Mock + with MockPlatformInterfaceMixin + implements LocationPlatform {} diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..5224052 --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,453 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + app_settings: + dependency: "direct main" + description: + name: app_settings + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.1+1" + archive: + dependency: transitive + description: + name: archive + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.13" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.0" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.1" + barcode_scan: + dependency: "direct main" + description: + name: barcode_scan + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.3" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.14.12" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.4" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "5.2.1" + fixnum: + dependency: transitive + description: + name: fixnum + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.11" + flushbar: + dependency: "direct main" + description: + name: flushbar + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.4" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_launcher_icons: + dependency: "direct main" + description: + name: flutter_launcher_icons + url: "https://pub.dartlang.org" + source: hosted + version: "0.7.5" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.8" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + http: + dependency: "direct main" + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.1" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.4" + image: + dependency: transitive + description: + name: image + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.12" + image_picker: + dependency: "direct main" + description: + name: image_picker + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.7+2" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + intl: + dependency: "direct main" + description: + name: intl + url: "https://pub.dartlang.org" + source: hosted + version: "0.16.1" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.2" + location: + dependency: "direct main" + description: + path: "local_plugin/location-3.0.2" + relative: true + source: path + version: "3.0.2" + location_platform_interface: + dependency: transitive + description: + name: location_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + location_web: + dependency: transitive + description: + name: location_web + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.6" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.8" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.4" + path_provider: + dependency: "direct main" + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.11" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+1" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4+3" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.0" + permission_handler: + dependency: "direct main" + description: + name: permission_handler + url: "https://pub.dartlang.org" + source: hosted + version: "5.0.1+1" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.0" + photo_view: + dependency: "direct main" + description: + name: photo_view + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.2" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.1" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.13" + protobuf: + dependency: transitive + description: + name: protobuf + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.3" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.7+3" + shared_preferences_macos: + dependency: transitive + description: + name: shared_preferences_macos + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+10" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2+7" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.0" + sqflite: + dependency: "direct main" + description: + name: sqflite + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2+1" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.3" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" + synchronized: + dependency: transitive + description: + name: synchronized + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0+1" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.15" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "3.6.1" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.1" +sdks: + dart: ">=2.8.0 <3.0.0" + flutter: ">=1.12.13+hotfix.5 <2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..f6d0e8a --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,90 @@ +name: unitstocks +description: App to stock Thamrin Brothers Units +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: + image_picker: + photo_view: + sqflite: + path_provider: + flushbar: + http: + intl: + shared_preferences: + location: + path: 'local_plugin/location-3.0.2' + permission_handler: + app_settings: +# autocomplete_textfield: + barcode_scan: + flutter_launcher_icons: + +dev_dependencies: + flutter_test: + sdk: flutter + +flutter_icons: + android: "launcher_icon" + ios: true + image_path: "asset/icon.png" + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/test/widget_test.dart b/test/widget_test.dart new file mode 100644 index 0000000..c79fb50 --- /dev/null +++ b/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:unitstocks/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +}