秦港相关方

master
hs 2025-12-12 09:11:30 +08:00
commit d39a355ede
236 changed files with 27776 additions and 0 deletions

44
.gitignore vendored Normal file
View File

@ -0,0 +1,44 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
/lib/git-cheatsheet.md
# Android Studio will place build artifacts here
/android/app/debug
/android/app/release

30
.metadata Normal file
View File

@ -0,0 +1,30 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: "d7b523b356d15fb81e7d340bbe52b47f93937323"
channel: "stable"
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: d7b523b356d15fb81e7d340bbe52b47f93937323
base_revision: d7b523b356d15fb81e7d340bbe52b47f93937323
- platform: web
create_revision: d7b523b356d15fb81e7d340bbe52b47f93937323
base_revision: d7b523b356d15fb81e7d340bbe52b47f93937323
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

0
.tgitconfig Normal file
View File

16
README.md Normal file
View File

@ -0,0 +1,16 @@
# flutter_integrated_whb
危化项目.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

30
analysis_options.yaml Normal file
View File

@ -0,0 +1,30 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
camel_case_types: false
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

14
android/.gitignore vendored Normal file
View File

@ -0,0 +1,14 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
.cxx/
# Remember to never publicly share your keystore.
# See https://flutter.dev/to/reference-keystore
key.properties
**/*.keystore
**/*.jks

View File

@ -0,0 +1,66 @@
import java.util.Properties
plugins {
id("com.android.application")
id("kotlin-android")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
}
// 🔐 加载 key.properties
val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("key.properties")
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(keystorePropertiesFile.inputStream())
}
android {
namespace = "com.company.myapp2"
compileSdk = flutter.compileSdkVersion
ndkVersion = "28.1.13356709"
// 使用 JDK 17 / JavaVersion.VERSION_17推荐与 AGP 8.9.x 兼容)
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
// jvmTarget 要与 Java 版本一致
jvmTarget = JavaVersion.VERSION_17.toString()
}
defaultConfig {
applicationId = "com.company.myapp2"
minSdk = 24
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}
signingConfigs {
create("release") {
storeFile = file(keystoreProperties["storeFile"] as String)
storePassword = keystoreProperties["storePassword"] as String
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["keyPassword"] as String
}
// debug signingConfig 通常存在Android Gradle 会有默认 debug 签名)
// 如果你自定义 debug 签名,则可以在这里创建
}
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
isMinifyEnabled = false
isShrinkResources = false
}
debug {
// 使用默认 debug 签名(或你自定义的 debug
// signingConfig = signingConfigs.getByName("debug")
}
}
}
flutter {
source = "../.."
}

View File

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

View File

@ -0,0 +1,130 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- 定位权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<!-- Android 13+ -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<!-- Android 12 及以下 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 相机 -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- 麦克风 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 通讯录 -->
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<!-- 蓝牙 -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!-- Android 12+ -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <!-- Android 12+ -->
<!-- 网络 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- 存储兼容旧版Android 11+ 基本无效) -->
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29"
tools:replace="android:maxSdkVersion" />
<!-- NFC -->
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="true" />
<!-- 安装 APK -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<!-- 角标适配不同厂商 -->
<!-- Samsung -->
<uses-permission android:name="com.sec.android.provider.badge.permission.READ"/>
<uses-permission android:name="com.sec.android.provider.badge.permission.WRITE"/>
<!-- Huawei -->
<uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE" />
<uses-permission android:name="com.huawei.android.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.huawei.android.launcher.permission.WRITE_SETTINGS" />
<!-- HTC -->
<uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS"/>
<uses-permission android:name="com.htc.launcher.permission.UPDATE_SHORTCUT"/>
<!-- Apex -->
<uses-permission android:name="com.anddoes.launcher.permission.UPDATE_COUNT"/>
<!-- Sony -->
<uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE"/>
<uses-permission android:name="com.sonymobile.home.permission.PROVIDER_INSERT_BADGE"/>
<!-- Solid -->
<uses-permission android:name="com.majeur.launcher.permission.UPDATE_BADGE"/>
<application
android:label="@string/appName"
android:name=".MyApplication"
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true"
android:enableOnBackInvokedCallback="true">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" />
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="43G1sKuHV6oRTrdR9VTIGPF9soej7V5a" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- FileProvider 配置 -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.company.myapp2.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<!-- Flutter 插件需要 -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<!-- Android 11+ package visibility -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
<!-- 允许安装器查询 -->
<package android:name="com.android.packageinstaller" />
</queries>
</manifest>

View File

