├── android ├── .gradle │ ├── 4.10.2 │ │ ├── gc.properties │ │ ├── fileChanges │ │ │ └── last-build.bin │ │ ├── fileHashes │ │ │ ├── fileHashes.bin │ │ │ ├── fileHashes.lock │ │ │ └── resourceHashesCache.bin │ │ ├── fileContent │ │ │ └── fileContent.lock │ │ ├── javaCompile │ │ │ ├── jarAnalysis.bin │ │ │ ├── javaCompile.lock │ │ │ ├── taskHistory.bin │ │ │ └── classAnalysis.bin │ │ └── taskHistory │ │ │ ├── taskHistory.bin │ │ │ └── taskHistory.lock │ ├── vcs-1 │ │ └── gc.properties │ └── buildOutputCleanup │ │ ├── cache.properties │ │ ├── outputFiles.bin │ │ └── buildOutputCleanup.lock ├── app │ ├── src │ │ └── main │ │ │ ├── ic_launcher-web.png │ │ │ ├── res │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_round.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_round.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_round.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_round.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_round.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── values │ │ │ │ ├── color.xml │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ └── styles.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ └── drawable │ │ │ │ └── launch_background.xml │ │ │ ├── gen │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── itzmeanjan │ │ │ │ └── traceme │ │ │ │ ├── R.java │ │ │ │ └── Manifest.java │ │ │ ├── java │ │ │ └── io │ │ │ │ └── flutter │ │ │ │ └── plugins │ │ │ │ └── GeneratedPluginRegistrant.java │ │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── itzmeanjan │ │ │ │ └── traceme │ │ │ │ ├── RouteDataManager.kt │ │ │ │ ├── FeatureDataManager.kt │ │ │ │ └── LocationDataHolder.kt │ │ │ ├── AndroidManifest.xml │ │ │ └── main.iml │ └── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── .idea │ ├── caches │ │ └── build_file_checksums.ser │ ├── vcs.xml │ ├── modules.xml │ ├── misc.xml │ ├── libraries │ │ ├── Gradle__com_google_code_findbugs_jsr305_2_0_1_jar.xml │ │ ├── Gradle____local_aars____home_anjan_flutter_bin_cache_artifacts_engine_android_arm_flutter_jar_unspecified_jar.xml │ │ ├── Gradle____local_aars____home_anjan_AndroidStudioProjects_locatorz_build_app_intermediates_flutter_flutter_x86_jar_unspecified_jar.xml │ │ ├── Gradle__androidx_multidex_multidex_2_0_0_aar.xml │ │ ├── Gradle__junit_junit_4_12_jar.xml │ │ ├── Gradle__net_sf_kxml_kxml2_2_3_0_jar.xml │ │ ├── Gradle__androidx_multidex_multidex_instrumentation_2_0_0_aar.xml │ │ ├── Gradle__javax_inject_javax_inject_1_jar.xml │ │ ├── Gradle__com_google_android_gms_play_services_base_16_0_1_aar.xml │ │ ├── Gradle__com_google_android_gms_play_services_tasks_16_0_1_aar.xml │ │ ├── Gradle__com_squareup_javawriter_2_1_1_jar.xml │ │ ├── Gradle__org_hamcrest_hamcrest_core_1_3_jar.xml │ │ ├── Gradle__org_jetbrains_annotations_13_0_jar.xml │ │ ├── Gradle__com_google_android_gms_play_services_basement_16_0_1_aar.xml │ │ ├── Gradle__com_google_android_gms_play_services_location_16_0_0_aar.xml │ │ ├── Gradle__org_hamcrest_hamcrest_library_1_3_jar.xml │ │ ├── Gradle__androidx_annotation_annotation_1_0_0_jar.xml │ │ ├── Gradle__androidx_arch_core_core_common_2_0_0_jar.xml │ │ ├── Gradle__androidx_collection_collection_1_0_0_jar.xml │ │ ├── Gradle__com_google_android_gms_play_services_places_placereport_16_0_0_aar.xml │ │ ├── Gradle__androidx_room_room_common_2_0_0_rc01_jar.xml │ │ ├── Gradle__org_hamcrest_hamcrest_integration_1_3_jar.xml │ │ ├── Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_3_21_jar.xml │ │ ├── Gradle__androidx_lifecycle_lifecycle_common_2_0_0_jar.xml │ │ ├── Gradle__org_jetbrains_kotlin_kotlin_stdlib_jdk7_1_3_21_jar.xml │ │ ├── Gradle__org_jetbrains_kotlin_kotlin_stdlib_common_1_3_21_jar.xml │ │ ├── Gradle__androidx_loader_loader_1_0_0_aar.xml │ │ ├── Gradle__androidx_viewpager_viewpager_1_0_0_aar.xml │ │ ├── Gradle__androidx_sqlite_sqlite_2_0_0_rc01_aar.xml │ │ ├── Gradle__androidx_customview_customview_1_0_0_aar.xml │ │ ├── Gradle__androidx_test_runner_1_1_2_alpha01_aar.xml │ │ ├── Gradle__androidx_arch_core_core_runtime_2_0_0_aar.xml │ │ ├── Gradle__androidx_test_monitor_1_1_2_alpha01_aar.xml │ │ ├── Gradle__androidx_documentfile_documentfile_1_0_0_aar.xml │ │ ├── Gradle__androidx_interpolator_interpolator_1_0_0_aar.xml │ │ ├── Gradle__androidx_cursoradapter_cursoradapter_1_0_0_aar.xml │ │ ├── Gradle__androidx_legacy_legacy_support_v4_1_0_0_aar.xml │ │ ├── Gradle__androidx_lifecycle_lifecycle_runtime_2_0_0_aar.xml │ │ ├── Gradle__androidx_lifecycle_lifecycle_livedata_2_0_0_aar.xml │ │ ├── Gradle__androidx_lifecycle_lifecycle_viewmodel_2_0_0_aar.xml │ │ ├── Gradle__androidx_sqlite_sqlite_framework_2_0_0_rc01_aar.xml │ │ ├── Gradle__androidx_legacy_legacy_support_core_ui_1_0_0_aar.xml │ │ ├── Gradle__androidx_slidingpanelayout_slidingpanelayout_1_0_0_aar.xml │ │ ├── Gradle__androidx_legacy_legacy_support_core_utils_1_0_0_aar.xml │ │ ├── Gradle__androidx_lifecycle_lifecycle_livedata_core_2_0_0_aar.xml │ │ ├── Gradle__androidx_test_espresso_espresso_core_3_1_2_alpha01_aar.xml │ │ ├── Gradle__androidx_asynclayoutinflater_asynclayoutinflater_1_0_0_aar.xml │ │ ├── Gradle__androidx_versionedparcelable_versionedparcelable_1_0_0_aar.xml │ │ ├── Gradle__androidx_localbroadcastmanager_localbroadcastmanager_1_0_0_aar.xml │ │ ├── Gradle__androidx_core_core_1_0_1_aar.xml │ │ ├── Gradle__androidx_test_espresso_espresso_idling_resource_3_1_2_alpha01_aar.xml │ │ ├── Gradle__androidx_media_media_1_0_0_aar.xml │ │ ├── Gradle__androidx_print_print_1_0_0_aar.xml │ │ ├── Gradle__androidx_fragment_fragment_1_0_0_aar.xml │ │ ├── Gradle__androidx_drawerlayout_drawerlayout_1_0_0_aar.xml │ │ ├── Gradle__androidx_room_room_runtime_2_0_0_rc01_aar.xml │ │ ├── Gradle__androidx_coordinatorlayout_coordinatorlayout_1_0_0_aar.xml │ │ └── Gradle__androidx_swiperefreshlayout_swiperefreshlayout_1_0_0_aar.xml │ ├── runConfigurations.xml │ ├── gradle.xml │ ├── codeStyles │ │ └── Project.xml │ └── assetWizardSettings.xml ├── gradle.properties ├── local.properties ├── settings.gradle ├── build.gradle ├── android.iml ├── gradlew.bat ├── trace_me_android.iml └── gradlew ├── ios ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ ├── Generated.xcconfig │ └── AppFrameworkInfo.plist ├── Runner │ ├── AppDelegate.h │ ├── Assets.xcassets │ │ ├── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ └── Contents.json │ ├── main.m │ ├── GeneratedPluginRegistrant.m │ ├── GeneratedPluginRegistrant.h │ ├── AppDelegate.m │ ├── Info.plist │ └── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard ├── Runner.xcworkspace │ └── contents.xcworkspacedata └── Runner.xcodeproj │ ├── project.xcworkspace │ └── contents.xcworkspacedata │ └── xcshareddata │ └── xcschemes │ └── Runner.xcscheme ├── recording.mp4 ├── Screenshot_20190324-222334.png ├── Screenshot_20190324-222349.png ├── Screenshot_20190324-222400.png ├── Screenshot_20190324-222432.png ├── Screenshot_20190331-221646.png ├── lib ├── main.dart ├── FeatureHolder.dart ├── CSVExporter.dart ├── PlatformLevelLocationIssueHandler.dart ├── MyLocation.dart ├── RouteToMap.dart ├── RouteInfoHolder.dart ├── SettingsPage.dart ├── MyAppHome.dart └── FeatureCollector.dart ├── locatorz.iml ├── trace_me.iml ├── README.md ├── LICENSE ├── test └── widget_test.dart ├── pubspec.yaml └── pubspec.lock /android/.gradle/4.10.2/gc.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /android/.gradle/vcs-1/gc.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /android/.gradle/4.10.2/fileChanges/last-build.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /recording.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/recording.mp4 -------------------------------------------------------------------------------- /android/.gradle/buildOutputCleanup/cache.properties: -------------------------------------------------------------------------------- 1 | #Fri Jan 18 21:32:58 IST 2019 2 | gradle.version=4.10.2 3 | -------------------------------------------------------------------------------- /Screenshot_20190324-222334.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/Screenshot_20190324-222334.png -------------------------------------------------------------------------------- /Screenshot_20190324-222349.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/Screenshot_20190324-222349.png -------------------------------------------------------------------------------- /Screenshot_20190324-222400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/Screenshot_20190324-222400.png -------------------------------------------------------------------------------- /Screenshot_20190324-222432.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/Screenshot_20190324-222432.png -------------------------------------------------------------------------------- /Screenshot_20190331-221646.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/Screenshot_20190331-221646.png -------------------------------------------------------------------------------- /android/app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/.idea/caches/build_file_checksums.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/.idea/caches/build_file_checksums.ser -------------------------------------------------------------------------------- /android/.gradle/4.10.2/fileHashes/fileHashes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/.gradle/4.10.2/fileHashes/fileHashes.bin -------------------------------------------------------------------------------- /android/.gradle/4.10.2/fileHashes/fileHashes.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/.gradle/4.10.2/fileHashes/fileHashes.lock -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX = true 3 | android.enableJetifier = true 4 | android.enableR8 = true 5 | -------------------------------------------------------------------------------- /android/local.properties: -------------------------------------------------------------------------------- 1 | sdk.dir=/home/anjan/Android/Sdk 2 | flutter.sdk=/home/anjan/flutter 3 | flutter.versionName=1.2.1 4 | flutter.buildMode=release -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /android/.gradle/4.10.2/fileContent/fileContent.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/.gradle/4.10.2/fileContent/fileContent.lock -------------------------------------------------------------------------------- /android/.gradle/4.10.2/javaCompile/jarAnalysis.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/.gradle/4.10.2/javaCompile/jarAnalysis.bin -------------------------------------------------------------------------------- /android/.gradle/4.10.2/javaCompile/javaCompile.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/.gradle/4.10.2/javaCompile/javaCompile.lock -------------------------------------------------------------------------------- /android/.gradle/4.10.2/javaCompile/taskHistory.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/.gradle/4.10.2/javaCompile/taskHistory.bin -------------------------------------------------------------------------------- /android/.gradle/4.10.2/taskHistory/taskHistory.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/.gradle/4.10.2/taskHistory/taskHistory.bin -------------------------------------------------------------------------------- /android/.gradle/4.10.2/taskHistory/taskHistory.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/.gradle/4.10.2/taskHistory/taskHistory.lock -------------------------------------------------------------------------------- /android/.gradle/buildOutputCleanup/outputFiles.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/.gradle/buildOutputCleanup/outputFiles.bin -------------------------------------------------------------------------------- /android/.gradle/4.10.2/javaCompile/classAnalysis.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/.gradle/4.10.2/javaCompile/classAnalysis.bin -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/.gradle/4.10.2/fileHashes/resourceHashesCache.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/.gradle/4.10.2/fileHashes/resourceHashesCache.bin -------------------------------------------------------------------------------- /android/.gradle/buildOutputCleanup/buildOutputCleanup.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #44ffff 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #44FFFF 4 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzmeanjan/locatorz/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /android/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/gen/com/example/itzmeanjan/traceme/R.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package com.example.itzmeanjan.traceme; 4 | 5 | /* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */ 6 | public final class R { 7 | } -------------------------------------------------------------------------------- /android/app/src/main/gen/com/example/itzmeanjan/traceme/Manifest.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package com.example.itzmeanjan.traceme; 4 | 5 | /* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */ 6 | public final class Manifest { 7 | } -------------------------------------------------------------------------------- /ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ios/Runner/GeneratedPluginRegistrant.m: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | #import "GeneratedPluginRegistrant.h" 6 | 7 | @implementation GeneratedPluginRegistrant 8 | 9 | + (void)registerWithRegistry:(NSObject*)registry { 10 | } 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun Oct 27 14:54:49 IST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /ios/Flutter/Generated.xcconfig: -------------------------------------------------------------------------------- 1 | // This is a generated file; do not edit or check into version control. 2 | FLUTTER_ROOT=/home/anjan/flutter 3 | FLUTTER_APPLICATION_PATH=/home/anjan/AndroidStudioProjects/locatorz 4 | FLUTTER_TARGET=lib/main.dart 5 | FLUTTER_BUILD_DIR=build 6 | SYMROOT=${SOURCE_ROOT}/../build/ios 7 | FLUTTER_FRAMEWORK_DIR=/home/anjan/flutter/bin/cache/artifacts/engine/ios 8 | FLUTTER_BUILD_NAME=1.2.1 9 | -------------------------------------------------------------------------------- /ios/Runner/GeneratedPluginRegistrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | #ifndef GeneratedPluginRegistrant_h 6 | #define GeneratedPluginRegistrant_h 7 | 8 | #import 9 | 10 | @interface GeneratedPluginRegistrant : NSObject 11 | + (void)registerWithRegistry:(NSObject*)registry; 12 | @end 13 | 14 | #endif /* GeneratedPluginRegistrant_h */ 15 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_2_0_1_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle____local_aars____home_anjan_flutter_bin_cache_artifacts_engine_android_arm_flutter_jar_unspecified_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'MyAppHome.dart'; 3 | 4 | void main() => runApp(MyApp()); 5 | 6 | class MyApp extends StatelessWidget { 7 | @override 8 | Widget build(BuildContext context) { 9 | return MaterialApp( 10 | title: 'Locatorz', 11 | theme: ThemeData.light(), 12 | darkTheme: ThemeData.dark(), 13 | initialRoute: '/', 14 | routes: { 15 | '/': (context) => MyAppHome(), 16 | }, 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/FeatureHolder.dart: -------------------------------------------------------------------------------- 1 | class FeatureHolder { 2 | String featureName; 3 | String featureType; 4 | String moreInfoOnFeature; 5 | List featureLocation; 6 | 7 | FeatureHolder(this.featureName, this.featureType, this.moreInfoOnFeature, 8 | this.featureLocation); 9 | } 10 | 11 | class FeatureLocation { 12 | String longitude; 13 | String latitude; 14 | String altitude; 15 | String timeStamp; 16 | 17 | FeatureLocation(this.longitude, this.latitude, this.altitude, this.timeStamp); 18 | } 19 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle____local_aars____home_anjan_AndroidStudioProjects_locatorz_build_app_intermediates_flutter_flutter_x86_jar_unspecified_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_multidex_multidex_2_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__junit_junit_4_12_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__net_sf_kxml_kxml2_2_3_0_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_multidex_multidex_instrumentation_2_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__javax_inject_javax_inject_1_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__com_google_android_gms_play_services_base_16_0_1_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__com_google_android_gms_play_services_tasks_16_0_1_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__com_squareup_javawriter_2_1_1_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__org_jetbrains_annotations_13_0_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__com_google_android_gms_play_services_basement_16_0_1_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__com_google_android_gms_play_services_location_16_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__org_hamcrest_hamcrest_library_1_3_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_annotation_annotation_1_0_0_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_arch_core_core_common_2_0_0_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_collection_collection_1_0_0_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__com_google_android_gms_play_services_places_placereport_16_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_room_room_common_2_0_0_rc01_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__org_hamcrest_hamcrest_integration_1_3_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_3_21_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_common_2_0_0_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_jdk7_1_3_21_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /locatorz.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /trace_me.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java: -------------------------------------------------------------------------------- 1 | package io.flutter.plugins; 2 | 3 | import io.flutter.plugin.common.PluginRegistry; 4 | 5 | /** 6 | * Generated file. Do not edit. 7 | */ 8 | public final class GeneratedPluginRegistrant { 9 | public static void registerWith(PluginRegistry registry) { 10 | if (alreadyRegisteredWith(registry)) { 11 | return; 12 | } 13 | } 14 | 15 | private static boolean alreadyRegisteredWith(PluginRegistry registry) { 16 | final String key = GeneratedPluginRegistrant.class.getCanonicalName(); 17 | if (registry.hasPlugin(key)) { 18 | return true; 19 | } 20 | registry.registrarFor(key); 21 | return false; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_common_1_3_21_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.1' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_loader_loader_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_viewpager_viewpager_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_sqlite_sqlite_2_0_0_rc01_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_customview_customview_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_test_runner_1_1_2_alpha01_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_arch_core_core_runtime_2_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_test_monitor_1_1_2_alpha01_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_documentfile_documentfile_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_interpolator_interpolator_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_cursoradapter_cursoradapter_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_legacy_legacy_support_v4_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_runtime_2_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_2_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_2_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_sqlite_sqlite_framework_2_0_0_rc01_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_legacy_legacy_support_core_ui_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_slidingpanelayout_slidingpanelayout_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_legacy_legacy_support_core_utils_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_core_2_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_test_espresso_espresso_core_3_1_2_alpha01_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_asynclayoutinflater_asynclayoutinflater_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_versionedparcelable_versionedparcelable_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_localbroadcastmanager_localbroadcastmanager_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_core_core_1_0_1_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_test_espresso_espresso_idling_resource_3_1_2_alpha01_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_media_media_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_print_print_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_fragment_fragment_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /android/android.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_drawerlayout_drawerlayout_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_room_room_runtime_2_0_0_rc01_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_coordinatorlayout_coordinatorlayout_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /android/.idea/libraries/Gradle__androidx_swiperefreshlayout_swiperefreshlayout_1_0_0_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /lib/CSVExporter.dart: -------------------------------------------------------------------------------- 1 | import 'PlatformLevelLocationIssueHandler.dart'; 2 | import 'dart:async'; 3 | 4 | class CSVExporter { 5 | final String dirName; 6 | String fileName; 7 | final List> dataToExport; 8 | final PlatformLevelLocationIssueHandler platformLevelLocationIssueHandler; 9 | 10 | CSVExporter(this.dirName, this.fileName, this.dataToExport, 11 | this.platformLevelLocationIssueHandler); 12 | 13 | Future exportToCSV() async { 14 | return await platformLevelLocationIssueHandler.methodChannel.invokeMethod( 15 | "exportToCSV", { 16 | "dirName": dirName, 17 | "fileName": fileName, 18 | "data": dataToExport 19 | }).then((dynamic value) { 20 | return value == 1; 21 | }); 22 | } 23 | 24 | Future requestStorageAccessPermission() async { 25 | return await platformLevelLocationIssueHandler.methodChannel 26 | .invokeMethod("requestStorageAccessPermission") 27 | .then((dynamic value) { 28 | return value == 1; 29 | }); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # locatorz 2 | 3 | A Simple Flutter based Android Application to work with Location based Data ;) 4 | 5 | ## Documentation :: 6 | 7 | - Work in Progress :) 8 | 9 | ## Screenshots :: 10 | 11 | ![ScreenShot 1](https://github.com/itzmeanjan/locatorz/blob/master/Screenshot_20190324-222334.png) 12 | ![ScreenShot 2](https://github.com/itzmeanjan/locatorz/blob/master/Screenshot_20190324-222349.png) 13 | ![ScreenShot 3](https://github.com/itzmeanjan/locatorz/blob/master/Screenshot_20190324-222400.png) 14 | ![ScreenShot 4](https://github.com/itzmeanjan/locatorz/blob/master/Screenshot_20190331-221646.png) 15 | ![ScreenShot 5](https://github.com/itzmeanjan/locatorz/blob/master/Screenshot_20190324-222432.png) 16 | 17 | 18 | ## Screen Recording :: 19 | You might be interested in checking out [this](https://github.com/itzmeanjan/locatorz/blob/master/recording.mp4) screen recording. 20 | 21 | ## Download :: 22 | 23 | - Latest version of App can be downloaded [here](https://github.com/itzmeanjan/locatorz/blob/master/locatorz.apk) :) 24 | 25 | 26 | Hope it was helpful. 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Anjan Roy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:trace_me/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/itzmeanjan/traceme/RouteDataManager.kt: -------------------------------------------------------------------------------- 1 | package com.example.itzmeanjan.traceme 2 | 3 | import androidx.room.* 4 | 5 | 6 | @Entity(tableName = "routes", primaryKeys = ["longitude", "latitude", "timeStamp"]) 7 | data class LocationData( 8 | @ColumnInfo(name = "longitude") var longitude: String, @ColumnInfo(name = "latitude") var latitude: String, @ColumnInfo(name = "timeStamp") var timeStamp: String, 9 | @ColumnInfo(name = "altitude") var altitude: String, 10 | @ColumnInfo(name = "routeId") var routeId: Int 11 | ) 12 | 13 | @Dao 14 | interface LocationDao{ 15 | 16 | @Insert(onConflict = OnConflictStrategy.REPLACE) 17 | fun insertData(vararg location: LocationData) 18 | 19 | @Delete 20 | fun deleteData(locationData: LocationData) 21 | 22 | @Query("select * from routes") 23 | fun getRoutes(): List 24 | 25 | @Query("select max(routeId) from routes") 26 | fun getLastUsedRouteId(): Int 27 | 28 | @Query("delete from routes") 29 | fun clearTables() 30 | } 31 | 32 | @Database(entities = [LocationData::class], version = 1) 33 | abstract class RouteDataManager: RoomDatabase(){ 34 | abstract fun locationDao(): LocationDao 35 | } 36 | -------------------------------------------------------------------------------- /lib/PlatformLevelLocationIssueHandler.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/services.dart'; 2 | import 'dart:async'; 3 | 4 | class PlatformLevelLocationIssueHandler { 5 | MethodChannel methodChannel; 6 | String methodChannelName; 7 | EventChannel eventChannel; 8 | String eventChannelName; 9 | PlatformLevelLocationIssueHandler(this.methodChannel, this.methodChannelName, 10 | this.eventChannel, this.eventChannelName); 11 | 12 | Future requestLocationPermission() async { 13 | // First Call it and check whether location permission is available or not 14 | bool result; 15 | try { 16 | await methodChannel 17 | .invokeMethod('requestLocationPermission') 18 | .then((dynamic value) { 19 | result = value == 1; 20 | }); 21 | } on PlatformException { 22 | // doing nothing useful yet 23 | result = false; 24 | } 25 | return result; 26 | } 27 | 28 | Future requestToEnableLocation() async { 29 | // After that you may call it to request user for enabling location 30 | bool result; 31 | try { 32 | await methodChannel.invokeMethod('enableLocation').then((dynamic value) { 33 | result = value == 1; 34 | }); 35 | } on PlatformException { 36 | result = false; 37 | } 38 | return result; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | trace_me 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /android/.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 19 | 23 | 30 | 34 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/itzmeanjan/traceme/FeatureDataManager.kt: -------------------------------------------------------------------------------- 1 | package com.example.itzmeanjan.traceme 2 | 3 | import androidx.room.* 4 | 5 | @Entity(tableName = "features", primaryKeys = ["featureId"]) 6 | data class FeatureData( 7 | @ColumnInfo(name = "featureId") var featureId: Int, 8 | @ColumnInfo(name = "featureName") var featureName: String, 9 | @ColumnInfo(name = "featureDescription") var featureDescription: String, 10 | @ColumnInfo(name = "featureType") var featureType: String 11 | ) 12 | 13 | @Entity(tableName = "featureLocation") 14 | data class FeatureLocationData( 15 | @PrimaryKey(autoGenerate = true) var featureLocationId: Int, 16 | @ColumnInfo(name = "featureId") var featureId: Int, 17 | @ColumnInfo(name = "longitude") var longitude: String, 18 | @ColumnInfo(name = "latitude") var latitude: String, 19 | @ColumnInfo(name = "altitude") var altitude: String, 20 | @ColumnInfo(name = "timeStamp") var timeStamp: String 21 | ) 22 | 23 | 24 | @Dao 25 | interface FeatureDao{ 26 | @Insert(onConflict = OnConflictStrategy.REPLACE) 27 | fun insertData(feature: FeatureData) 28 | 29 | @Query("select max(featureId) from features") 30 | fun getLastUsedFeatureId(): Int 31 | 32 | @Query("select * from features") 33 | fun getFeatures(): List 34 | 35 | @Query("select * from features where featureId = :featureId") 36 | fun getFeatureById(featureId: Int): FeatureData 37 | 38 | @Delete 39 | fun deleteFeature(feature: FeatureData) 40 | 41 | @Query("delete from features") 42 | fun clearTable() 43 | } 44 | 45 | @Dao 46 | interface FeatureLocationDao{ 47 | @Insert(onConflict = OnConflictStrategy.REPLACE) 48 | fun insertData(vararg featureLocation: FeatureLocationData) 49 | 50 | @Query("select * from featureLocation") 51 | fun getFeatureLocations(): List 52 | 53 | @Query("select * from featureLocation where featureId = :featureId") 54 | fun getFeatureLocationById(featureId: Int): List 55 | 56 | @Delete 57 | fun deleteFeatureLocation(featureLocation: FeatureLocationData) 58 | 59 | @Query("delete from featureLocation") 60 | fun clearTable() 61 | } 62 | 63 | @Database(entities = [FeatureData::class, FeatureLocationData::class], version = 1) 64 | abstract class FeatureDataManager: RoomDatabase(){ 65 | abstract fun getFeatureDao(): FeatureDao 66 | 67 | abstract fun getFeatureLocationDao(): FeatureLocationDao 68 | } -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.2.1' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply plugin: 'kotlin-kapt' 27 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 28 | 29 | android { 30 | signingConfigs { 31 | } 32 | compileSdkVersion 29 33 | sourceSets { 34 | main.java.srcDirs += 'src/main/kotlin' 35 | } 36 | lintOptions { 37 | disable 'InvalidPackage' 38 | } 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.example.itzmeanjan.traceme" 42 | minSdkVersion 16 43 | targetSdkVersion 29 44 | versionName '1.1.0' 45 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 46 | versionCode 2 47 | multiDexEnabled true 48 | } 49 | buildTypes { 50 | release { 51 | // TODO: Add your own signing config for the release build. 52 | // Signing with the debug keys for now, so `flutter run --release` works. 53 | signingConfig signingConfigs.debug 54 | } 55 | } 56 | buildToolsVersion '29.0.2' 57 | productFlavors { 58 | } 59 | compileOptions { 60 | sourceCompatibility = kotlin_version 61 | targetCompatibility = kotlin_version 62 | } 63 | } 64 | 65 | flutter { 66 | source '../..' 67 | } 68 | 69 | dependencies { 70 | implementation 'com.google.android.gms:play-services-location:17.0.0' 71 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 72 | testImplementation 'junit:junit:4.12' 73 | api 'androidx.core:core:1.1.0' 74 | api "android.arch.persistence.room:runtime:1.1.1" 75 | kapt "android.arch.persistence.room:compiler:1.1.1" 76 | } 77 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: trace_me 2 | description: A Simple Flutter App to work with Location Data ;) 3 | 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # Read more about versioning at semver.org. 10 | version: 1.2.1 11 | 12 | author: Anjan Roy 13 | 14 | repository: https://github.com/itzmeanjan/locatorz/ 15 | 16 | documentation: https://github.com/itzmeanjan/locatorz/blob/master/README.md 17 | 18 | environment: 19 | sdk: ">=2.0.0-dev.68.0 <3.0.0" 20 | 21 | dependencies: 22 | flutter: 23 | sdk: flutter 24 | 25 | # The following adds the Cupertino Icons font to your application. 26 | # Use with the CupertinoIcons class for iOS style icons. 27 | cupertino_icons: ^0.1.2 28 | 29 | dev_dependencies: 30 | flutter_test: 31 | sdk: flutter 32 | 33 | 34 | # For information on the generic Dart part of this file, see the 35 | # following page: https://www.dartlang.org/tools/pub/pubspec 36 | 37 | # The following section is specific to Flutter. 38 | flutter: 39 | 40 | # The following line ensures that the Material Icons font is 41 | # included with your application, so that you can use the icons in 42 | # the material Icons class. 43 | uses-material-design: true 44 | 45 | # To add assets to your application, add an assets section, like this: 46 | # assets: 47 | # - images/a_dot_burr.jpeg 48 | # - images/a_dot_ham.jpeg 49 | 50 | # An image asset can refer to one or more resolution-specific "variants", see 51 | # https://flutter.io/assets-and-images/#resolution-aware. 52 | 53 | # For details regarding adding assets from package dependencies, see 54 | # https://flutter.io/assets-and-images/#from-packages 55 | 56 | # To add custom fonts to your application, add a fonts section here, 57 | # in this "flutter" section. Each entry in this list should have a 58 | # "family" key with the font family name, and a "fonts" key with a 59 | # list giving the asset and other descriptors for the font. For 60 | # example: 61 | # fonts: 62 | # - family: Schyler 63 | # fonts: 64 | # - asset: fonts/Schyler-Regular.ttf 65 | # - asset: fonts/Schyler-Italic.ttf 66 | # style: italic 67 | # - family: Trajan Pro 68 | # fonts: 69 | # - asset: fonts/TrajanPro.ttf 70 | # - asset: fonts/TrajanPro_Bold.ttf 71 | # weight: 700 72 | # 73 | # For details regarding fonts from package dependencies, 74 | # see https://flutter.io/custom-fonts/#from-packages 75 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /lib/MyLocation.dart: -------------------------------------------------------------------------------- 1 | class MyLocation { 2 | MyLocation( 3 | this.longitude, 4 | this.latitude, 5 | this.time, 6 | this.altitude, 7 | this.bearing, 8 | this.speed, 9 | this.accuracy, 10 | this.verticalAccuracy, 11 | this.bearingAccuracy, 12 | this.speedAccuracy, 13 | this.provider, 14 | this.satelliteCount); 15 | double longitude; 16 | double latitude; 17 | DateTime time; 18 | double altitude; 19 | double bearing; 20 | double speed; 21 | double accuracy; 22 | double verticalAccuracy; 23 | double bearingAccuracy; 24 | double speedAccuracy; 25 | String provider; 26 | int satelliteCount; 27 | 28 | String getParsedTimeString() { 29 | if (this.time.isUtc) this.time = this.time.toLocal(); 30 | Map mapObj = { 31 | 'day': '${this.time.day}', 32 | 'month': '${this.time.month}', 33 | 'year': '${this.time.year}', 34 | 'hour': '${this.time.hour}', 35 | 'minute': '${this.time.minute}', 36 | 'second': '${this.time.second}', 37 | }; 38 | if (this.time.day < 10) { 39 | mapObj['day'] = '0${this.time.day}'; 40 | } 41 | if (this.time.month < 10) { 42 | mapObj['month'] = '0${this.time.month}'; 43 | } 44 | if (this.time.hour < 10) { 45 | mapObj['hour'] = '0${this.time.hour}'; 46 | } 47 | if (this.time.minute < 10) { 48 | mapObj['minute'] = '0${this.time.minute}'; 49 | } 50 | if (this.time.second < 10) { 51 | mapObj['second'] = '0${this.time.second}'; 52 | } 53 | return '${mapObj['day']}/${mapObj['month']}/${mapObj['year']} ${mapObj['hour']}:${mapObj['minute']}:${mapObj['second']}'; 54 | } 55 | 56 | double getSpeedInKiloMetersPerHour() { 57 | return (this.speed * 3600) / 1000; 58 | } 59 | 60 | double getSpeedAccuracyInKiloMetersPerHour() { 61 | return (this.speedAccuracy * 3600) / 1000; 62 | } 63 | 64 | String bearingToDirectionName() { 65 | Map tmpMap = { 66 | 0: 'North', 67 | 1: 'North North East', 68 | 2: 'North East', 69 | 3: 'East North East', 70 | 4: 'East', 71 | 5: 'East South East', 72 | 6: 'South East', 73 | 7: 'South South East', 74 | 8: 'South', 75 | 9: 'South South West', 76 | 10: 'South West', 77 | 11: 'West South West', 78 | 12: 'West', 79 | 13: 'West North West', 80 | 14: 'North West', 81 | 15: 'North North West' 82 | }; 83 | if (this.bearing != null) 84 | return tmpMap[ 85 | (((this.bearing + (360 / 16) / 2) % 360) / (360 / 16)).floor()]; 86 | return "NA"; 87 | } 88 | 89 | bool isBetterLocation(MyLocation location) { 90 | if ((this.longitude == null && this.latitude == null) && 91 | (location.longitude != null && location.latitude != null)) { 92 | return true; 93 | } 94 | try { 95 | if (location.accuracy < this.accuracy) if (location.time 96 | .isAfter(this.time)) return true; 97 | return false; 98 | } on Exception { 99 | return false; 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /lib/RouteToMap.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart'; 3 | import 'dart:ui'; 4 | 5 | class RouteToMap extends StatefulWidget { 6 | RouteToMap(this._points); 7 | final List> _points; 8 | 9 | @override 10 | _RouteToMapState createState() => _RouteToMapState(); 11 | } 12 | 13 | class _RouteToMapState extends State { 14 | @override 15 | void initState() { 16 | super.initState(); 17 | SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]); 18 | } 19 | 20 | @override 21 | void dispose() { 22 | super.dispose(); 23 | SystemChrome.setPreferredOrientations([ 24 | DeviceOrientation.landscapeLeft, 25 | DeviceOrientation.landscapeRight, 26 | DeviceOrientation.portraitDown, 27 | DeviceOrientation.portraitUp, 28 | ]); 29 | } 30 | 31 | double getMax(List data) { 32 | double max = -999; 33 | data.forEach((elem) => max = max < elem ? elem : max); 34 | return max; 35 | } 36 | 37 | double getMin(List data) { 38 | double min = 999; 39 | data.forEach((elem) => min = min > elem ? elem : min); 40 | return min; 41 | } 42 | 43 | @override 44 | Widget build(BuildContext context) { 45 | return Scaffold( 46 | appBar: AppBar( 47 | title: Text('Route To Map'), 48 | backgroundColor: Colors.cyanAccent, 49 | elevation: 16, 50 | ), 51 | body: Container( 52 | padding: EdgeInsets.all(20), 53 | color: Colors.black87, 54 | child: CustomPaint( 55 | painter: MyPainter( 56 | widget._points, 57 | getMax(widget._points.map((elem) => elem[0]).toList()) - 58 | getMin(widget._points.map((elem) => elem[0]).toList()), 59 | getMax(widget._points.map((elem) => elem[1]).toList()) - 60 | getMin(widget._points.map((elem) => elem[1]).toList())), 61 | size: Size.infinite, 62 | ), 63 | ), 64 | ); 65 | } 66 | } 67 | 68 | class MyPainter extends CustomPainter { 69 | MyPainter(this._points, this._width, this._height); 70 | 71 | List> _points; 72 | double _width; 73 | double _height; 74 | 75 | @override 76 | void paint(Canvas canvas, Size size) { 77 | /*var paint = Paint() 78 | ..style = PaintingStyle.stroke 79 | ..strokeWidth = .5 80 | ..color = Colors.cyanAccent 81 | ..strokeCap = StrokeCap.round;*/ 82 | var center = size.center(Offset(0, 0)); 83 | canvas.drawLine( 84 | size.centerLeft(Offset(0, 0)), 85 | size.centerRight(Offset(0, 0)), 86 | Paint() 87 | ..color = Colors.white 88 | ..strokeWidth = .2); 89 | canvas.drawLine( 90 | size.topCenter(Offset(0, 0)), 91 | size.bottomCenter(Offset(0, 0)), 92 | Paint() 93 | ..color = Colors.white 94 | ..strokeWidth = .2); 95 | var coordinates = _points 96 | .map((elem) => Offset( 97 | center.dx + elem[0] * (size.width / size.height), 98 | center.dy - elem[1] * (size.width / size.height), 99 | )) 100 | .toList(); 101 | canvas.drawPoints( 102 | PointMode.points, 103 | coordinates, 104 | Paint() 105 | ..style = PaintingStyle.stroke 106 | ..strokeWidth = 1 107 | ..color = Colors.redAccent 108 | ..strokeCap = StrokeCap.round); 109 | } 110 | 111 | @override 112 | bool shouldRepaint(CustomPainter oldDelegate) => true; 113 | } 114 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 77 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "2.3.0" 11 | boolean_selector: 12 | dependency: transitive 13 | description: 14 | name: boolean_selector 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "1.0.5" 18 | charcode: 19 | dependency: transitive 20 | description: 21 | name: charcode 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "1.1.2" 25 | collection: 26 | dependency: transitive 27 | description: 28 | name: collection 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "1.14.11" 32 | cupertino_icons: 33 | dependency: "direct main" 34 | description: 35 | name: cupertino_icons 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "0.1.2" 39 | flutter: 40 | dependency: "direct main" 41 | description: flutter 42 | source: sdk 43 | version: "0.0.0" 44 | flutter_test: 45 | dependency: "direct dev" 46 | description: flutter 47 | source: sdk 48 | version: "0.0.0" 49 | matcher: 50 | dependency: transitive 51 | description: 52 | name: matcher 53 | url: "https://pub.dartlang.org" 54 | source: hosted 55 | version: "0.12.5" 56 | meta: 57 | dependency: transitive 58 | description: 59 | name: meta 60 | url: "https://pub.dartlang.org" 61 | source: hosted 62 | version: "1.1.7" 63 | path: 64 | dependency: transitive 65 | description: 66 | name: path 67 | url: "https://pub.dartlang.org" 68 | source: hosted 69 | version: "1.6.4" 70 | pedantic: 71 | dependency: transitive 72 | description: 73 | name: pedantic 74 | url: "https://pub.dartlang.org" 75 | source: hosted 76 | version: "1.8.0+1" 77 | quiver: 78 | dependency: transitive 79 | description: 80 | name: quiver 81 | url: "https://pub.dartlang.org" 82 | source: hosted 83 | version: "2.0.5" 84 | sky_engine: 85 | dependency: transitive 86 | description: flutter 87 | source: sdk 88 | version: "0.0.99" 89 | source_span: 90 | dependency: transitive 91 | description: 92 | name: source_span 93 | url: "https://pub.dartlang.org" 94 | source: hosted 95 | version: "1.5.5" 96 | stack_trace: 97 | dependency: transitive 98 | description: 99 | name: stack_trace 100 | url: "https://pub.dartlang.org" 101 | source: hosted 102 | version: "1.9.3" 103 | stream_channel: 104 | dependency: transitive 105 | description: 106 | name: stream_channel 107 | url: "https://pub.dartlang.org" 108 | source: hosted 109 | version: "2.0.0" 110 | string_scanner: 111 | dependency: transitive 112 | description: 113 | name: string_scanner 114 | url: "https://pub.dartlang.org" 115 | source: hosted 116 | version: "1.0.5" 117 | term_glyph: 118 | dependency: transitive 119 | description: 120 | name: term_glyph 121 | url: "https://pub.dartlang.org" 122 | source: hosted 123 | version: "1.1.0" 124 | test_api: 125 | dependency: transitive 126 | description: 127 | name: test_api 128 | url: "https://pub.dartlang.org" 129 | source: hosted 130 | version: "0.2.5" 131 | typed_data: 132 | dependency: transitive 133 | description: 134 | name: typed_data 135 | url: "https://pub.dartlang.org" 136 | source: hosted 137 | version: "1.1.6" 138 | vector_math: 139 | dependency: transitive 140 | description: 141 | name: vector_math 142 | url: "https://pub.dartlang.org" 143 | source: hosted 144 | version: "2.0.8" 145 | sdks: 146 | dart: ">=2.2.2 <3.0.0" 147 | -------------------------------------------------------------------------------- /lib/RouteInfoHolder.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | class RouteInfoHolder { 4 | LocationDataChunk startLocation; 5 | double distanceCovered; // in kilometers 6 | List locationTrace; 7 | int duration; // in seconds 8 | double avgSpeed; // in km/h 9 | RouteInfoHolder(this.startLocation, this.locationTrace); 10 | 11 | void addNewLocationData(LocationDataChunk location) { 12 | locationTrace.add(location); 13 | } 14 | 15 | double getAverageSpeed() { 16 | double tmp = 0.0; 17 | int count = 0; 18 | locationTrace.forEach((LocationDataChunk elem) { 19 | tmp = tmp + elem.speed != null ? elem.speed : 0.0; 20 | count = count + elem.speed != null ? 1 : 0; 21 | }); 22 | return count == 0 ? tmp : tmp / count; 23 | } 24 | 25 | String getTimeSpentOnRoute() { 26 | String text = ''; 27 | if (this.duration > 60) { 28 | if (this.duration > 3600) { 29 | if (this.duration > 3600 * 24) { 30 | if (this.duration > 3600 * 24 * 7) { 31 | if (this.duration > 3600 * 24 * 7 * 52) 32 | text = 33 | '${this.duration ~/ 31449600}y ${(this.duration % 31449600) ~/ 604800}w ${((this.duration % 31449600) % 604800) ~/ 86400}d ${(((this.duration % 31449600) % 604800) % 86400) ~/ 3600}h ${((((this.duration % 31449600) % 604800) % 86400) % 3600) ~/ 60}m ${((((this.duration % 31449600) % 604800) % 86400) % 3600) % 60}s'; 34 | else 35 | text = 36 | '${this.duration ~/ 604800}w ${(this.duration % 604800) ~/ 86400}d ${((this.duration % 604800) % 86400) ~/ 3600}h ${(((this.duration % 604800) % 86400) % 3600) ~/ 60}m ${(((this.duration % 604800) % 86400) % 3600) % 60}s'; 37 | } else 38 | text = 39 | '${this.duration ~/ 86400}d ${(this.duration % 86400) ~/ 3600}h ${((this.duration % 86400) % 3600) ~/ 60}m ${((this.duration % 86400) % 3600) % 60}s'; 40 | } else 41 | text = 42 | '${this.duration ~/ 3600}h ${(this.duration % 3600) ~/ 60}m ${(this.duration % 3600) % 60}s'; 43 | } else 44 | text = '${this.duration ~/ 60}m ${this.duration % 60}s'; 45 | } else 46 | text = '${this.duration}s'; 47 | return text; 48 | } 49 | 50 | double calculateDistanceBetweenPoints( 51 | LocationDataChunk point1, LocationDataChunk point2) { 52 | try { 53 | double theta = point1.longitude - point2.longitude; 54 | double distance = 55 | sin(getRadian(point1.latitude)) * sin(getRadian(point2.latitude)) + 56 | cos(getRadian(point1.latitude)) * 57 | cos(getRadian(point2.latitude)) * 58 | cos(getRadian(theta)); 59 | distance = getDegree(acos(distance)) * 60 * 1.1515; 60 | return distance * 1.609344; 61 | } catch (e) { 62 | return 0.0; 63 | } 64 | } 65 | 66 | double getDistance() { 67 | double tmp = 0.0; 68 | if (locationTrace.length == 1) return tmp; 69 | for (int i = 1; i < locationTrace.length; i++) 70 | tmp += calculateDistanceBetweenPoints( 71 | locationTrace[i - 1], locationTrace[i]); 72 | return tmp; 73 | } 74 | 75 | double getRadian(double data) { 76 | // degree to radian converter 77 | return (data * pi) / 180.0; 78 | } 79 | 80 | double getDegree(double data) { 81 | // radian to degree converter 82 | return (data * 180.0) / pi; 83 | } 84 | } 85 | 86 | class LocationDataChunk { 87 | double longitude; 88 | double latitude; 89 | DateTime time; 90 | double altitude; 91 | double accuracy; 92 | double speed; // in km/h 93 | LocationDataChunk(this.longitude, this.latitude, this.time, this.altitude, 94 | this.accuracy, this.speed); 95 | 96 | String getParsedTimeString() { 97 | if (this.time.isUtc) this.time = this.time.toLocal(); 98 | Map mapObj = { 99 | 'day': '${this.time.day}', 100 | 'month': '${this.time.month}', 101 | 'year': '${this.time.year}', 102 | 'hour': '${this.time.hour}', 103 | 'minute': '${this.time.minute}', 104 | 'second': '${this.time.second}', 105 | }; 106 | if (this.time.day < 10) { 107 | mapObj['day'] = '0${this.time.day}'; 108 | } 109 | if (this.time.month < 10) { 110 | mapObj['month'] = '0${this.time.month}'; 111 | } 112 | if (this.time.hour < 10) { 113 | mapObj['hour'] = '0${this.time.hour}'; 114 | } 115 | if (this.time.minute < 10) { 116 | mapObj['minute'] = '0${this.time.minute}'; 117 | } 118 | if (this.time.second < 10) { 119 | mapObj['second'] = '0${this.time.second}'; 120 | } 121 | return '${mapObj['day']}/${mapObj['month']}/${mapObj['year']} ${mapObj['hour']}:${mapObj['minute']}:${mapObj['second']}'; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /android/trace_me_android.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /lib/SettingsPage.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'PlatformLevelLocationIssueHandler.dart'; 3 | 4 | class SettingsPage extends StatefulWidget { 5 | final PlatformLevelLocationIssueHandler 6 | platformLevelLocationIssueHandler; // used for invoking platform level methods, using MethodChannel 7 | 8 | SettingsPage({Key key, @required this.platformLevelLocationIssueHandler}) 9 | : super(key: key); 10 | 11 | @override 12 | _SettingsPageState createState() => _SettingsPageState(); 13 | } 14 | 15 | class _SettingsPageState extends State { 16 | int useLocationDataFrom; // used for holding current selection 17 | 18 | @override 19 | void initState() { 20 | super.initState(); 21 | widget.platformLevelLocationIssueHandler.methodChannel 22 | .invokeMethod("fetchLocationDataSourcePreference") 23 | .then((dynamic val) { 24 | if (val.toString().isNotEmpty) { 25 | setState(() { 26 | useLocationDataFrom = int.parse(val.toString(), radix: 10); 27 | }); 28 | } 29 | }); 30 | } 31 | 32 | @override 33 | void dispose() async { 34 | if (useLocationDataFrom != null) 35 | await widget.platformLevelLocationIssueHandler.methodChannel.invokeMethod( 36 | "storeLocationDataSourcePreference", { 37 | "locationDataSourcePreference": useLocationDataFrom.toString() 38 | }); 39 | // add more code here ... 40 | super.dispose(); 41 | } 42 | 43 | @override 44 | Widget build(BuildContext context) { 45 | return Scaffold( 46 | appBar: AppBar( 47 | title: Text( 48 | 'Settings', 49 | style: TextStyle(color: Colors.black87), 50 | ), 51 | elevation: 8, 52 | backgroundColor: Colors.cyanAccent, 53 | ), 54 | body: ListView( 55 | padding: EdgeInsets.all(10), 56 | children: [ 57 | Card( 58 | elevation: 16.0, 59 | margin: 60 | EdgeInsets.only(left: 3.0, right: 3.0, top: 12.0, bottom: 12.0), 61 | child: Column( 62 | mainAxisSize: MainAxisSize.min, 63 | children: [ 64 | Divider( 65 | color: Colors.white, 66 | height: 20.0, 67 | ), 68 | Row( 69 | mainAxisAlignment: MainAxisAlignment.center, 70 | mainAxisSize: MainAxisSize.min, 71 | children: [ 72 | Text( 73 | ":: Settings ::", 74 | style: TextStyle( 75 | letterSpacing: 2.0, 76 | fontWeight: FontWeight.bold, 77 | ), 78 | ), 79 | ], 80 | ), 81 | Container( 82 | padding: EdgeInsets.all(8.0), 83 | margin: 84 | EdgeInsets.only(left: 8, right: 8, top: 12, bottom: 12), 85 | decoration: BoxDecoration( 86 | borderRadius: BorderRadius.circular(18.0), 87 | border: Border.all( 88 | color: Colors.tealAccent.shade400, 89 | width: 0.2, 90 | style: BorderStyle.solid), 91 | gradient: LinearGradient( 92 | colors: [Colors.cyanAccent, Colors.tealAccent], 93 | begin: Alignment.topLeft, 94 | end: Alignment.bottomRight), 95 | ), 96 | child: Column( 97 | mainAxisSize: MainAxisSize.min, 98 | children: [ 99 | Divider( 100 | color: Colors.white, 101 | height: 10.0, 102 | ), 103 | Row( 104 | mainAxisAlignment: MainAxisAlignment.start, 105 | mainAxisSize: MainAxisSize.min, 106 | children: [ 107 | Text( 108 | "Which one would you like me to use ?", 109 | style: TextStyle( 110 | fontStyle: FontStyle.italic, 111 | ), 112 | ) 113 | ], 114 | ), 115 | Divider( 116 | color: Colors.white30, 117 | height: 20.0, 118 | ), 119 | Row( 120 | mainAxisSize: MainAxisSize.min, 121 | children: [ 122 | Radio( 123 | value: 1, 124 | activeColor: Colors.blueAccent, 125 | groupValue: useLocationDataFrom, 126 | onChanged: (int val) => setState(() { 127 | useLocationDataFrom = val; 128 | }), 129 | ), 130 | Text("android.location.Location based Location"), 131 | ], 132 | ), 133 | Row( 134 | mainAxisSize: MainAxisSize.min, 135 | children: [ 136 | Radio( 137 | value: 0, 138 | activeColor: Colors.blueAccent, 139 | groupValue: useLocationDataFrom, 140 | onChanged: (int val) => setState(() { 141 | useLocationDataFrom = val; 142 | }), 143 | ), 144 | Text("Google Mobile Services based Location"), 145 | ], 146 | ), 147 | ], 148 | ), 149 | ), 150 | ], 151 | ), 152 | ), 153 | ], 154 | ), 155 | ); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/itzmeanjan/traceme/LocationDataHolder.kt: -------------------------------------------------------------------------------- 1 | package com.example.itzmeanjan.traceme 2 | 3 | import android.location.Location 4 | import android.os.Build 5 | import com.google.android.gms.location.LocationCallback 6 | import android.location.LocationListener 7 | import android.os.Bundle 8 | import com.google.android.gms.location.LocationResult 9 | import io.flutter.plugin.common.EventChannel 10 | 11 | data class LocationDataHolder(var longitude: Double, var latitude: Double, var time: Long, var altitude: Double?, var bearing: Float?, var speed: Float?, var accuracy: Float?, var verticalAccuracy: Float?, var bearingAccuracy: Float?, var speedAccuracy: Float?, var provider: String?, var satelliteCount: Int?) 12 | 13 | class MyLocationCallBack(eventSink: EventChannel.EventSink): LocationCallback(){ 14 | private val event = eventSink 15 | override fun onLocationResult(p0: LocationResult?) { 16 | if(p0!=null){ 17 | for (location in p0.locations){ 18 | val locationDataHolder = LocationDataHolder(location.longitude,location.latitude,location.time,null,null,null,null,null,null,null,null,null) 19 | if(location.hasAltitude()) 20 | locationDataHolder.altitude = location.altitude 21 | if(location.hasBearing()) 22 | locationDataHolder.bearing = location.bearing 23 | if(location.hasSpeed()) 24 | locationDataHolder.speed = location.speed 25 | if(location.hasAccuracy()) 26 | locationDataHolder.accuracy = location.accuracy 27 | if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.O){ 28 | if(location.hasVerticalAccuracy()) 29 | locationDataHolder.verticalAccuracy = location.verticalAccuracyMeters 30 | if(location.hasBearingAccuracy()) 31 | locationDataHolder.bearingAccuracy = location.bearingAccuracyDegrees 32 | if(location.hasSpeedAccuracy()) 33 | locationDataHolder.speedAccuracy = location.speedAccuracyMetersPerSecond 34 | } 35 | if(location.provider!=null) 36 | locationDataHolder.provider = location.provider 37 | if(location.extras!=null) 38 | locationDataHolder.satelliteCount = location.extras.getInt("satellites",0) 39 | event.success( 40 | mapOf( 41 | "longitude" to locationDataHolder.longitude, 42 | "latitude" to locationDataHolder.latitude, 43 | "time" to locationDataHolder.time, 44 | "altitude" to locationDataHolder.altitude, 45 | "bearing" to locationDataHolder.bearing, 46 | "speed" to locationDataHolder.speed, 47 | "accuracy" to locationDataHolder.accuracy, 48 | "verticalAccuracy" to locationDataHolder.verticalAccuracy, 49 | "bearingAccuracy" to locationDataHolder.bearingAccuracy, 50 | "speedAccuracy" to locationDataHolder.speedAccuracy, 51 | "provider" to locationDataHolder.provider, 52 | "satelliteCount" to locationDataHolder.satelliteCount 53 | ) 54 | ) 55 | } 56 | } 57 | } 58 | } 59 | 60 | class MyLocationListener(eventSink: EventChannel.EventSink): LocationListener{ 61 | private val event = eventSink 62 | override fun onProviderDisabled(provider: String?) { 63 | } 64 | 65 | override fun onProviderEnabled(provider: String?) { 66 | } 67 | 68 | override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) { 69 | } 70 | 71 | override fun onLocationChanged(location: Location?) { 72 | if(location!=null){ 73 | val locationDataHolder = LocationDataHolder(location.longitude,location.latitude,location.time,null,null,null,null,null,null,null,null,null) 74 | if(location.hasAltitude()) 75 | locationDataHolder.altitude = location.altitude 76 | if(location.hasBearing()) 77 | locationDataHolder.bearing = location.bearing 78 | if(location.hasSpeed()) 79 | locationDataHolder.speed = location.speed 80 | if(location.hasAccuracy()) 81 | locationDataHolder.accuracy = location.accuracy 82 | if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.O){ 83 | if(location.hasVerticalAccuracy()) 84 | locationDataHolder.verticalAccuracy = location.verticalAccuracyMeters 85 | if(location.hasBearingAccuracy()) 86 | locationDataHolder.bearingAccuracy = location.bearingAccuracyDegrees 87 | if(location.hasSpeedAccuracy()) 88 | locationDataHolder.speedAccuracy = location.speedAccuracyMetersPerSecond 89 | } 90 | if(location.provider!=null) 91 | locationDataHolder.provider = location.provider 92 | if(location.extras!=null) 93 | locationDataHolder.satelliteCount = location.extras.getInt("satellites",0) 94 | event.success( 95 | mapOf( 96 | "longitude" to locationDataHolder.longitude, 97 | "latitude" to locationDataHolder.latitude, 98 | "time" to locationDataHolder.time, 99 | "altitude" to locationDataHolder.altitude, 100 | "bearing" to locationDataHolder.bearing, 101 | "speed" to locationDataHolder.speed, 102 | "accuracy" to locationDataHolder.accuracy, 103 | "verticalAccuracy" to locationDataHolder.verticalAccuracy, 104 | "bearingAccuracy" to locationDataHolder.bearingAccuracy, 105 | "speedAccuracy" to locationDataHolder.speedAccuracy, 106 | "provider" to locationDataHolder.provider, 107 | "satelliteCount" to locationDataHolder.satelliteCount 108 | ) 109 | ) 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /android/.idea/assetWizardSettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 147 | 148 | -------------------------------------------------------------------------------- /android/app/src/main/main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /lib/MyAppHome.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart'; 3 | import 'MyLocation.dart'; 4 | import 'PlatformLevelLocationIssueHandler.dart'; 5 | import 'FeatureCollector.dart'; 6 | import 'RouteTracker.dart'; 7 | import 'SettingsPage.dart'; 8 | 9 | class MyAppHome extends StatefulWidget { 10 | @override 11 | _MyAppHomeState createState() => _MyAppHomeState(); 12 | } 13 | 14 | class _MyAppHomeState extends State { 15 | MyLocation currentLocator = MyLocation( 16 | null, null, null, null, null, null, null, null, null, null, null, null); 17 | final String eventChannelName = 18 | 'com.example.itzmeanjan.traceme.locationUpdateEventChannel'; 19 | final String methodChannelName = 20 | 'com.example.itzmeanjan.traceme.locationUpdateMethodChannel'; 21 | bool _areWeGettingLocationUpdates = false; 22 | PlatformLevelLocationIssueHandler platformLevelLocationIssueHandler; 23 | 24 | @override 25 | void initState() { 26 | super.initState(); 27 | platformLevelLocationIssueHandler = PlatformLevelLocationIssueHandler( 28 | MethodChannel(methodChannelName), 29 | methodChannelName, 30 | null, 31 | eventChannelName); 32 | } 33 | 34 | @override 35 | void dispose() { 36 | // ends location listening service, while disposing app 37 | if (_areWeGettingLocationUpdates) { 38 | platformLevelLocationIssueHandler.methodChannel.invokeMethod( 39 | "stopLocationUpdate"); // calling platform level method, which is defined in MainActivity.kt 40 | } 41 | _areWeGettingLocationUpdates = false; 42 | platformLevelLocationIssueHandler = null; 43 | super.dispose(); 44 | } 45 | 46 | void _onData(dynamic event) { 47 | setState(() { 48 | extractLocationData(event); 49 | }); 50 | } 51 | 52 | void _onError(dynamic error) { 53 | setState(() { 54 | _areWeGettingLocationUpdates = false; 55 | }); 56 | } 57 | 58 | void extractLocationData(dynamic event) { 59 | currentLocator.longitude = event['longitude']; 60 | currentLocator.latitude = event['latitude']; 61 | currentLocator.time = 62 | DateTime.fromMillisecondsSinceEpoch(event['time'], isUtc: true); 63 | currentLocator.altitude = event['altitude']; 64 | currentLocator.bearing = event['bearing']; 65 | currentLocator.speed = event['speed']; 66 | currentLocator.accuracy = event['accuracy']; 67 | currentLocator.verticalAccuracy = event['verticalAccuracy']; 68 | currentLocator.bearingAccuracy = event['bearingAccuracy']; 69 | currentLocator.speedAccuracy = event['speedAccuracy']; 70 | currentLocator.provider = event['provider']; 71 | currentLocator.satelliteCount = event['satelliteCount']; 72 | } 73 | 74 | void requestLocationUpdate() { 75 | platformLevelLocationIssueHandler 76 | .requestLocationPermission() 77 | .then((bool result) { 78 | if (result) { 79 | platformLevelLocationIssueHandler 80 | .requestToEnableLocation() 81 | .then((bool resp) async { 82 | if (resp) { 83 | platformLevelLocationIssueHandler.eventChannel = 84 | EventChannel(eventChannelName); 85 | await platformLevelLocationIssueHandler.methodChannel 86 | .invokeMethod("fetchLocationDataSourcePreference") 87 | .then((dynamic id) async { 88 | // trying to fetch user preferred way for retrieving Device Location. This preference is stored in SharedPreference . 89 | await platformLevelLocationIssueHandler.methodChannel 90 | .invokeMethod("startLocationUpdate", { 91 | "id": id.toString().isNotEmpty ? id.toString() : "1" 92 | }) // 0 -> google play service based location update request 93 | // 1 -> android platform based location update, from android.hardware.gps 94 | .then((dynamic value) { 95 | if (value == 1) { 96 | platformLevelLocationIssueHandler.eventChannel 97 | .receiveBroadcastStream() 98 | .listen(_onData, onError: _onError); 99 | setState(() { 100 | _areWeGettingLocationUpdates = true; 101 | }); 102 | } 103 | }); 104 | }); 105 | } 106 | }); 107 | } 108 | }); 109 | } 110 | 111 | void stopLocationUpdate() { 112 | platformLevelLocationIssueHandler.methodChannel 113 | .invokeMethod("stopLocationUpdate") 114 | .then((dynamic value) { 115 | if (value == 1) { 116 | platformLevelLocationIssueHandler.eventChannel = null; 117 | setState(() { 118 | _areWeGettingLocationUpdates = false; 119 | }); 120 | } 121 | }); 122 | } 123 | 124 | @override 125 | Widget build(BuildContext context) { 126 | return Scaffold( 127 | drawer: Drawer( 128 | child: ListView( 129 | children: [ 130 | DrawerHeader( 131 | decoration: BoxDecoration( 132 | color: Colors.cyanAccent, 133 | ), 134 | child: Container( 135 | child: Align( 136 | alignment: AlignmentDirectional.center, 137 | child: Text( 138 | "Locatorz", 139 | textScaleFactor: 1.5, 140 | style: TextStyle( 141 | letterSpacing: 4.0, 142 | fontSize: 20.0, 143 | color: Colors.black, 144 | ), 145 | ), 146 | )), 147 | ), 148 | ListTile( 149 | title: Text( 150 | 'Feature Collector', 151 | ), 152 | leading: Icon(Icons.add), 153 | onTap: () { 154 | if (_areWeGettingLocationUpdates) stopLocationUpdate(); 155 | Navigator.push(context, MaterialPageRoute(builder: (context) { 156 | return FeatureCollectorHome( 157 | location: this.currentLocator, 158 | platformLevelLocationIssueHandler: 159 | platformLevelLocationIssueHandler, 160 | ); 161 | })); 162 | }, 163 | ), 164 | ListTile( 165 | title: Text( 166 | 'Route Tracker', 167 | ), 168 | leading: Icon(Icons.directions), 169 | onTap: () { 170 | if (_areWeGettingLocationUpdates) stopLocationUpdate(); 171 | Navigator.push(context, MaterialPageRoute(builder: (context) { 172 | return RouteTrackerHome( 173 | location: this.currentLocator, 174 | platformLevelLocationIssueHandler: 175 | platformLevelLocationIssueHandler, 176 | ); 177 | })); 178 | }, 179 | ), 180 | ListTile( 181 | title: Text( 182 | 'Settings', 183 | ), 184 | leading: Icon(Icons.settings), 185 | onTap: () { 186 | if (_areWeGettingLocationUpdates) stopLocationUpdate(); 187 | Navigator.push(context, MaterialPageRoute(builder: (context) { 188 | return SettingsPage( 189 | platformLevelLocationIssueHandler: 190 | platformLevelLocationIssueHandler, 191 | ); 192 | })); 193 | }, 194 | ), 195 | ], 196 | ), 197 | ), 198 | appBar: AppBar( 199 | title: Text( 200 | 'Locatorz', 201 | style: TextStyle( 202 | color: Colors.black87, 203 | ), 204 | ), 205 | elevation: 12, 206 | backgroundColor: Colors.cyanAccent, 207 | ), 208 | body: Center( 209 | child: Card( 210 | elevation: 16.0, 211 | margin: EdgeInsets.all(12), 212 | child: Container( 213 | margin: EdgeInsets.all(4.0), 214 | padding: EdgeInsets.all(10.0), 215 | decoration: BoxDecoration( 216 | borderRadius: BorderRadius.circular(10.0), 217 | gradient: LinearGradient( 218 | colors: [Colors.cyanAccent, Colors.tealAccent], 219 | begin: Alignment.topLeft, 220 | end: Alignment.bottomRight), 221 | border: Border.all( 222 | width: 0.35, style: BorderStyle.solid, color: Colors.white70), 223 | ), 224 | child: Column( 225 | mainAxisSize: MainAxisSize.min, 226 | children: [ 227 | Row( 228 | mainAxisAlignment: MainAxisAlignment.center, 229 | children: [ 230 | Text( 231 | 'Location Info', 232 | textScaleFactor: 1.0, 233 | style: TextStyle( 234 | fontStyle: FontStyle.italic, 235 | letterSpacing: 4, 236 | fontWeight: FontWeight.bold, 237 | fontSize: 22, 238 | shadows: [ 239 | Shadow( 240 | color: Colors.grey, 241 | offset: Offset(1.6, 1.6), 242 | ), 243 | ]), 244 | ), 245 | ], 246 | ), 247 | Divider( 248 | height: 20.0, 249 | color: Colors.black26, 250 | ), 251 | Row( 252 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 253 | children: [ 254 | Text('Longitude', 255 | style: TextStyle(fontStyle: FontStyle.italic)), 256 | VerticalDivider(), 257 | Text(currentLocator.longitude != null 258 | ? '${currentLocator.longitude}' 259 | : 'NA'), 260 | ], 261 | ), 262 | Divider( 263 | height: 10.0, 264 | color: Colors.white, 265 | ), 266 | Row( 267 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 268 | children: [ 269 | Text('Latitude', 270 | style: TextStyle(fontStyle: FontStyle.italic)), 271 | VerticalDivider(), 272 | Text(currentLocator.latitude != null 273 | ? '${currentLocator.latitude}' 274 | : 'NA'), 275 | ], 276 | ), 277 | Divider( 278 | height: 10.0, 279 | color: Colors.white, 280 | ), 281 | Row( 282 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 283 | children: [ 284 | Text('Altitude', 285 | style: TextStyle(fontStyle: FontStyle.italic)), 286 | VerticalDivider(), 287 | Text(currentLocator.altitude != null 288 | ? '${currentLocator.altitude} m' 289 | : 'NA'), 290 | ], 291 | ), 292 | Divider( 293 | height: 10.0, 294 | color: Colors.white, 295 | ), 296 | Row( 297 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 298 | children: [ 299 | Text('Bearing', 300 | style: TextStyle(fontStyle: FontStyle.italic)), 301 | VerticalDivider(), 302 | Text(currentLocator.bearing != null 303 | ? 'along ${currentLocator.bearingToDirectionName()}' 304 | : 'NA') 305 | ], 306 | ), 307 | Divider( 308 | height: 10.0, 309 | color: Colors.white, 310 | ), 311 | Row( 312 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 313 | children: [ 314 | Text('Speed', style: TextStyle(fontStyle: FontStyle.italic)), 315 | VerticalDivider(), 316 | Text(currentLocator.speed != null 317 | ? '${currentLocator.getSpeedInKiloMetersPerHour()} kmph' 318 | : 'NA'), 319 | ], 320 | ), 321 | Divider( 322 | height: 10.0, 323 | color: Colors.white, 324 | ), 325 | Row( 326 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 327 | children: [ 328 | Text('Accuracy', 329 | style: TextStyle(fontStyle: FontStyle.italic)), 330 | VerticalDivider(), 331 | Text(currentLocator.accuracy != null 332 | ? '${currentLocator.accuracy} m' 333 | : 'NA'), 334 | ], 335 | ), 336 | Divider( 337 | height: 10.0, 338 | color: Colors.white, 339 | ), 340 | Row( 341 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 342 | children: [ 343 | Text('Vertical Accuracy', 344 | style: TextStyle(fontStyle: FontStyle.italic)), 345 | VerticalDivider(), 346 | Text(currentLocator.verticalAccuracy != null 347 | ? '${currentLocator.verticalAccuracy} m' 348 | : 'NA'), 349 | ], 350 | ), 351 | Divider( 352 | height: 10.0, 353 | color: Colors.white, 354 | ), 355 | Row( 356 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 357 | children: [ 358 | Text('Bearing Accuracy', 359 | style: TextStyle(fontStyle: FontStyle.italic)), 360 | VerticalDivider(), 361 | Text(currentLocator.bearingAccuracy != null 362 | ? '${currentLocator.bearingAccuracy}' 363 | : 'NA'), 364 | ], 365 | ), 366 | Divider( 367 | height: 10.0, 368 | color: Colors.white, 369 | ), 370 | Row( 371 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 372 | children: [ 373 | Text('Speed Accuracy', 374 | style: TextStyle(fontStyle: FontStyle.italic)), 375 | VerticalDivider(), 376 | Text(currentLocator.speedAccuracy != null 377 | ? '${currentLocator.getSpeedAccuracyInKiloMetersPerHour()} kmph' 378 | : 'NA'), 379 | ], 380 | ), 381 | Divider( 382 | height: 10.0, 383 | color: Colors.white, 384 | ), 385 | Row( 386 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 387 | children: [ 388 | Text('Provider', 389 | style: TextStyle(fontStyle: FontStyle.italic)), 390 | VerticalDivider(), 391 | Text(currentLocator.provider != null 392 | ? '${currentLocator.provider.toUpperCase()}' 393 | : 'NA'), 394 | ], 395 | ), 396 | Divider( 397 | height: 10.0, 398 | color: Colors.white, 399 | ), 400 | Row( 401 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 402 | children: [ 403 | Text('Satellite Count', 404 | style: TextStyle(fontStyle: FontStyle.italic)), 405 | VerticalDivider(), 406 | Text(currentLocator.satelliteCount != null 407 | ? '${currentLocator.satelliteCount}' 408 | : 'NA'), 409 | ], 410 | ), 411 | Divider( 412 | height: 10.0, 413 | color: Colors.white, 414 | ), 415 | Row( 416 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 417 | children: [ 418 | Text('TimeStamp', 419 | style: TextStyle(fontStyle: FontStyle.italic)), 420 | VerticalDivider(), 421 | Text(currentLocator.time != null 422 | ? currentLocator.getParsedTimeString() 423 | : 'NA'), 424 | ], 425 | ), 426 | Divider( 427 | height: 6.0, 428 | color: Colors.white, 429 | ), 430 | ], 431 | ), 432 | ), 433 | )), 434 | floatingActionButton: FloatingActionButton( 435 | highlightElevation: 4.0, 436 | onPressed: !_areWeGettingLocationUpdates 437 | ? requestLocationUpdate 438 | : stopLocationUpdate, 439 | tooltip: !_areWeGettingLocationUpdates 440 | ? 'Request Location Update' 441 | : 'Stop Location Update', 442 | child: !_areWeGettingLocationUpdates 443 | ? Icon( 444 | Icons.my_location, 445 | color: Colors.white, 446 | ) 447 | : Icon( 448 | Icons.stop, 449 | color: Colors.white, 450 | ), 451 | backgroundColor: 452 | !_areWeGettingLocationUpdates ? Colors.cyanAccent : Colors.red, 453 | ), 454 | ); 455 | } 456 | } 457 | -------------------------------------------------------------------------------- /lib/FeatureCollector.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'MyLocation.dart'; 3 | import 'PlatformLevelLocationIssueHandler.dart'; 4 | import 'NewFeatureEntryMaker.dart'; 5 | import 'dart:async'; 6 | 7 | class FeatureCollectorHome extends StatefulWidget { 8 | final MyLocation location; 9 | final PlatformLevelLocationIssueHandler platformLevelLocationIssueHandler; 10 | 11 | FeatureCollectorHome( 12 | {Key key, 13 | @required this.location, 14 | @required this.platformLevelLocationIssueHandler}) 15 | : super(key: key); 16 | 17 | @override 18 | _FeatureCollectorState createState() => _FeatureCollectorState(); 19 | } 20 | 21 | class _FeatureCollectorState extends State { 22 | Future>>> myFeatures; 23 | int featureCount = 0; 24 | 25 | @override 26 | void initState() { 27 | super.initState(); 28 | myFeatures = getFeatures(); 29 | myFeatures.then((Map>> val) { 30 | setState(() { 31 | featureCount = val.keys.toList().length; 32 | }); 33 | }); 34 | } 35 | 36 | Future>>> getFeatures() async { 37 | return await widget.platformLevelLocationIssueHandler.methodChannel 38 | .invokeMethod("getFeatures") 39 | .then((dynamic val) { 40 | Map>> features = {}; 41 | Map.from(val).forEach((String key, dynamic value) { 42 | List> tmpList = []; 43 | List.from(value).forEach((dynamic elem) { 44 | tmpList.add(Map.from(elem)); 45 | }); 46 | features[key] = tmpList; 47 | }); 48 | return features; 49 | }); 50 | } 51 | 52 | List layoutInflater( 53 | String featureId, List> element) { 54 | return [ 55 | Row( 56 | mainAxisAlignment: MainAxisAlignment.start, 57 | children: [ 58 | Text( 59 | 'FeatureId :: ', 60 | style: TextStyle( 61 | letterSpacing: 3.0, 62 | ), 63 | ), 64 | Text( 65 | '$featureId', 66 | style: TextStyle(color: Colors.red, fontStyle: FontStyle.italic), 67 | ), 68 | ], 69 | ), 70 | Container( 71 | margin: EdgeInsets.all(8.0), 72 | padding: 73 | EdgeInsets.only(left: 12.0, right: 12.0, top: 8.0, bottom: 8.0), 74 | decoration: BoxDecoration( 75 | gradient: LinearGradient( 76 | colors: [Colors.cyan, Colors.teal], 77 | begin: Alignment.bottomRight, 78 | end: Alignment.topLeft), 79 | borderRadius: BorderRadius.circular(15), 80 | ), 81 | child: Column( 82 | mainAxisSize: MainAxisSize.min, 83 | children: [ 84 | Row( 85 | children: [ 86 | Expanded( 87 | child: Text( 88 | '${element[0]["featureName"]}', 89 | textAlign: TextAlign.left, 90 | ), 91 | ), 92 | VerticalDivider( 93 | width: 6, 94 | ), 95 | Expanded( 96 | child: Text( 97 | '${{ 98 | "0": "Point", 99 | "1": "Line", 100 | "2": "Polygon" 101 | }[element[0]["featureType"]] ?? "NA"}', 102 | textAlign: TextAlign.right, 103 | ), 104 | ), 105 | ], 106 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 107 | ), 108 | ], 109 | ), 110 | ), 111 | Container( 112 | margin: EdgeInsets.all(8.0), 113 | padding: 114 | EdgeInsets.only(left: 12.0, right: 12.0, top: 8.0, bottom: 8.0), 115 | decoration: BoxDecoration( 116 | gradient: LinearGradient( 117 | colors: [Colors.teal, Colors.greenAccent], 118 | begin: Alignment.bottomRight, 119 | end: Alignment.topLeft), 120 | borderRadius: BorderRadius.circular(15), 121 | ), 122 | child: Column( 123 | mainAxisSize: MainAxisSize.min, 124 | children: [ 125 | ExpansionTile( 126 | trailing: Icon( 127 | Icons.arrow_drop_down, 128 | color: Colors.white, 129 | ), 130 | title: Text( 131 | "Feature Description", 132 | style: 133 | TextStyle(letterSpacing: 2.0, fontStyle: FontStyle.italic), 134 | ), 135 | initiallyExpanded: false, 136 | children: [ 137 | Container( 138 | margin: EdgeInsets.all(8.0), 139 | padding: EdgeInsets.all(10.0), 140 | decoration: BoxDecoration( 141 | borderRadius: BorderRadius.circular(15), 142 | color: Colors.lightBlueAccent.shade100, 143 | border: Border.all( 144 | color: Colors.white, 145 | style: BorderStyle.solid, 146 | width: 0.15), 147 | ), 148 | child: Text.rich( 149 | TextSpan( 150 | text: '${element[0]["featureDescription"]}', 151 | ), 152 | ), 153 | ), 154 | ], 155 | ), 156 | ], 157 | ), 158 | ), 159 | Container( 160 | margin: EdgeInsets.all(8.0), 161 | padding: 162 | EdgeInsets.only(left: 12.0, right: 12.0, top: 8.0, bottom: 8.0), 163 | decoration: BoxDecoration( 164 | gradient: LinearGradient( 165 | colors: [Colors.teal, Colors.greenAccent], 166 | begin: Alignment.bottomRight, 167 | end: Alignment.topLeft), 168 | borderRadius: BorderRadius.circular(15), 169 | ), 170 | child: Column( 171 | mainAxisSize: MainAxisSize.min, 172 | children: [ 173 | ExpansionTile( 174 | trailing: Icon( 175 | Icons.arrow_drop_down, 176 | color: Colors.white, 177 | ), 178 | title: Text( 179 | "Coordinate(s)", 180 | style: 181 | TextStyle(letterSpacing: 2.0, fontStyle: FontStyle.italic), 182 | ), 183 | initiallyExpanded: false, 184 | children: element.map((Map elem) { 185 | return Container( 186 | margin: EdgeInsets.all(8.0), 187 | padding: EdgeInsets.all(10.0), 188 | decoration: BoxDecoration( 189 | gradient: LinearGradient( 190 | colors: [Colors.white12, Colors.blueGrey], 191 | begin: Alignment.bottomRight, 192 | end: Alignment.topLeft), 193 | borderRadius: BorderRadius.circular(15), 194 | ), 195 | child: Column( 196 | mainAxisSize: MainAxisSize.min, 197 | children: [ 198 | Row( 199 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 200 | children: [ 201 | Text( 202 | 'Longitude', 203 | ), 204 | Text( 205 | '${elem["longitude"]}', 206 | ), 207 | ], 208 | ), 209 | Divider( 210 | height: 6, 211 | ), 212 | Row( 213 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 214 | children: [ 215 | Text( 216 | 'Latitude', 217 | ), 218 | Text( 219 | '${elem["latitude"]}', 220 | ), 221 | ], 222 | ), 223 | Divider( 224 | height: 6, 225 | ), 226 | Row( 227 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 228 | children: [ 229 | Text( 230 | 'Altitude', 231 | ), 232 | Text( 233 | '${elem["altitude"]} m', 234 | ), 235 | ], 236 | ), 237 | Divider( 238 | height: 6, 239 | ), 240 | Row( 241 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 242 | children: [ 243 | Text( 244 | 'Time of Data Collection', 245 | ), 246 | Text( 247 | '${elem["timeStamp"]}', 248 | ), 249 | ], 250 | ), 251 | ], 252 | ), 253 | ); 254 | }).toList(), 255 | ), 256 | ], 257 | ), 258 | ), 259 | ]; 260 | } 261 | 262 | @override 263 | Widget build(BuildContext context) { 264 | return Scaffold( 265 | appBar: AppBar( 266 | title: Text( 267 | 'Feature Collector', 268 | style: TextStyle(color: Colors.black87), 269 | ), 270 | elevation: 12, 271 | backgroundColor: Colors.cyanAccent, 272 | actions: [ 273 | Builder( 274 | builder: (BuildContext ctx) { 275 | return IconButton( 276 | icon: Icon( 277 | Icons.delete, 278 | color: Colors.white, 279 | ), 280 | onPressed: featureCount != 0 281 | ? () { 282 | showDialog( 283 | builder: (BuildContext context) { 284 | return AlertDialog( 285 | title: Text("Clear Records"), 286 | elevation: 14.0, 287 | content: Text( 288 | "Do you want me to clear all Saved Features ?", 289 | ), 290 | actions: [ 291 | RaisedButton( 292 | child: Text( 293 | "Yes", 294 | style: TextStyle(color: Colors.black), 295 | ), 296 | onPressed: () => Navigator.of(ctx).pop(true), 297 | color: Colors.tealAccent, 298 | ), 299 | RaisedButton( 300 | child: Text( 301 | "No", 302 | style: TextStyle(color: Colors.black), 303 | ), 304 | color: Colors.tealAccent, 305 | onPressed: () => Navigator.of(ctx).pop(false), 306 | ), 307 | ], 308 | ); 309 | }, 310 | context: context, 311 | ).then((dynamic value) async { 312 | if (value == true) { 313 | await widget 314 | .platformLevelLocationIssueHandler.methodChannel 315 | .invokeMethod("clearFeatures") 316 | .then((dynamic val) { 317 | if (val == 1) { 318 | Scaffold.of(ctx).showSnackBar(SnackBar( 319 | content: Text( 320 | "Cleared all Features", 321 | style: TextStyle(color: Colors.black), 322 | ), 323 | duration: Duration(seconds: 1), 324 | backgroundColor: Colors.cyanAccent, 325 | )); 326 | setState(() { 327 | myFeatures = getFeatures(); 328 | myFeatures.then( 329 | (Map>> 330 | val) { 331 | featureCount = val.keys.toList().length; 332 | }); 333 | }); 334 | } 335 | }); 336 | } 337 | }); 338 | } 339 | : () { 340 | Scaffold.of(ctx).showSnackBar(SnackBar( 341 | content: Text( 342 | "Nothing to Clear", 343 | style: TextStyle(color: Colors.white), 344 | ), 345 | duration: Duration(seconds: 1), 346 | backgroundColor: Colors.redAccent, 347 | )); 348 | }, 349 | ); 350 | }, 351 | ), 352 | ], 353 | ), 354 | body: FutureBuilder>>>( 355 | future: myFeatures, 356 | builder: (BuildContext context, 357 | AsyncSnapshot>>> snapshot) { 358 | switch (snapshot.connectionState) { 359 | case ConnectionState.none: 360 | return Center( 361 | child: Container( 362 | padding: EdgeInsets.all(6.0), 363 | child: Column( 364 | mainAxisSize: MainAxisSize.min, 365 | children: [ 366 | Icon( 367 | Icons.sentiment_dissatisfied, 368 | color: Colors.cyanAccent, 369 | size: 150, 370 | ), 371 | Text("Nothing saved yet :/"), 372 | ], 373 | ), 374 | ), 375 | ); 376 | case ConnectionState.active: 377 | case ConnectionState.waiting: 378 | return Center( 379 | child: CircularProgressIndicator( 380 | value: null, 381 | backgroundColor: Colors.cyanAccent, 382 | ), 383 | ); 384 | case ConnectionState.done: 385 | if (snapshot.data == null || snapshot.data.isEmpty) { 386 | return Center( 387 | child: Container( 388 | padding: EdgeInsets.all(6.0), 389 | child: Column( 390 | mainAxisSize: MainAxisSize.min, 391 | children: [ 392 | Icon( 393 | Icons.sentiment_dissatisfied, 394 | color: Colors.cyanAccent, 395 | size: 150, 396 | ), 397 | Text("Nothing saved yet :/"), 398 | ], 399 | ), 400 | )); 401 | } else { 402 | List featureIds = snapshot.data.keys.toList(); 403 | featureCount = featureIds.length; 404 | return ListView.builder( 405 | itemBuilder: (BuildContext context, int index) { 406 | return GestureDetector( 407 | onTap: () {}, 408 | child: Container( 409 | margin: EdgeInsets.only( 410 | left: 4.0, right: 4.0, top: 6.0, bottom: 6.0), 411 | padding: EdgeInsets.only( 412 | left: 14.0, right: 14.0, top: 10.0, bottom: 10.0), 413 | decoration: BoxDecoration( 414 | gradient: LinearGradient( 415 | colors: [ 416 | Colors.cyanAccent, 417 | Colors.tealAccent 418 | ], 419 | begin: Alignment.topLeft, 420 | end: Alignment.bottomLeft), 421 | borderRadius: BorderRadius.circular(20.0), 422 | border: Border.all( 423 | color: Colors.white, 424 | width: 0.15, 425 | style: BorderStyle.solid, 426 | )), 427 | child: Column( 428 | mainAxisSize: MainAxisSize.min, 429 | children: layoutInflater(featureIds[index], 430 | snapshot.data[featureIds[index]]), 431 | ), 432 | ), 433 | ); 434 | }, 435 | itemCount: featureIds.length, 436 | padding: EdgeInsets.all(8.0), 437 | ); 438 | } 439 | } 440 | }), 441 | floatingActionButton: FloatingActionButton( 442 | onPressed: () async { 443 | await Navigator.of(context) 444 | .push(MaterialPageRoute( 445 | builder: (BuildContext context) => NewFeatureEntryMaker( 446 | location: widget.location, 447 | platformLevelLocationIssueHandler: 448 | widget.platformLevelLocationIssueHandler), 449 | )) 450 | .then((dynamic value) { 451 | setState(() { 452 | myFeatures = getFeatures(); 453 | myFeatures.then((Map>> val) { 454 | featureCount = val.keys.toList().length; 455 | }); 456 | }); 457 | }); 458 | }, 459 | backgroundColor: Colors.cyanAccent, 460 | highlightElevation: 4.0, 461 | tooltip: 'Add new Feature', 462 | child: Icon( 463 | Icons.add, 464 | color: Colors.white, 465 | ), 466 | ), 467 | ); 468 | } 469 | } 470 | --------------------------------------------------------------------------------