expo-gaode-map-navigation 1.0.1-next.0 → 1.0.1-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -28
- package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapModule.kt +7 -0
- package/android/src/main/java/expo/modules/gaodemap/map/modules/SDKInitializer.kt +38 -3
- package/build/map/ExpoGaodeMapModule.js +5 -5
- package/ios/map/ExpoGaodeMapModule.swift +22 -6
- package/package.json +13 -6
- package/package.json.backup +0 -47
- package/plugin/README.md +0 -52
- package/plugin/build/withGaodeMap.d.ts +0 -22
- package/plugin/build/withGaodeMap.js +0 -169
- package/plugin/src/withGaodeMap.ts +0 -231
- package/plugin/tsconfig.tsbuildinfo +0 -1
- package/src/ExpoGaodeMapNaviView.tsx +0 -94
- package/src/ExpoGaodeMapNavigation.types.ts +0 -3
- package/src/ExpoGaodeMapNavigationModule.ts +0 -11
- package/src/index.ts +0 -262
- package/src/map/ExpoGaodeMap.types.ts +0 -46
- package/src/map/ExpoGaodeMapModule.ts +0 -315
- package/src/map/ExpoGaodeMapView.tsx +0 -120
- package/src/map/components/overlays/Circle.tsx +0 -20
- package/src/map/components/overlays/Cluster.tsx +0 -26
- package/src/map/components/overlays/HeatMap.tsx +0 -27
- package/src/map/components/overlays/Marker.tsx +0 -88
- package/src/map/components/overlays/MultiPoint.tsx +0 -27
- package/src/map/components/overlays/Polygon.tsx +0 -19
- package/src/map/components/overlays/Polyline.tsx +0 -19
- package/src/map/components/overlays/index.ts +0 -7
- package/src/map/index.ts +0 -37
- package/src/map/types/common.types.ts +0 -126
- package/src/map/types/index.ts +0 -55
- package/src/map/types/location.types.ts +0 -368
- package/src/map/types/map-view.types.ts +0 -281
- package/src/map/types/overlays.types.ts +0 -404
- package/src/map/utils/EventManager.ts +0 -23
- package/src/map/utils/ModuleLoader.ts +0 -115
- package/src/types/coordinates.types.ts +0 -25
- package/src/types/independent.types.ts +0 -288
- package/src/types/index.ts +0 -5
- package/src/types/naviview.types.ts +0 -330
- package/src/types/route.types.ts +0 -305
package/README.md
CHANGED
|
@@ -1,49 +1,120 @@
|
|
|
1
1
|
# expo-gaode-map-navigation
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
高德地图“导航一体化”模块。内置地图渲染能力与导航能力,提供从地图展示到路径规划与实时导航的完整解决方案。
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
- 🗺️ **路径规划**:支持驾车、步行、骑行、公交等多种出行方式
|
|
8
|
-
- 🧭 **导航引导**:提供实时导航引导功能
|
|
9
|
-
- 📍 **多种策略**:支持最快路线、最短路线、避免拥堵等策略
|
|
10
|
-
- 🚗 **途经点支持**:支持设置途经点的路径规划
|
|
5
|
+
## 模块定位与使用约束
|
|
11
6
|
|
|
12
|
-
|
|
7
|
+
- 独立使用:本模块已封装地图相关能力(MapView/覆盖物等)与导航能力,不需要、也不应同时安装核心地图包。
|
|
8
|
+
- 禁止共存:请勿与 `expo-gaode-map` 同时安装或链接。两者均包含地图 SDK,Android 上会产生 `3dmap` vs `navi-3dmap` 的二进制冲突。
|
|
9
|
+
- 简化依赖:安装本模块即可获得地图 + 导航全量能力,无需额外地图依赖。
|
|
13
10
|
|
|
14
|
-
|
|
11
|
+
## 功能特性
|
|
15
12
|
|
|
16
|
-
|
|
13
|
+
- 🗺️ 地图渲染:内置地图视图与常用覆盖物(标注、折线、多边形、热力图、聚合等)
|
|
14
|
+
- 🧭 路径与导航:驾车、步行、骑行等多种出行策略与实时引导
|
|
15
|
+
- ⚙️ 策略丰富:最快、最短、避拥堵、少收费、少红绿灯等
|
|
16
|
+
- 🚗 复杂路线:支持多途经点、限行考虑、分段规划
|
|
17
|
+
- 🌐 Web API 协作:可与 `expo-gaode-map-web-api` 配合,统一通过基础初始化下发 Web Key 后使用
|
|
17
18
|
|
|
18
19
|
## 安装
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
仅安装本模块(不要安装 `expo-gaode-map`):
|
|
21
22
|
|
|
22
23
|
```bash
|
|
23
|
-
npm
|
|
24
|
+
# npm
|
|
25
|
+
npm install expo-gaode-map-navigation
|
|
26
|
+
|
|
27
|
+
# or yarn
|
|
28
|
+
yarn add expo-gaode-map-navigation
|
|
29
|
+
|
|
30
|
+
# or pnpm
|
|
31
|
+
pnpm add expo-gaode-map-navigation
|
|
24
32
|
```
|
|
25
33
|
|
|
26
|
-
|
|
34
|
+
如果项目中已安装过核心地图包,请先移除避免冲突:
|
|
27
35
|
|
|
28
36
|
```bash
|
|
29
|
-
npm
|
|
37
|
+
npm uninstall expo-gaode-map
|
|
38
|
+
# or: yarn remove expo-gaode-map
|
|
39
|
+
# or: pnpm remove expo-gaode-map
|
|
30
40
|
```
|
|
31
41
|
|
|
32
|
-
|
|
42
|
+
## 初始化
|
|
33
43
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
在应用启动阶段初始化 SDK Key(Android/iOS 原生 Key 与可选的 Web API Key):
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { ExpoGaodeMapModule } from 'expo-gaode-map-navigation';
|
|
48
|
+
|
|
49
|
+
ExpoGaodeMapModule.initSDK({
|
|
50
|
+
androidKey: 'your-android-key',
|
|
51
|
+
iosKey: 'your-ios-key',
|
|
52
|
+
webKey: 'your-web-api-key', // 可选;若使用 Web API 包,建议一并下发
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
说明:
|
|
57
|
+
- 如后续使用 `expo-gaode-map-web-api`,建议同时传入 `webKey`,该包会从本模块运行时读取 `webKey`,实现“无参构造”的简化用法(new GaodeWebAPI())。
|
|
58
|
+
|
|
59
|
+
## 地图与导航基础用法
|
|
60
|
+
|
|
61
|
+
地图视图(内置地图能力):
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
import React from 'react';
|
|
65
|
+
import { View } from 'react-native';
|
|
66
|
+
import { MapView, Marker } from 'expo-gaode-map-navigation';
|
|
67
|
+
|
|
68
|
+
export default function BasicMapScreen() {
|
|
69
|
+
return (
|
|
70
|
+
<View style={{ flex: 1 }}>
|
|
71
|
+
<MapView
|
|
72
|
+
style={{ flex: 1 }}
|
|
73
|
+
initialCameraPosition={{
|
|
74
|
+
target: { latitude: 39.909186, longitude: 116.397411 },
|
|
75
|
+
zoom: 12,
|
|
76
|
+
}}
|
|
77
|
+
>
|
|
78
|
+
<Marker
|
|
79
|
+
position={{ latitude: 39.909186, longitude: 116.397411 }}
|
|
80
|
+
title="天安门"
|
|
81
|
+
snippet="北京·东城区"
|
|
82
|
+
/>
|
|
83
|
+
</MapView>
|
|
84
|
+
</View>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
路径规划与导航(示例):
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import { calculateRoute, DriveStrategy } from 'expo-gaode-map-navigation';
|
|
93
|
+
|
|
94
|
+
const result = await calculateRoute({
|
|
95
|
+
type: 'drive',
|
|
96
|
+
from: { latitude: 39.9, longitude: 116.4 },
|
|
97
|
+
to: { latitude: 39.91, longitude: 116.41 },
|
|
98
|
+
strategy: DriveStrategy.FASTEST,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// 结果包含距离/时长/分步指引等
|
|
37
102
|
```
|
|
38
103
|
|
|
39
|
-
|
|
104
|
+
说明:
|
|
105
|
+
- 地图组件与导航能力均来自 `expo-gaode-map-navigation`,无需、也不应从 `expo-gaode-map` 引入任何 API。
|
|
40
106
|
|
|
41
|
-
##
|
|
107
|
+
## 路径规划(原生与 Web API 双方案)
|
|
42
108
|
|
|
43
|
-
|
|
109
|
+
本模块同时支持“原生导航引擎路径规划”和“Web API 路径规划”,可按业务场景自由选择或组合使用:
|
|
110
|
+
|
|
111
|
+
- 原生方案(推荐用于移动端实时导航):端侧原生 SDK 能力,更适合实时引导、语音播报、复杂交通路况处理、弱网/离线等。
|
|
112
|
+
- Web API 方案(推荐用于快速查询/对比/多端一致):通过 `expo-gaode-map-web-api` 发起 HTTP 请求,便于统一计算逻辑、方案对比或与服务端配合。
|
|
113
|
+
|
|
114
|
+
原生方案示例:
|
|
115
|
+
```ts
|
|
44
116
|
import { calculateRoute, DriveStrategy } from 'expo-gaode-map-navigation';
|
|
45
117
|
|
|
46
|
-
// 驾车路径规划
|
|
47
118
|
const result = await calculateRoute({
|
|
48
119
|
type: 'drive',
|
|
49
120
|
from: { latitude: 39.9, longitude: 116.4 },
|
|
@@ -51,15 +122,33 @@ const result = await calculateRoute({
|
|
|
51
122
|
strategy: DriveStrategy.FASTEST,
|
|
52
123
|
});
|
|
53
124
|
|
|
54
|
-
|
|
55
|
-
console.log('时间:', result.duration, '秒');
|
|
56
|
-
console.log('路径点:', result.steps.length, '步');
|
|
125
|
+
// result 包含距离/时长/分步指引等原生返回
|
|
57
126
|
```
|
|
58
127
|
|
|
59
|
-
|
|
128
|
+
Web API 方案示例(需在初始化时提供 webKey):
|
|
129
|
+
```ts
|
|
130
|
+
import { GaodeWebAPI } from 'expo-gaode-map-web-api';
|
|
131
|
+
|
|
132
|
+
// 无参构造:从 expo-gaode-map-navigation 初始化中动态解析 webKey
|
|
133
|
+
const api = new GaodeWebAPI();
|
|
134
|
+
|
|
135
|
+
// 驾车路径规划(Web API)
|
|
136
|
+
const res = await api.route.driving('116.400000,39.900000', '116.410000,39.910000', {
|
|
137
|
+
show_fields: 'cost,navi',
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// res.route.paths[0] 中包含距离/时长/导航步骤等
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
选择建议:
|
|
144
|
+
- 实时导航/引导优先原生方案;
|
|
145
|
+
- 方案对比、批量测算、多端统一优先 Web API;也可结合两者,在端上落地选择逻辑。
|
|
146
|
+
|
|
147
|
+
## Android 注意事项
|
|
60
148
|
|
|
61
|
-
|
|
149
|
+
- 本模块内部使用 `navi-3dmap` 体系,已包含地图能力;请勿同时引入核心 `3dmap` 体系以免二进制冲突。
|
|
150
|
+
- 若历史项目从核心包迁移至本模块,务必移除 `expo-gaode-map` 依赖与其 native 配置(Gradle/CocoaPods 链接等)。
|
|
62
151
|
|
|
63
|
-
##
|
|
152
|
+
## 许可
|
|
64
153
|
|
|
65
154
|
MIT
|
|
@@ -32,6 +32,13 @@ class ExpoGaodeMapModule : Module() {
|
|
|
32
32
|
override fun definition() = ModuleDefinition {
|
|
33
33
|
Name("NaviMap")
|
|
34
34
|
|
|
35
|
+
// 在模块加载时尝试从本地缓存恢复隐私同意状态,避免每次启动都必须 JS 调用
|
|
36
|
+
try {
|
|
37
|
+
SDKInitializer.restorePrivacyState(appContext.reactContext!!)
|
|
38
|
+
} catch (e: Exception) {
|
|
39
|
+
android.util.Log.w("ExpoGaodeMap", "恢复隐私状态时出现问题: ${e.message}")
|
|
40
|
+
}
|
|
41
|
+
|
|
35
42
|
// ==================== 隐私合规管理 ====================
|
|
36
43
|
|
|
37
44
|
/**
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
package expo.modules.gaodemap.map.modules
|
|
2
2
|
|
|
3
3
|
import android.content.Context
|
|
4
|
+
import android.content.SharedPreferences
|
|
4
5
|
import com.amap.api.location.AMapLocationClient
|
|
5
6
|
import com.amap.api.maps.MapsInitializer
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* SDK 初始化管理器
|
|
9
|
-
*
|
|
10
|
+
*
|
|
10
11
|
* 负责:
|
|
11
12
|
* - 初始化高德地图 SDK
|
|
12
13
|
* - 初始化高德定位 SDK
|
|
@@ -15,8 +16,14 @@ import com.amap.api.maps.MapsInitializer
|
|
|
15
16
|
*/
|
|
16
17
|
object SDKInitializer {
|
|
17
18
|
|
|
18
|
-
/**
|
|
19
|
+
/** 隐私协议是否已同意(进程内缓存) */
|
|
19
20
|
private var privacyAgreed = false
|
|
21
|
+
|
|
22
|
+
private const val PREFS_NAME = "expo_gaode_map_prefs"
|
|
23
|
+
private const val KEY_PRIVACY_AGREED = "privacy_agreed"
|
|
24
|
+
|
|
25
|
+
private fun prefs(context: Context): SharedPreferences =
|
|
26
|
+
context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
|
|
20
27
|
|
|
21
28
|
/**
|
|
22
29
|
* 更新隐私合规状态
|
|
@@ -42,8 +49,36 @@ object SDKInitializer {
|
|
|
42
49
|
AMapLocationClient.updatePrivacyAgree(context, false)
|
|
43
50
|
android.util.Log.w("ExpoGaodeMap", "⚠️ 用户未同意隐私协议,SDK 功能将受限")
|
|
44
51
|
}
|
|
52
|
+
|
|
53
|
+
// 持久化状态,供下次启动自动恢复
|
|
54
|
+
try {
|
|
55
|
+
prefs(context).edit().putBoolean(KEY_PRIVACY_AGREED, hasAgreed).apply()
|
|
56
|
+
} catch (e: Exception) {
|
|
57
|
+
android.util.Log.w("ExpoGaodeMap", "持久化隐私状态失败: ${e.message}")
|
|
58
|
+
}
|
|
45
59
|
}
|
|
46
60
|
|
|
61
|
+
/**
|
|
62
|
+
* 从本地存储恢复隐私合规状态(在应用启动或模块加载时调用)
|
|
63
|
+
* 若无记录则保持默认 false,不抛出异常。
|
|
64
|
+
*/
|
|
65
|
+
fun restorePrivacyState(context: Context) {
|
|
66
|
+
try {
|
|
67
|
+
val saved = prefs(context).getBoolean(KEY_PRIVACY_AGREED, false)
|
|
68
|
+
privacyAgreed = saved
|
|
69
|
+
|
|
70
|
+
// 同步到 SDK
|
|
71
|
+
MapsInitializer.updatePrivacyShow(context, true, true)
|
|
72
|
+
AMapLocationClient.updatePrivacyShow(context, true, true)
|
|
73
|
+
MapsInitializer.updatePrivacyAgree(context, saved)
|
|
74
|
+
AMapLocationClient.updatePrivacyAgree(context, saved)
|
|
75
|
+
|
|
76
|
+
android.util.Log.d("ExpoGaodeMap", "🔁 已从缓存恢复隐私状态: $saved")
|
|
77
|
+
} catch (e: Exception) {
|
|
78
|
+
android.util.Log.w("ExpoGaodeMap", "恢复隐私状态失败: ${e.message}")
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
47
82
|
/**
|
|
48
83
|
* 检查隐私协议是否已同意
|
|
49
84
|
*
|
|
@@ -79,7 +114,7 @@ object SDKInitializer {
|
|
|
79
114
|
|
|
80
115
|
/**
|
|
81
116
|
* 获取 SDK 版本号
|
|
82
|
-
*
|
|
117
|
+
*
|
|
83
118
|
* @return SDK 版本字符串
|
|
84
119
|
*/
|
|
85
120
|
fun getVersion(): String {
|
|
@@ -13,11 +13,11 @@ try {
|
|
|
13
13
|
nativeModule = (0, expo_1.requireNativeModule)('NaviMap');
|
|
14
14
|
}
|
|
15
15
|
catch (error) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
// 原生模块加载失败时的静默处理
|
|
17
|
+
// 这是正常的,因为 navigation 包可以独立使用,不一定需要完整的地图功能
|
|
18
|
+
if (__DEV__) {
|
|
19
|
+
console.warn('[expo-gaode-map-navigation] NaviMap 原生模块未加载,地图相关功能将不可用');
|
|
20
|
+
}
|
|
21
21
|
}
|
|
22
22
|
// 记录最近一次 initSDK 的配置(含 webKey)
|
|
23
23
|
let _sdkConfig = null;
|
|
@@ -18,16 +18,27 @@ public class NaviMapModule: Module {
|
|
|
18
18
|
private var permissionManager: PermissionManager?
|
|
19
19
|
/// 隐私协议是否已同意(模块级别跟踪)
|
|
20
20
|
private static var privacyAgreed: Bool = false
|
|
21
|
+
/// 隐私同意持久化 Key
|
|
22
|
+
private static let privacyDefaultsKey = "expo_gaode_map_privacy_agreed"
|
|
21
23
|
|
|
22
24
|
public func definition() -> ModuleDefinition {
|
|
23
25
|
Name("NaviMap")
|
|
24
26
|
|
|
25
|
-
//
|
|
26
|
-
// 需要在用户同意隐私协议后手动调用 updatePrivacyCompliance 方法
|
|
27
|
+
// 模块初始化:尝试从本地缓存恢复隐私同意状态
|
|
27
28
|
OnCreate {
|
|
28
|
-
//
|
|
29
|
+
// 先确保隐私信息展示状态
|
|
29
30
|
MAMapView.updatePrivacyShow(AMapPrivacyShowStatus.didShow, privacyInfo: AMapPrivacyInfoStatus.didContain)
|
|
30
|
-
|
|
31
|
+
|
|
32
|
+
// 从 UserDefaults 恢复上次的同意状态(默认 false)
|
|
33
|
+
let saved = UserDefaults.standard.bool(forKey: NaviMapModule.privacyDefaultsKey)
|
|
34
|
+
NaviMapModule.privacyAgreed = saved
|
|
35
|
+
if saved {
|
|
36
|
+
// 同步到 SDK
|
|
37
|
+
MAMapView.updatePrivacyAgree(AMapPrivacyAgreeStatus.didAgree)
|
|
38
|
+
print("🔁 ExpoGaodeMap: 已从缓存恢复隐私同意状态: true")
|
|
39
|
+
} else {
|
|
40
|
+
print("ℹ️ ExpoGaodeMap: 未发现已同意记录,等待用户同意后再使用 SDK")
|
|
41
|
+
}
|
|
31
42
|
}
|
|
32
43
|
|
|
33
44
|
// ==================== 隐私合规管理 ====================
|
|
@@ -37,10 +48,15 @@ public class NaviMapModule: Module {
|
|
|
37
48
|
* 必须在用户同意隐私协议后调用
|
|
38
49
|
*/
|
|
39
50
|
Function("updatePrivacyCompliance") { (hasAgreed: Bool) in
|
|
51
|
+
// 更新内存状态
|
|
40
52
|
NaviMapModule.privacyAgreed = hasAgreed
|
|
53
|
+
// 持久化到本地,供下次启动自动恢复
|
|
54
|
+
UserDefaults.standard.set(hasAgreed, forKey: NaviMapModule.privacyDefaultsKey)
|
|
55
|
+
|
|
41
56
|
if hasAgreed {
|
|
57
|
+
// 同步到 SDK
|
|
42
58
|
MAMapView.updatePrivacyAgree(AMapPrivacyAgreeStatus.didAgree)
|
|
43
|
-
print("✅ ExpoGaodeMap: 用户已同意隐私协议,可以使用 SDK")
|
|
59
|
+
print("✅ ExpoGaodeMap: 用户已同意隐私协议,可以使用 SDK(状态已持久化)")
|
|
44
60
|
|
|
45
61
|
// 在用户同意后,如果尚未设置 API Key,则尝试从 Info.plist 读取并设置
|
|
46
62
|
if AMapServices.shared().apiKey == nil || AMapServices.shared().apiKey?.isEmpty == true {
|
|
@@ -54,7 +70,7 @@ public class NaviMapModule: Module {
|
|
|
54
70
|
}
|
|
55
71
|
} else {
|
|
56
72
|
MAMapView.updatePrivacyAgree(AMapPrivacyAgreeStatus.notAgree)
|
|
57
|
-
print("⚠️ ExpoGaodeMap: 用户未同意隐私协议,SDK
|
|
73
|
+
print("⚠️ ExpoGaodeMap: 用户未同意隐私协议,SDK 功能将受限(状态已持久化)")
|
|
58
74
|
}
|
|
59
75
|
}
|
|
60
76
|
|
package/package.json
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-gaode-map-navigation",
|
|
3
|
-
"version": "1.0.1-next.
|
|
4
|
-
"description": "高德地图导航功能模块 -
|
|
5
|
-
"main": "
|
|
6
|
-
"types": "
|
|
3
|
+
"version": "1.0.1-next.2",
|
|
4
|
+
"description": "高德地图导航功能模块 - 路径规划、导航引导,独立版本包含完整地图功能",
|
|
5
|
+
"main": "build/index.js",
|
|
6
|
+
"types": "build/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"build",
|
|
9
|
+
"android",
|
|
10
|
+
"ios",
|
|
11
|
+
"app.plugin.js",
|
|
12
|
+
"expo-module.config.json"
|
|
13
|
+
],
|
|
7
14
|
"keywords": [
|
|
8
15
|
"react-native",
|
|
9
16
|
"expo",
|
|
@@ -22,7 +29,7 @@
|
|
|
22
29
|
"license": "MIT",
|
|
23
30
|
"homepage": "https://github.com/TomWq/expo-gaode-map#readme",
|
|
24
31
|
"dependencies": {
|
|
25
|
-
"
|
|
32
|
+
"supercluster": "^8.0.1"
|
|
26
33
|
},
|
|
27
34
|
"devDependencies": {
|
|
28
35
|
"@types/react": "~19.1.0",
|
|
@@ -37,7 +44,7 @@
|
|
|
37
44
|
"react-native": "*"
|
|
38
45
|
},
|
|
39
46
|
"scripts": {
|
|
40
|
-
"build": "expo-module build",
|
|
47
|
+
"build": "expo-module build && pnpm run build:plugin",
|
|
41
48
|
"build:plugin": "tsc --project plugin/tsconfig.json",
|
|
42
49
|
"clean": "expo-module clean",
|
|
43
50
|
"lint": "expo-module lint",
|
package/package.json.backup
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "expo-gaode-map-navigation",
|
|
3
|
-
"version": "1.0.0-beta.0",
|
|
4
|
-
"description": "高德地图导航功能模块 - 路径规划、导航引导,基于expo-gaode-map",
|
|
5
|
-
"main": "src/index.ts",
|
|
6
|
-
"types": "src/index.d.ts",
|
|
7
|
-
"scripts": {
|
|
8
|
-
"build": "expo-module build",
|
|
9
|
-
"build:plugin": "tsc --project plugin/tsconfig.json",
|
|
10
|
-
"clean": "expo-module clean",
|
|
11
|
-
"lint": "expo-module lint",
|
|
12
|
-
"test": "expo-module test",
|
|
13
|
-
"prepare": "expo-module prepare",
|
|
14
|
-
"prepublishOnly": "expo-module prepublishOnly",
|
|
15
|
-
"expo-module": "expo-module"
|
|
16
|
-
},
|
|
17
|
-
"keywords": [
|
|
18
|
-
"react-native",
|
|
19
|
-
"expo",
|
|
20
|
-
"expo-gaode-map",
|
|
21
|
-
"amap",
|
|
22
|
-
"navigation",
|
|
23
|
-
"route",
|
|
24
|
-
"高德地图",
|
|
25
|
-
"导航"
|
|
26
|
-
],
|
|
27
|
-
"repository": "https://github.com/TomWq/expo-gaode-map",
|
|
28
|
-
"bugs": {
|
|
29
|
-
"url": "https://github.com/TomWq/expo-gaode-map/issues"
|
|
30
|
-
},
|
|
31
|
-
"author": "尚博信_王强 <wangqiang03@sunboxsoft.com> (https://github.com/TomWq)",
|
|
32
|
-
"license": "MIT",
|
|
33
|
-
"homepage": "https://github.com/TomWq/expo-gaode-map#readme",
|
|
34
|
-
"dependencies": {},
|
|
35
|
-
"devDependencies": {
|
|
36
|
-
"@types/react": "~19.1.0",
|
|
37
|
-
"expo": "^54.0.18",
|
|
38
|
-
"expo-module-scripts": "^5.0.7",
|
|
39
|
-
"react-native": "0.81.5",
|
|
40
|
-
"typescript": "^5.9.3"
|
|
41
|
-
},
|
|
42
|
-
"peerDependencies": {
|
|
43
|
-
"expo": "*",
|
|
44
|
-
"react": "*",
|
|
45
|
-
"react-native": "*"
|
|
46
|
-
}
|
|
47
|
-
}
|
package/plugin/README.md
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
# Expo Config Plugin for expo-gaode-map
|
|
2
|
-
|
|
3
|
-
这是 `expo-gaode-map` 的 Expo Config Plugin 实现。
|
|
4
|
-
|
|
5
|
-
## 功能
|
|
6
|
-
|
|
7
|
-
- 自动配置 iOS 和 Android 平台的高德地图 API Key
|
|
8
|
-
- 自动添加定位权限
|
|
9
|
-
- 自动初始化高德地图 SDK
|
|
10
|
-
|
|
11
|
-
## 开发
|
|
12
|
-
|
|
13
|
-
### 构建插件
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
npm run build:plugin
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
### 目录结构
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
plugin/
|
|
23
|
-
├── src/
|
|
24
|
-
│ └── withGaodeMap.ts # 插件源代码
|
|
25
|
-
├── build/ # 编译输出目录
|
|
26
|
-
├── tsconfig.json # TypeScript 配置
|
|
27
|
-
└── README.md # 本文件
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## 使用方法
|
|
31
|
-
|
|
32
|
-
请查看主文档: [CONFIG_PLUGIN.md](../docs/CONFIG_PLUGIN.md)
|
|
33
|
-
|
|
34
|
-
## 技术细节
|
|
35
|
-
|
|
36
|
-
### 修改的文件
|
|
37
|
-
|
|
38
|
-
**iOS:**
|
|
39
|
-
- `Info.plist` - 添加 API Key 和权限
|
|
40
|
-
- `AppDelegate.m` - 添加 SDK 初始化代码
|
|
41
|
-
|
|
42
|
-
**Android:**
|
|
43
|
-
- `AndroidManifest.xml` - 添加 API Key 和权限
|
|
44
|
-
|
|
45
|
-
### 依赖
|
|
46
|
-
|
|
47
|
-
- `@expo/config-plugins` - Expo 配置插件核心库
|
|
48
|
-
|
|
49
|
-
## 参考
|
|
50
|
-
|
|
51
|
-
- [Expo Config Plugins](https://docs.expo.dev/config-plugins/introduction/)
|
|
52
|
-
- [Creating a Config Plugin](https://docs.expo.dev/config-plugins/plugins-and-mods/)
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { ConfigPlugin } from '@expo/config-plugins';
|
|
2
|
-
/**
|
|
3
|
-
* 高德地图插件配置类型
|
|
4
|
-
*/
|
|
5
|
-
export type GaodeMapPluginProps = {
|
|
6
|
-
/** iOS 平台 API Key */
|
|
7
|
-
iosApiKey?: string;
|
|
8
|
-
/** Android 平台 API Key */
|
|
9
|
-
androidApiKey?: string;
|
|
10
|
-
/** 是否启用定位功能 */
|
|
11
|
-
enableLocation?: boolean;
|
|
12
|
-
/** iOS 定位权限描述 */
|
|
13
|
-
locationDescription?: string;
|
|
14
|
-
/** 是否启用后台定位(Android & iOS) */
|
|
15
|
-
enableBackgroundLocation?: boolean;
|
|
16
|
-
};
|
|
17
|
-
/**
|
|
18
|
-
* 导出为可运行一次的插件
|
|
19
|
-
* 这确保插件只会运行一次,即使在配置中被多次引用
|
|
20
|
-
*/
|
|
21
|
-
declare const _default: ConfigPlugin<GaodeMapPluginProps>;
|
|
22
|
-
export default _default;
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const config_plugins_1 = require("@expo/config-plugins");
|
|
4
|
-
/**
|
|
5
|
-
* iOS: 修改 Info.plist 添加 API Key 和权限
|
|
6
|
-
*/
|
|
7
|
-
const withGaodeMapInfoPlist = (config, props) => {
|
|
8
|
-
return (0, config_plugins_1.withInfoPlist)(config, (config) => {
|
|
9
|
-
// 添加高德地图 API Key
|
|
10
|
-
if (props.iosApiKey) {
|
|
11
|
-
config.modResults.AMapApiKey = props.iosApiKey;
|
|
12
|
-
}
|
|
13
|
-
// 添加定位相关权限
|
|
14
|
-
if (props.enableLocation !== false) {
|
|
15
|
-
const description = props.locationDescription || '需要访问您的位置信息以提供地图服务';
|
|
16
|
-
// 使用时定位权限(必需)
|
|
17
|
-
config.modResults.NSLocationWhenInUseUsageDescription = description;
|
|
18
|
-
// 后台定位权限(可选)
|
|
19
|
-
if (props.enableBackgroundLocation) {
|
|
20
|
-
config.modResults.NSLocationAlwaysUsageDescription = description;
|
|
21
|
-
config.modResults.NSLocationAlwaysAndWhenInUseUsageDescription = description;
|
|
22
|
-
// 添加后台定位模式
|
|
23
|
-
if (!config.modResults.UIBackgroundModes) {
|
|
24
|
-
config.modResults.UIBackgroundModes = [];
|
|
25
|
-
}
|
|
26
|
-
if (!config.modResults.UIBackgroundModes.includes('location')) {
|
|
27
|
-
config.modResults.UIBackgroundModes.push('location');
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return config;
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
|
-
/**
|
|
35
|
-
* iOS: 注意 - 不再需要修改 AppDelegate
|
|
36
|
-
*
|
|
37
|
-
* 高德地图 SDK 已经支持从 Info.plist 自动读取 API Key
|
|
38
|
-
* 并且我们在 ExpoGaodeMapModule.swift 中提供了 initSDK 方法
|
|
39
|
-
* 用户可以选择以下任一方式初始化:
|
|
40
|
-
* 1. 通过 Info.plist 中的 AMapApiKey 字段(自动读取)
|
|
41
|
-
* 2. 通过 JavaScript 调用 ExpoGaodeMap.initSDK({ iosKey: 'your-key' })
|
|
42
|
-
*/
|
|
43
|
-
/**
|
|
44
|
-
* Android: 修改 AndroidManifest.xml 添加 API Key 和权限
|
|
45
|
-
*/
|
|
46
|
-
const withGaodeMapAndroidManifest = (config, props) => {
|
|
47
|
-
return (0, config_plugins_1.withAndroidManifest)(config, (config) => {
|
|
48
|
-
const androidManifest = config.modResults.manifest;
|
|
49
|
-
// 添加基础权限(高德地图 SDK 必需)
|
|
50
|
-
const basePermissions = [
|
|
51
|
-
'android.permission.ACCESS_COARSE_LOCATION',
|
|
52
|
-
'android.permission.ACCESS_FINE_LOCATION',
|
|
53
|
-
'android.permission.ACCESS_NETWORK_STATE',
|
|
54
|
-
'android.permission.ACCESS_WIFI_STATE',
|
|
55
|
-
'android.permission.READ_PHONE_STATE',
|
|
56
|
-
'android.permission.BLUETOOTH',
|
|
57
|
-
'android.permission.BLUETOOTH_ADMIN',
|
|
58
|
-
];
|
|
59
|
-
if (!androidManifest['uses-permission']) {
|
|
60
|
-
androidManifest['uses-permission'] = [];
|
|
61
|
-
}
|
|
62
|
-
basePermissions.forEach((permission) => {
|
|
63
|
-
const hasPermission = androidManifest['uses-permission']?.some((item) => item.$?.['android:name'] === permission);
|
|
64
|
-
if (!hasPermission) {
|
|
65
|
-
androidManifest['uses-permission']?.push({
|
|
66
|
-
$: { 'android:name': permission },
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
// 后台定位权限(可选,仅在 enableBackgroundLocation 为 true 时添加)
|
|
71
|
-
if (props.enableBackgroundLocation) {
|
|
72
|
-
const backgroundPermissions = [
|
|
73
|
-
'android.permission.ACCESS_BACKGROUND_LOCATION',
|
|
74
|
-
'android.permission.FOREGROUND_SERVICE',
|
|
75
|
-
'android.permission.FOREGROUND_SERVICE_LOCATION',
|
|
76
|
-
];
|
|
77
|
-
if (!androidManifest['uses-permission']) {
|
|
78
|
-
androidManifest['uses-permission'] = [];
|
|
79
|
-
}
|
|
80
|
-
backgroundPermissions.forEach((permission) => {
|
|
81
|
-
const hasPermission = androidManifest['uses-permission']?.some((item) => item.$?.['android:name'] === permission);
|
|
82
|
-
if (!hasPermission) {
|
|
83
|
-
androidManifest['uses-permission']?.push({
|
|
84
|
-
$: { 'android:name': permission },
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
// 添加前台服务(如果启用后台定位)
|
|
90
|
-
const mainApplication = androidManifest.application?.[0];
|
|
91
|
-
if (mainApplication && props.enableBackgroundLocation) {
|
|
92
|
-
if (!mainApplication['service']) {
|
|
93
|
-
mainApplication['service'] = [];
|
|
94
|
-
}
|
|
95
|
-
// 检查是否已存在 LocationForegroundService
|
|
96
|
-
const hasService = mainApplication['service'].some((item) => item.$?.['android:name'] === 'expo.modules.gaodemap.services.LocationForegroundService');
|
|
97
|
-
if (!hasService) {
|
|
98
|
-
mainApplication['service'].push({
|
|
99
|
-
$: {
|
|
100
|
-
'android:name': 'expo.modules.gaodemap.services.LocationForegroundService',
|
|
101
|
-
'android:enabled': 'true',
|
|
102
|
-
'android:exported': 'false',
|
|
103
|
-
'android:foregroundServiceType': 'location',
|
|
104
|
-
},
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
// 添加 API Key 到 application 标签
|
|
109
|
-
if (mainApplication && props.androidApiKey) {
|
|
110
|
-
if (!mainApplication['meta-data']) {
|
|
111
|
-
mainApplication['meta-data'] = [];
|
|
112
|
-
}
|
|
113
|
-
// 检查是否已存在
|
|
114
|
-
const hasApiKey = mainApplication['meta-data'].some((item) => item.$?.['android:name'] === 'com.amap.api.v2.apikey');
|
|
115
|
-
if (!hasApiKey) {
|
|
116
|
-
mainApplication['meta-data'].push({
|
|
117
|
-
$: {
|
|
118
|
-
'android:name': 'com.amap.api.v2.apikey',
|
|
119
|
-
'android:value': props.androidApiKey,
|
|
120
|
-
},
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
// 更新现有的 API Key
|
|
125
|
-
const apiKeyIndex = mainApplication['meta-data'].findIndex((item) => item.$?.['android:name'] === 'com.amap.api.v2.apikey');
|
|
126
|
-
if (apiKeyIndex !== -1) {
|
|
127
|
-
mainApplication['meta-data'][apiKeyIndex].$ = {
|
|
128
|
-
'android:name': 'com.amap.api.v2.apikey',
|
|
129
|
-
'android:value': props.androidApiKey,
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return config;
|
|
135
|
-
});
|
|
136
|
-
};
|
|
137
|
-
/**
|
|
138
|
-
* Android: 修改 app/build.gradle(预留扩展)
|
|
139
|
-
*/
|
|
140
|
-
const withGaodeMapAppBuildGradle = (config, props) => {
|
|
141
|
-
return (0, config_plugins_1.withAppBuildGradle)(config, (config) => {
|
|
142
|
-
// Android 3D 地图 SDK 10.0+ 已内置搜索功能
|
|
143
|
-
// 不需要额外的 Gradle 配置
|
|
144
|
-
return config;
|
|
145
|
-
});
|
|
146
|
-
};
|
|
147
|
-
/**
|
|
148
|
-
* 主插件函数 - 组合所有修改器
|
|
149
|
-
*/
|
|
150
|
-
const withGaodeMap = (config, props = {}) => {
|
|
151
|
-
// 验证配置
|
|
152
|
-
if (!props.iosApiKey && !props.androidApiKey) {
|
|
153
|
-
config_plugins_1.WarningAggregator.addWarningIOS('expo-gaode-map-navigation', '未配置 API Key。请在 app.json 的 plugins 中配置 iosApiKey 和 androidApiKey');
|
|
154
|
-
}
|
|
155
|
-
// 应用 iOS 配置
|
|
156
|
-
config = withGaodeMapInfoPlist(config, props);
|
|
157
|
-
// 注意:不再需要修改 AppDelegate,因为:
|
|
158
|
-
// 1. SDK 会自动从 Info.plist 读取 AMapApiKey
|
|
159
|
-
// 2. 可以通过 ExpoGaodeMapModule.initSDK() 方法初始化
|
|
160
|
-
// 应用 Android 配置
|
|
161
|
-
config = withGaodeMapAndroidManifest(config, props);
|
|
162
|
-
config = withGaodeMapAppBuildGradle(config, props);
|
|
163
|
-
return config;
|
|
164
|
-
};
|
|
165
|
-
/**
|
|
166
|
-
* 导出为可运行一次的插件
|
|
167
|
-
* 这确保插件只会运行一次,即使在配置中被多次引用
|
|
168
|
-
*/
|
|
169
|
-
exports.default = (0, config_plugins_1.createRunOncePlugin)(withGaodeMap, 'expo-gaode-map-navigation', '1.0.0');
|