@ -0,0 +1,123 @@
package com.company.myapp2
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import androidx.core.content.FileProvider
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import java.io.File
class MainActivity: FlutterActivity() {
private val CHANNEL = "app.install"
private val REQ_INSTALL_UNKNOWN = 9999
// 暂存安装请求(仅在跳转设置并等待返回时使用)
private var pendingApkPath: String? = null
private var pendingResult: MethodChannel.Result? = null
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
when (call.method) {
"installApk" -> {
val path = call.argument<String>("path")
if (path == null) {
result.error("NO_PATH", "no path provided", null)
return@setMethodCallHandler
}
handleInstallRequest(path, result)
}
else -> result.notImplemented()
}
}
}
private fun handleInstallRequest(path: String, result: MethodChannel.Result) {
val file = File(path)
if (!file.exists()) {
result.error("NO_FILE", "file not exist", null)
return
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// 8.0+ 需要 app 级别未知来源授权
if (!packageManager.canRequestPackageInstalls()) {
// 存储请求信息以便用户返回后继续
pendingApkPath = path
pendingResult = result
val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,
Uri.parse("package:$packageName"))
// 使用 startActivityForResult 以便用户返回后可以继续安装
startActivityForResult(intent, REQ_INSTALL_UNKNOWN)
return
}
}
// 已有授权 或 非 8.0+:直接安装
installApkInternal(path, result)
}
// 真正执行安装的函数(假定有权限)
private fun installApkInternal(path: String, result: MethodChannel.Result) {
val file = File(path)
if (!file.exists()) {
result.error("NO_FILE", "file not exist", null)
return
}
try {
val apkUri: Uri = FileProvider.getUriForFile(this, "$packageName.fileprovider", file)
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivity(intent)
result.success(true)
} catch (e: Exception) {
result.error("INSTALL_FAILED", e.message, null)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQ_INSTALL_UNKNOWN) {
// 用户从系统设置页返回后,检查是否已授权
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (packageManager.canRequestPackageInstalls()) {
// 授权已开:继续安装
val path = pendingApkPath
val res = pendingResult
// 清理 pending 状态
pendingApkPath = null
pendingResult = null
if (path != null && res != null) {
installApkInternal(path, res)
} else {
// 安全兜底:若没有 pending 数据,通知 caller 重新触发
res?.error("NO_PENDING", "no pending install info", null)
}
} else {
// 用户仍未授权
pendingApkPath = null
pendingResult?.error("NEED_INSTALL_PERMISSION", "user did not allow install unknown apps", null)
pendingResult = null
}
} else {
// API < 26尝试直接安装一次作为尝试某些 ROM 无法精准判断)
val path = pendingApkPath
val res = pendingResult
pendingApkPath = null
pendingResult = null
if (path != null && res != null) {
installApkInternal(path, res)
} else {
res?.error("NO_PENDING", "no pending install info", null)
}
}
}
}
}

View File

