秦港相关方
|
|
@ -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
|
||||||
|
|
@ -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,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.
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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 = "../.."
|
||||||
|
}
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 345 KiB |
|
|
@ -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>
|
||||||
|
After Width: | Height: | Size: 345 KiB |
|
|
@ -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>
|
||||||
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 8.9 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="appName">秦港相关方</string>
|
||||||
|
</resources>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
|
||||||
|
android.useAndroidX=true
|
||||||
|
android.enableJetifier=true
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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")
|
||||||
|
After Width: | Height: | Size: 9.0 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.0 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 9.0 KiB |
|
After Width: | Height: | Size: 1013 B |
|
After Width: | Height: | Size: 305 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 545 B |
|
After Width: | Height: | Size: 769 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 829 B |
|
After Width: | Height: | Size: 812 B |
|
After Width: | Height: | Size: 682 B |
|
After Width: | Height: | Size: 633 B |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 749 B |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 221 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 777 KiB |
|
After Width: | Height: | Size: 274 B |
|
After Width: | Height: | Size: 139 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 528 B |
|
After Width: | Height: | Size: 178 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -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>
|
||||||
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -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>
|
||||||
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
|
@ -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:
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||||
|
#include "Generated.xcconfig"
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||||
|
#include "Generated.xcconfig"
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||