@ -0,0 +1,38 @@
package com.company.myapp2
import android.app.Application
import android.content.Context
import android.util.Log
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// 通过反射调用 SDKInitializer避免在编译期要求依赖存在
try {
val sdkClass = Class.forName("com.baidu.mapapi.SDKInitializer")
// setAgreePrivacy(boolean) - 有些 SDK 要求先同意隐私
try {
val setAgree = sdkClass.getMethod("setAgreePrivacy", java.lang.Boolean::class.javaPrimitiveType)
setAgree.invoke(null, true)
Log.i("MyApplication", "SDKInitializer.setAgreePrivacy invoked via reflection")
} catch (t: Throwable) {
Log.w("MyApplication", "setAgreePrivacy not available or failed: ${t.message}")
}
// initialize(Context)
try {
val initMethod = sdkClass.getMethod("initialize", Context::class.java)
initMethod.invoke(null, this)
Log.i("MyApplication", "SDKInitializer.initialize invoked via reflection")
} catch (t: Throwable) {
Log.w("MyApplication", "initialize(Context) not available or failed: ${t.message}")
}
} catch (e: ClassNotFoundException) {
// 运行时没有找到该类(可能 plugin 未包含 SDK记录日志但不崩溃
Log.w("MyApplication", "Baidu SDKInitializer class not found at runtime: ${e.message}")
} catch (e: Throwable) {
Log.e("MyApplication", "Unexpected error while initializing Baidu SDK via reflection", e)
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 KiB

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
</item>
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 KiB

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
</item>
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="appName">秦港相关方</string>
</resources>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 允许访问 app 的缓存目录 -->
<cache-path name="cache" path="." />
<!-- 允许访问 app 的 files 目录 -->
<files-path name="files" path="." />
<!-- 允许访问外部下载目录 -->
<external-path name="download" path="." />
</paths>

View File

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

21
android/build.gradle.kts Normal file
View File

@ -0,0 +1,21 @@
allprojects {
repositories {
google()
mavenCentral()
}
}
val newBuildDir: Directory = rootProject.layout.buildDirectory.dir("../../build").get()
rootProject.layout.buildDirectory.value(newBuildDir)
subprojects {
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
project.layout.buildDirectory.value(newSubprojectBuildDir)
}
subprojects {
project.evaluationDependsOn(":app")
}
tasks.register<Delete>("clean") {
delete(rootProject.layout.buildDirectory)
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,3 @@
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true
android.enableJetifier=true

View File

@ -0,0 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
#distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.11.1-all.zip

View File

@ -0,0 +1,37 @@
pluginManagement {
val flutterSdkPath = run {
val properties = java.util.Properties()
file("local.properties").inputStream().use { properties.load(it) }
val flutterSdkPath = properties.getProperty("flutter.sdk")
require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
flutterSdkPath
}
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
resolutionStrategy {
eachPlugin {
val pluginId = requested.id.id
if (pluginId == "org.jetbrains.kotlin.android" || pluginId == "org.jetbrains.kotlin.jvm") {
// 与 build.gradle.kts 中 kotlin 插件版本保持一致
useVersion("2.2.20")
}
}
}
}
plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
// 与 android/build.gradle.kts 中使用的 AGP 版本保持一致
id("com.android.application") version "8.9.1" apply false
// 与 build.gradle.kts 中 kotlin 插件版本保持一致
id("org.jetbrains.kotlin.android") version "2.2.20" apply false
}
include(":app")

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1013 B

BIN
assets/images/banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

BIN
assets/images/bg1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
assets/images/bg2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
assets/images/g_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
assets/images/ico1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
assets/images/ico10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 545 B

BIN
assets/images/ico11.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 769 B

BIN
assets/images/ico12.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
assets/images/ico13.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 B

BIN
assets/images/ico14.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 812 B

BIN
assets/images/ico15.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 682 B

BIN
assets/images/ico16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 633 B

BIN
assets/images/ico2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
assets/images/ico3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
assets/images/ico4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
assets/images/ico5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
assets/images/ico6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
assets/images/ico7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
assets/images/ico8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
assets/images/ico9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 749 B

BIN
assets/images/img1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
assets/images/img2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
assets/images/loginbg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

BIN
assets/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
assets/images/lun.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 KiB

BIN
assets/images/more.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 B

BIN
assets/images/my_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

BIN
assets/images/null.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

BIN
assets/images/search.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

BIN
assets/images/unit_ico1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
assets/images/unit_ico2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

2
assets/js/jsencrypt.min.js vendored Normal file

File diff suppressed because one or more lines are too long

BIN
assets/map/100.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
assets/map/50.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
assets/map/c.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
assets/map/h.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
assets/map/hh.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

389
assets/map/index.html Normal file
View File

@ -0,0 +1,389 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>特殊作业扎点</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<style>
body, html, #container {
overflow: hidden;
width: 100%;
height: 100%;
margin: 0;
font-family: "微软雅黑";
}
#hint {
position: absolute;
z-index: 9999;
left: 10px;
top: 10px;
padding: 6px 10px;
background: rgba(255,255,255,0.9);
border-radius: 4px;
font-size: 12px;
}
</style>
<!-- Baidu Map WebGL (保留你的 key) -->
<script type="text/javascript"
src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=OElqFYoKiAH8KFtph8ftLKF5NlNrbCUr"></script>
<script src="./uni.webview.1.5.4.js"></script>
</head>
<body onload="onLoad()">
<div id="container"></div>
<div id="hint" style="display:none"></div>
</body>
<script>
// 地图与数据容器
var map = null;
var marker = null;
var GSON_LON_LAT_WSG84 = []; // WGS84 多点 [[lon,lat,alt], ...]
var GSON_LON_LAT_BD09 = []; // 转换后的 BD09 二维点 [[lng,lat],...]
var convertor = null;
// ---------------------------
// 通用通知宿主Flutter / 原生 / web
// 会尝试多种桥接方式
// data 可以是对象或字符串
// ---------------------------
function notifyHost(data) {
try {
// prefer passing object where supported
if (window.JS && typeof window.JS.postMessage === 'function') {
// webview_flutter JavaScriptChannel expects string
var payload = (typeof data === 'string') ? data : JSON.stringify(data);
window.JS.postMessage(payload);
return;
}
if (window.flutter_inappwebview && typeof window.flutter_inappwebview.callHandler === 'function') {
// flutter_inappwebview can accept objects
window.flutter_inappwebview.callHandler('messageHandler', data);
return;
}
if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.JS && typeof window.webkit.messageHandlers.JS.postMessage === 'function') {
window.webkit.messageHandlers.JS.postMessage(data);
return;
}
// fallback to uni (if present) to keep backward compatibility
if (window.uni && typeof window.uni.postMessage === 'function') {
window.uni.postMessage({data: data});
return;
}
// last resort, console (useful for debugging)
console.log('notifyHost:', data);
} catch (e) {
console.error('notifyHost error:', e);
}
}
// ---------------------------
// 尝试从 URL 初始化(如果 Flutter 把参数拼在 URL 上)
// 支持参数: longitude, latitude, GSON (JSON string, 已 encodeURIComponent)
// ---------------------------
function tryInitFromUrl() {
try {
const params = new URLSearchParams(window.location.search);
const lon = params.get('longitude');
const lat = params.get('latitude');
const gsonRaw = params.get('GSON'); // 预期是 encodeURIComponent(JSON.stringify([...]))
var has = false;
if (lon && lat) has = true;
if (gsonRaw) has = true;
if (!has) return false;
var gson = null;
if (gsonRaw) {
try {
gson = JSON.parse(decodeURIComponent(gsonRaw));
} catch (e) {
// 如果直接是未 encode 的 JSON 字符串,也尝试解析
try { gson = JSON.parse(gsonRaw); } catch (e2) { gson = null; }
}
}
// 使用从 url 获取到的数据执行初始化
initWithData({
longitude: parseFloat(lon),
latitude: parseFloat(lat),
GSON: gson
});
return true;
} catch (e) {
console.warn('tryInitFromUrl error', e);
return false;
}
}
// ---------------------------
// Flutter/宿主可调用的初始化函数
// 支持两种调用方式:
// 1) initWithData({longitude: xx, latitude: yy, GSON: [...]})
// 2) initWithData(longitude, latitude, GSONArray)
// GSONArray 结构应与原来一致([[lon,lat,alt], ...]
// ---------------------------
window.initWithData = function() {
var args = arguments;
var payload = {};
if (args.length === 1 && typeof args[0] === 'object') {
payload = args[0];
} else {
// try positional
payload.longitude = args[0];
payload.latitude = args[1];
payload.GSON = args[2];
}
try {
if (!payload) payload = {};
// default safe parse
var lon = Number(payload.longitude) || 0;
var lat = Number(payload.latitude) || 0;
var gson = payload.GSON || [];
// ensure convertor exists
if (!convertor && window.BMapGL && typeof BMapGL.Convertor === 'function') {
convertor = new BMapGL.Convertor();
}
// set global wgs84 list (if provided)
if (Array.isArray(gson) && gson.length > 0) {
GSON_LON_LAT_WSG84 = gson;
}
// init map & polygon
fnInitMap(lon, lat);
if (GSON_LON_LAT_WSG84 && GSON_LON_LAT_WSG84.length > 0) {
fnInitConvertorData(GSON_LON_LAT_WSG84);
}
showHint('地图已初始化');
return true;
} catch (e) {
console.error('initWithData error', e);
return false;
}
};
// 显示调试提示
function showHint(text) {
var el = document.getElementById('hint');
if (!el) return;
el.style.display = 'block';
el.innerText = text;
setTimeout(function(){ el.style.display = 'none'; }, 4000);
}
// ---------------------------
// 页面加载
// ---------------------------
function onLoad() {
// create convertor if possible
if (window.BMapGL && typeof BMapGL.Convertor === 'function') {
convertor = new BMapGL.Convertor();
} else {
console.warn('BMapGL.Convertor not ready yet.');
}
// 创建地图对象(延迟绑定 center等 init 时调用)
map = new BMapGL.Map('container');
map.enableScrollWheelZoom(true);
map.setDisplayOptions({ building: false });
map.addEventListener('click', MapClick);
// 如果 URL 带参数则自动初始化,否则等待宿主调用 initWithData(...)
var ok = tryInitFromUrl();
if (!ok) {
showHint('等待宿主调用 initWithData(...) 初始化地图');
}
}
// ---------------------------
// 点在多边形内判定(二维,只用 lon/lat
// polygon = [[lng,lat], ...]
// point = [lng, lat]
// ---------------------------
function isPointInPolygon(point, polygon) {
const x = point[0];
const y = point[1];
let inside = false;
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
const xi = polygon[i][0], yi = polygon[i][1];
const xj = polygon[j][0], yj = polygon[j][1];
const intersect = ((yi > y) !== (yj > y))
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
}
// 地图点击处理
function MapClick(e) {
try {
if (marker) map.removeOverlay(marker);
marker = new BMapGL.Marker(new BMapGL.Point(e.latlng.lng, e.latlng.lat));
const x = [e.latlng.lng, e.latlng.lat];
let inside = (GSON_LON_LAT_BD09 && GSON_LON_LAT_BD09.length > 0) ? isPointInPolygon(x, GSON_LON_LAT_BD09) : true;
if (!inside) {
//alert("当前选择点位不在区域中!");
notifyHost({type:'point_selected', ok:false, reason:'out_of_polygon', lng:e.latlng.lng, lat:e.latlng.lat});
} else {
map.addOverlay(marker);
// 把 BD09 -> WGS84 转换后的点回传给宿主
fnConvertorBd09ToWgs84Data2(e.latlng.lng, e.latlng.lat);
notifyHost({type:'point_selected', ok:true, lng:e.latlng.lng, lat:e.latlng.lat});
// // 直接把BD09回传
// notifyHost({type:'converted', longitue: e.latlng.lng, latitude: e.latlng.lat});
// notifyHost({
// type: 'point_selected',
// ok: true,
// lng: e.latlng.lng,
// lat: e.latlng.lat
// });
}
} catch (err) {
console.error('MapClick error', err);
}
}
// ---------------------------
// 将 WGS84 多点转换为 BD09 并绘制多边形
// arr: [[lon,lat,...], ...] 注意原 arr GSON_LON_LAT_WSG84顺序是 lon, lat
// ---------------------------
function fnInitConvertorData(arr) {
try {
if (!convertor) convertor = new BMapGL.Convertor();
var points = [];
for (let i = 0; i < arr.length; i++) {
var xi = arr[i][0], yi = arr[i][1];
points.push(new BMapGL.Point(xi, yi));
}
convertor.translate(points, 1, 5, function(res) {
if (!res || !res.points) {
console.warn('convertor.translate returned no points', res);
return;
}
GSON_LON_LAT_BD09 = [];
var list = [];
for (var p = 0; p < res.points.length; p++) {
let item = res.points[p];
GSON_LON_LAT_BD09.push([item.lng, item.lat]);
list.push(new BMapGL.Point(item.lng, item.lat));
}
var polygon = new BMapGL.Polygon(list, {
zIndex: 999,
strokeColor: 'blue',
strokeWeight: 5,
strokeOpacity: 0.5
});
map.addOverlay(polygon);
});
} catch (e) {
console.error('fnInitConvertorData error', e);
}
}
// ---------------------------
// 初始化地图中心longitude, latitude 为 WGS84
// ---------------------------
function fnInitMap(longitude, latitude) {
try {
if (!convertor) convertor = new BMapGL.Convertor();
var ponits = [ new BMapGL.Point(longitude, latitude) ];
convertor.translate(ponits, 1, 5, function(res) {
if (!res || !res.points || res.points.length === 0) {
console.warn('fnInitMap: translate failed', res);
return;
}
var pt = res.points[0];
map.centerAndZoom(new BMapGL.Point(pt.lng, pt.lat), 18);
});
} catch (e) {
console.error('fnInitMap error', e);
}
}
// ---------------------------
// BD09 -> WGS84 JS 版算法),并把结果 post 给宿主
// 注意: bdLat, bdLon 参数顺序(原函数输入顺序)
// 返回 [wgsLat, wgsLon](跟原实现一致)
// ---------------------------
const bd09ToWgs84 = (bdLat, bdLon) => {
const x_pi = (Math.PI * 3000.0) / 180.0;
const x = bdLon - 0.0065;
const y = bdLat - 0.006;
const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
const gcjLon = z * Math.cos(theta);
const gcjLat = z * Math.sin(theta);
let dlat = transformlat(gcjLon - 105.0, gcjLat - 35.0);
let dlng = transformlng(gcjLon - 105.0, gcjLat - 35.0);
const radlat = (gcjLat / 180.0) * Math.PI;
let magic = Math.sin(radlat);
magic = 1 - 0.006693421622965943 * magic * magic;
const sqrtmagic = Math.sqrt(magic);
dlat = (dlat * 180.0) / (((6378245.0 * (1 - 0.006693421622965943)) / (magic * sqrtmagic)) * Math.PI);
dlng = (dlng * 180.0) / ((6378245.0 / sqrtmagic) * Math.cos(radlat) * Math.PI);
const mglat = gcjLat + dlat;
const mglng = gcjLon + dlng;
const wgsLon = gcjLon * 2 - mglng;
const wgsLat = gcjLat * 2 - mglat;
return [wgsLat, wgsLon];
};
const transformlat = (lng, lat) => {
let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
ret += ((20.0 * Math.sin(6.0 * lng * Math.PI) + 20.0 * Math.sin(2.0 * lng * Math.PI)) * 2.0) / 3.0;
ret += ((20.0 * Math.sin(lat * Math.PI) + 40.0 * Math.sin((lat / 3.0) * Math.PI)) * 2.0) / 3.0;
ret += ((160.0 * Math.sin((lat / 12.0) * Math.PI) + 320 * Math.sin((lat * Math.PI) / 30.0)) * 2.0) / 3.0;
return ret;
};
const transformlng = (lng, lat) => {
let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
ret += ((20.0 * Math.sin(6.0 * lng * Math.PI) + 20.0 * Math.sin(2.0 * lng * Math.PI)) * 2.0) / 3.0;
ret += ((20.0 * Math.sin(lng * Math.PI) + 40.0 * Math.sin((lng / 3.0) * Math.PI)) * 2.0) / 3.0;
ret += ((150.0 * Math.sin((lng / 12.0) * Math.PI) + 300.0 * Math.sin((lng / 30.0) * Math.PI)) * 2.0) / 3.0;
return ret;
};
// ---------------------------
// 使用百度 convertor如果可用把 BD09 点转回 WGS84 并 postMessage 给宿主
// 备用:也会调用 bd09ToWgs84 本地算法
// ---------------------------
function fnConvertorBd09ToWgs84Data2(lng, lat) {
try {
// first try convertor.translate from BMapGL
if (convertor && typeof convertor.translate === 'function') {
var pts = [ new BMapGL.Point(lng, lat) ];
convertor.translate(pts, 5, 1, function(res) {
if (res && res.points && res.points.length > 0) {
var p = res.points[0];
// res.points are in WGS84? depends on convert params; keep compatibility:
notifyHost({type:'converted', longitue: p.lng, latitude: p.lat});
return;
}
// fallback to local algorithm if convertor result absent
var w = bd09ToWgs84(lat, lng);
notifyHost({type:'converted', longitue: w[1], latitude: w[0]});
});
} else {
var w = bd09ToWgs84(lat, lng);
notifyHost({type:'converted', longitue: w[1], latitude: w[0]});
}
} catch (e) {
console.error('fnConvertorBd09ToWgs84Data2 error', e);
var w = bd09ToWgs84(lat, lng);
notifyHost({type:'converted', longitue: w[1], latitude: w[0]});
}
}
// 兼容老方法名
window.fnInitMap = fnInitMap;
window.fnInitConvertorData = fnInitConvertorData;
window.fnConvertorBd09ToWgs84Data2 = fnConvertorBd09ToWgs84Data2;
</script>
</html>

BIN
assets/map/jc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
assets/map/l.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
assets/map/ls.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

137
assets/map/map.html Normal file
View File

@ -0,0 +1,137 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>地图</title>
<!-- 天地图API -->
<script src="https://api.tianditu.gov.cn/api?v=4.0&tk=e8a16137fd226a62a23cc7ba5c9c78ce" type="text/javascript"></script>
<style>
html, body { height: 100%; margin: 0; padding: 0; }
#mapDiv { position: absolute; top: 0; left: 0; right: 0; bottom: 0; }
</style>
</head>
<body onload="onLoad()">
<div id="mapDiv"></div>
</body>
<script type="text/javascript">
var map;
var zoom = 14;
var currentMarker = null;
function getUrlParam(name) {
if (window.__injectedParams && window.__injectedParams[name] !== undefined) {
return window.__injectedParams[name].toString();
}
const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
const r = window.location.search.substr(1).match(reg);
if (r != null) return decodeURI(r[2]);
return "";
}
function onLoad() {
var imageURL = "https://t0.tianditu.gov.cn/img_w/wmts?" +
"SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles" +
"&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=e8a16137fd226a62a23cc7ba5c9c78ce";
var lay = new T.TileLayer(imageURL, {minZoom: 1, maxZoom: 18});
var config = {layers: [lay]};
map = new T.Map("mapDiv", config);
var initLng = parseFloat(getUrlParam('longitude'));
var initLat = parseFloat(getUrlParam('latitude'));
if (isNaN(initLng) || isNaN(initLat) || initLng === 0 || initLat === 0) {
initLng = 116.397428;
initLat = 39.90923;
}
map.centerAndZoom(new T.LngLat(initLng, initLat), zoom);
map.enableScrollWheelZoom();
// 始终开启点击标点功能
addMapClick();
}
function addMapClick() {
map.addEventListener("click", MapClick);
}
function MapClick(event) {
var lng = event.lnglat.getLng();
var lat = event.lnglat.getLat();
// 清除旧标记并添加新标记(使用默认图标)
map.clearOverLays();
var marker = new T.Marker(new T.LngLat(lng, lat));
map.addOverLay(marker);
// 保存选中位置
window.selectedLocation = {
longitude: lng,
latitude: lat
};
// 发送位置信息给 Flutter
sendLocationToFlutter(lat, lng);
}
function sendLocationToFlutter(lat, lng) {
var payload = {
data: [
{
latitude: lat,
longitude: lng
}
]
};
// Flutter WebView 桥接
if (typeof window.flutterPostMessage === 'function') {
window.flutterPostMessage(payload);
return;
}
// 备用桥接方法uniapp 或小程序)
uni.getEnv(function (res) {
if (res.plus) {
uni.postMessage({ data: { "longitude": lng, "latitude": lat } });
} else {
if (window.wx && window.wx.miniProgram) {
try {
window.wx.miniProgram.postMessage({ data: { "longitude": lng, "latitude": lat } });
window.wx.miniProgram.navigateBack();
} catch(e) {
console.log('wx miniProgram error', e);
}
}
}
});
}
// Flutter 获取选中位置的方法
function getSelectedLocation() {
try {
if (window.selectedLocation) {
return window.selectedLocation;
}
return null;
} catch (e) {
console.log('getSelectedLocation error', e);
return null;
}
}
// Flutter 调用,设置地图中心和标记
function setLocation(lng, lat) {
try {
map.centerAndZoom(new T.LngLat(lng, lat), zoom);
var marker = new T.Marker(new T.LngLat(lng, lat));
map.clearOverLays();
map.addOverLay(marker);
window.selectedLocation = { longitude: lng, latitude: lat };
return true;
} catch (e) {
console.log('setLocation error', e);
return false;
}
}
</script>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
assets/tabbar/basics.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
assets/tabbar/my.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
assets/tabbar/my_cur.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
assets/tabbar/works.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
assets/tabbar/works_cur.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

3
devtools_options.yaml Normal file
View File

@ -0,0 +1,3 @@
description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions:

34
ios/.gitignore vendored Normal file
View File

@ -0,0 +1,34 @@
**/dgph
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>13.0</string>
</dict>
</plist>

View File

@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View File

@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

43
ios/Podfile Normal file
View File

@ -0,0 +1,43 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '13.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end

237
ios/Podfile.lock Normal file
View File

@ -0,0 +1,237 @@
PODS:
- BaiduMapKit/Base (6.6.4)
- BaiduMapKit/Map (6.6.4):
- BaiduMapKit/Base
- BaiduMapKit/Utils (6.6.4):
- BaiduMapKit/Base
- camera_avfoundation (0.0.1):
- Flutter
- connectivity_plus (0.0.1):
- Flutter
- device_info_plus (0.0.1):
- Flutter
- DKImagePickerController/Core (4.3.9):
- DKImagePickerController/ImageDataManager
- DKImagePickerController/Resource
- DKImagePickerController/ImageDataManager (4.3.9)
- DKImagePickerController/PhotoGallery (4.3.9):
- DKImagePickerController/Core
- DKPhotoGallery
- DKImagePickerController/Resource (4.3.9)
- DKPhotoGallery (0.0.19):
- DKPhotoGallery/Core (= 0.0.19)
- DKPhotoGallery/Model (= 0.0.19)
- DKPhotoGallery/Preview (= 0.0.19)
- DKPhotoGallery/Resource (= 0.0.19)
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Core (0.0.19):
- DKPhotoGallery/Model
- DKPhotoGallery/Preview
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Model (0.0.19):
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Preview (0.0.19):
- DKPhotoGallery/Model
- DKPhotoGallery/Resource
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Resource (0.0.19):
- SDWebImage
- SwiftyGif
- file_picker (0.0.1):
- DKImagePickerController/PhotoGallery
- Flutter
- Flutter (1.0.0)
- flutter_baidu_mapapi_base (3.9.0):
- BaiduMapKit/Utils (= 6.6.4)
- Flutter
- flutter_baidu_mapapi_map (3.9.0):
- BaiduMapKit/Map (= 6.6.4)
- Flutter
- flutter_baidu_mapapi_base
- flutter_baidu_mapapi_utils (3.9.0):
- BaiduMapKit/Utils (= 6.6.4)
- Flutter
- flutter_baidu_mapapi_base
- flutter_native_splash (2.4.3):
- Flutter
- flutter_new_badger (0.0.1):
- Flutter
- fluttertoast (0.0.2):
- Flutter
- geolocator_apple (1.2.0):
- Flutter
- FlutterMacOS
- image_picker_ios (0.0.1):
- Flutter
- mobile_scanner (7.0.0):
- Flutter
- FlutterMacOS
- nfc_manager (0.0.1):
- Flutter
- objective_c (0.0.1):
- Flutter
- open_file_ios (0.0.1):
- Flutter
- package_info_plus (0.4.5):
- Flutter
- pdfx (1.0.0):
- Flutter
- permission_handler_apple (9.3.0):
- Flutter
- photo_manager (3.8.0):
- Flutter
- FlutterMacOS
- SDWebImage (5.21.1):
- SDWebImage/Core (= 5.21.1)
- SDWebImage/Core (5.21.1)
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- SwiftyGif (5.4.5)
- url_launcher_ios (0.0.1):
- Flutter
- video_compress (0.3.0):
- Flutter
- video_player_avfoundation (0.0.1):
- Flutter
- FlutterMacOS
- wakelock_plus (0.0.1):
- Flutter
- webview_flutter_wkwebview (0.0.1):
- Flutter
- FlutterMacOS
DEPENDENCIES:
- camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`)
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`)
- Flutter (from `Flutter`)
- flutter_baidu_mapapi_base (from `.symlinks/plugins/flutter_baidu_mapapi_base/ios`)
- flutter_baidu_mapapi_map (from `.symlinks/plugins/flutter_baidu_mapapi_map/ios`)
- flutter_baidu_mapapi_utils (from `.symlinks/plugins/flutter_baidu_mapapi_utils/ios`)
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
- flutter_new_badger (from `.symlinks/plugins/flutter_new_badger/ios`)
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
- geolocator_apple (from `.symlinks/plugins/geolocator_apple/darwin`)
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- mobile_scanner (from `.symlinks/plugins/mobile_scanner/darwin`)
- nfc_manager (from `.symlinks/plugins/nfc_manager/ios`)
- objective_c (from `.symlinks/plugins/objective_c/ios`)
- open_file_ios (from `.symlinks/plugins/open_file_ios/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- pdfx (from `.symlinks/plugins/pdfx/ios`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- photo_manager (from `.symlinks/plugins/photo_manager/darwin`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
- video_compress (from `.symlinks/plugins/video_compress/ios`)
- video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`)
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/darwin`)
SPEC REPOS:
trunk:
- BaiduMapKit
- DKImagePickerController
- DKPhotoGallery
- SDWebImage
- SwiftyGif
EXTERNAL SOURCES:
camera_avfoundation:
:path: ".symlinks/plugins/camera_avfoundation/ios"
connectivity_plus:
:path: ".symlinks/plugins/connectivity_plus/ios"
device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios"
file_picker:
:path: ".symlinks/plugins/file_picker/ios"
Flutter:
:path: Flutter
flutter_baidu_mapapi_base:
:path: ".symlinks/plugins/flutter_baidu_mapapi_base/ios"
flutter_baidu_mapapi_map:
:path: ".symlinks/plugins/flutter_baidu_mapapi_map/ios"
flutter_baidu_mapapi_utils:
:path: ".symlinks/plugins/flutter_baidu_mapapi_utils/ios"
flutter_native_splash:
:path: ".symlinks/plugins/flutter_native_splash/ios"
flutter_new_badger:
:path: ".symlinks/plugins/flutter_new_badger/ios"
fluttertoast:
:path: ".symlinks/plugins/fluttertoast/ios"
geolocator_apple:
:path: ".symlinks/plugins/geolocator_apple/darwin"
image_picker_ios:
:path: ".symlinks/plugins/image_picker_ios/ios"
mobile_scanner:
:path: ".symlinks/plugins/mobile_scanner/darwin"
nfc_manager:
:path: ".symlinks/plugins/nfc_manager/ios"
objective_c:
:path: ".symlinks/plugins/objective_c/ios"
open_file_ios:
:path: ".symlinks/plugins/open_file_ios/ios"
package_info_plus:
:path: ".symlinks/plugins/package_info_plus/ios"
pdfx:
:path: ".symlinks/plugins/pdfx/ios"
permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios"
photo_manager:
:path: ".symlinks/plugins/photo_manager/darwin"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios"
video_compress:
:path: ".symlinks/plugins/video_compress/ios"
video_player_avfoundation:
:path: ".symlinks/plugins/video_player_avfoundation/darwin"
wakelock_plus:
:path: ".symlinks/plugins/wakelock_plus/ios"
webview_flutter_wkwebview:
:path: ".symlinks/plugins/webview_flutter_wkwebview/darwin"
SPEC CHECKSUMS:
BaiduMapKit: 84991811cb07b24c6ead7d59022c13245427782c
camera_avfoundation: 5675ca25298b6f81fa0a325188e7df62cc217741
connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd
device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
flutter_baidu_mapapi_base: 24dd82034374c6f52a73e90316834c63ff8d4f64
flutter_baidu_mapapi_map: f799cc1bb3d39196b8d3d59399ca8635e690bd44
flutter_baidu_mapapi_utils: 0c69394243d51e97f521f396e150aaaf31e84e29
flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf
flutter_new_badger: 133aaf93e9a5542bf905c8483d8b83c5ef4946ea
fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1
geolocator_apple: ab36aa0e8b7d7a2d7639b3b4e48308394e8cef5e
image_picker_ios: e0ece4aa2a75771a7de3fa735d26d90817041326
mobile_scanner: 9157936403f5a0644ca3779a38ff8404c5434a93
nfc_manager: f6d5609c09b4640b914a3dc67479a2e392965fd0
objective_c: 89e720c30d716b036faf9c9684022048eee1eee2
open_file_ios: 5ff7526df64e4394b4fe207636b67a95e83078bb
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
pdfx: 77f4dddc48361fbb01486fa2bdee4532cbb97ef3
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
photo_manager: 343d78032bf7ebe944d2ab9702204dc2eda07338
SDWebImage: f29024626962457f3470184232766516dee8dfea
shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b
video_compress: f2133a07762889d67f0711ac831faa26f956980e
video_player_avfoundation: dd410b52df6d2466a42d28550e33e4146928280a
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
webview_flutter_wkwebview: 8ebf4fded22593026f7dbff1fbff31ea98573c8d
PODFILE CHECKSUM: 3c63482e143d1b91d2d2560aee9fb04ecc74ac7e
COCOAPODS: 1.16.2

Some files were not shown because too many files have changed in this diff Show More