expo-gaode-map-navigation 2.0.3 → 2.0.4-next.0

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.
Files changed (63) hide show
  1. package/android/build.gradle +3 -0
  2. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapModule.kt +32 -50
  3. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapView.kt +5 -15
  4. package/android/src/main/java/expo/modules/gaodemap/map/modules/SDKInitializer.kt +41 -14
  5. package/build/ExpoGaodeMapNaviView.d.ts.map +1 -1
  6. package/build/ExpoGaodeMapNaviView.js +3 -2
  7. package/build/ExpoGaodeMapNaviView.js.map +1 -1
  8. package/build/ExpoGaodeMapNavigationModule.d.ts +2 -7
  9. package/build/ExpoGaodeMapNavigationModule.d.ts.map +1 -1
  10. package/build/ExpoGaodeMapNavigationModule.js +12 -2
  11. package/build/ExpoGaodeMapNavigationModule.js.map +1 -1
  12. package/build/map/ExpoGaodeMapModule.d.ts.map +1 -1
  13. package/build/map/ExpoGaodeMapModule.js +154 -16
  14. package/build/map/ExpoGaodeMapModule.js.map +1 -1
  15. package/build/map/ExpoGaodeMapOfflineModule.d.ts.map +1 -1
  16. package/build/map/ExpoGaodeMapOfflineModule.js +12 -2
  17. package/build/map/ExpoGaodeMapOfflineModule.js.map +1 -1
  18. package/build/map/ExpoGaodeMapView.d.ts.map +1 -1
  19. package/build/map/ExpoGaodeMapView.js +8 -2
  20. package/build/map/ExpoGaodeMapView.js.map +1 -1
  21. package/build/map/components/overlays/Circle.d.ts.map +1 -1
  22. package/build/map/components/overlays/Circle.js +3 -2
  23. package/build/map/components/overlays/Circle.js.map +1 -1
  24. package/build/map/components/overlays/Cluster.d.ts.map +1 -1
  25. package/build/map/components/overlays/Cluster.js +3 -2
  26. package/build/map/components/overlays/Cluster.js.map +1 -1
  27. package/build/map/components/overlays/HeatMap.d.ts.map +1 -1
  28. package/build/map/components/overlays/HeatMap.js +3 -2
  29. package/build/map/components/overlays/HeatMap.js.map +1 -1
  30. package/build/map/components/overlays/Marker.d.ts.map +1 -1
  31. package/build/map/components/overlays/Marker.js +3 -2
  32. package/build/map/components/overlays/Marker.js.map +1 -1
  33. package/build/map/components/overlays/MultiPoint.d.ts.map +1 -1
  34. package/build/map/components/overlays/MultiPoint.js +3 -2
  35. package/build/map/components/overlays/MultiPoint.js.map +1 -1
  36. package/build/map/components/overlays/Polygon.d.ts.map +1 -1
  37. package/build/map/components/overlays/Polygon.js +3 -2
  38. package/build/map/components/overlays/Polygon.js.map +1 -1
  39. package/build/map/components/overlays/Polyline.d.ts.map +1 -1
  40. package/build/map/components/overlays/Polyline.js +3 -2
  41. package/build/map/components/overlays/Polyline.js.map +1 -1
  42. package/build/map/types/common.types.d.ts +6 -0
  43. package/build/map/types/common.types.d.ts.map +1 -1
  44. package/build/map/types/common.types.js.map +1 -1
  45. package/build/map/types/native-module.types.d.ts +4 -1
  46. package/build/map/types/native-module.types.d.ts.map +1 -1
  47. package/build/map/types/native-module.types.js.map +1 -1
  48. package/build/map/utils/ErrorHandler.d.ts +6 -0
  49. package/build/map/utils/ErrorHandler.d.ts.map +1 -1
  50. package/build/map/utils/ErrorHandler.js +31 -0
  51. package/build/map/utils/ErrorHandler.js.map +1 -1
  52. package/build/map/utils/lazyNativeViewManager.d.ts +3 -0
  53. package/build/map/utils/lazyNativeViewManager.d.ts.map +1 -0
  54. package/build/map/utils/lazyNativeViewManager.js +11 -0
  55. package/build/map/utils/lazyNativeViewManager.js.map +1 -0
  56. package/ios/ExpoGaodeMapNavigation.podspec +5 -0
  57. package/ios/map/ExpoGaodeMapModule.swift +20 -42
  58. package/ios/map/ExpoGaodeMapView.swift +160 -77
  59. package/ios/map/GaodeMapPrivacyManager.swift +65 -0
  60. package/ios/map/modules/LocationManager.swift +43 -24
  61. package/package.json +1 -1
  62. package/android/src/main/java/expo/modules/gaodemap/map/MapPreloadManager.kt +0 -494
  63. package/ios/map/MapPreloadManager.swift +0 -348
@@ -27,6 +27,9 @@ if (useManagedAndroidSdkVersions) {
27
27
  }
28
28
  }
29
29
 
30
+ logger.warn("[expo-gaode-map-navigation] Thank you for using expo-gaode-map-navigation ❤️")
31
+ logger.warn("[expo-gaode-map-navigation] If you enjoy using expo-gaode-map-navigation, please consider sponsoring this project: https://github.com/TomWq")
32
+
30
33
  android {
31
34
  namespace "expo.modules.gaodemap.navigation"
32
35
  defaultConfig {
@@ -30,42 +30,6 @@ class ExpoGaodeMapModule : Module() {
30
30
  override fun definition() = ModuleDefinition {
31
31
  Name("ExpoGaodeMap")
32
32
 
33
- // 在模块加载时尝试从本地缓存恢复隐私同意状态,避免每次启动都必须 JS 调用
34
- try {
35
- val context = appContext.reactContext!!
36
- SDKInitializer.restorePrivacyState(context)
37
-
38
- // 初始化预加载管理器(注册内存监听)
39
- MapPreloadManager.initialize(context)
40
-
41
- // 尝试从 AndroidManifest.xml 读取并设置 API Key
42
- val apiKey = context.packageManager
43
- .getApplicationInfo(context.packageName, android.content.pm.PackageManager.GET_META_DATA)
44
- .metaData?.getString("com.amap.api.v2.apikey")
45
-
46
- if (!apiKey.isNullOrEmpty()) {
47
- try {
48
- MapsInitializer.setApiKey(apiKey)
49
- com.amap.api.location.AMapLocationClient.setApiKey(apiKey)
50
-
51
-
52
- // 只有在 API Key 已设置的情况下才启动预加载
53
- android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({
54
- android.util.Log.i("ExpoGaodeMap", "🚀 自动启动地图预加载")
55
- MapPreloadManager.startPreload(context, poolSize = 1)
56
- }, 2000)
57
- } catch (e: Exception) {
58
- android.util.Log.w("ExpoGaodeMap", "设置 API Key 失败: ${e.message}")
59
- }
60
- } else {
61
- android.util.Log.w("ExpoGaodeMap", "⚠️ AndroidManifest.xml 未找到 API Key,跳过自动预加载")
62
- }
63
-
64
- } catch (e: Exception) {
65
- android.util.Log.w("ExpoGaodeMap", "恢复隐私状态时出现问题: ${e.message}")
66
- }
67
-
68
-
69
33
  // ==================== SDK 初始化 ====================
70
34
 
71
35
  /**
@@ -74,23 +38,42 @@ class ExpoGaodeMapModule : Module() {
74
38
  */
75
39
  Function("initSDK") { config: Map<String, String> ->
76
40
  val androidKey = config["androidKey"]
77
- if (androidKey != null) {
78
- try {
79
- SDKInitializer.initSDK(appContext.reactContext!!, androidKey)
80
- getLocationManager() // 初始化定位管理器
81
-
82
- // 初始化成功后自动触发一次预加载
83
- MapPreloadManager.startPreload(appContext.reactContext!!, poolSize = 1)
84
- } catch (e: SecurityException) {
85
- android.util.Log.e("ExpoGaodeMap", "隐私协议未同意: ${e.message}")
86
- throw expo.modules.kotlin.exception.CodedException("PRIVACY_NOT_AGREED", e.message ?: "用户未同意隐私协议", e)
87
- } catch (e: Exception) {
88
- android.util.Log.e("ExpoGaodeMap", "SDK 初始化失败: ${e.message}")
89
- throw expo.modules.kotlin.exception.CodedException("INIT_FAILED", e.message ?: "SDK 初始化失败", e)
41
+ try {
42
+ val context = appContext.reactContext!!
43
+ if (androidKey != null) {
44
+ SDKInitializer.initSDK(context, androidKey)
45
+ } else if (!SDKInitializer.isPrivacyReady()) {
46
+ throw expo.modules.kotlin.exception.CodedException(
47
+ "PRIVACY_NOT_AGREED",
48
+ "隐私协议未完成确认,请先调用 setPrivacyShow/setPrivacyAgree",
49
+ null
50
+ )
51
+ } else {
52
+ SDKInitializer.applyPrivacyState(context)
90
53
  }
54
+
55
+ getLocationManager()
56
+ } catch (e: SecurityException) {
57
+ android.util.Log.e("ExpoGaodeMap", "隐私协议未同意: ${e.message}")
58
+ throw expo.modules.kotlin.exception.CodedException("PRIVACY_NOT_AGREED", e.message ?: "用户未同意隐私协议", e)
59
+ } catch (e: Exception) {
60
+ android.util.Log.e("ExpoGaodeMap", "SDK 初始化失败: ${e.message}")
61
+ throw expo.modules.kotlin.exception.CodedException("INIT_FAILED", e.message ?: "SDK 初始化失败", e)
91
62
  }
92
63
  }
93
64
 
65
+ Function("setPrivacyShow") { hasShow: Boolean, hasContainsPrivacy: Boolean ->
66
+ SDKInitializer.setPrivacyShow(appContext.reactContext!!, hasShow, hasContainsPrivacy)
67
+ }
68
+
69
+ Function("setPrivacyAgree") { hasAgree: Boolean ->
70
+ SDKInitializer.setPrivacyAgree(appContext.reactContext!!, hasAgree)
71
+ }
72
+
73
+ Function("getPrivacyStatus") {
74
+ SDKInitializer.getPrivacyStatus()
75
+ }
76
+
94
77
  /**
95
78
  * 设置是否加载世界向量地图
96
79
  * @param enable 是否开启
@@ -890,7 +873,6 @@ class ExpoGaodeMapModule : Module() {
890
873
  OnDestroy {
891
874
  locationManager?.destroy()
892
875
  locationManager = null
893
- MapPreloadManager.cleanup()
894
876
  }
895
877
  }
896
878
 
@@ -13,6 +13,7 @@ import expo.modules.kotlin.viewevent.EventDispatcher
13
13
  import expo.modules.kotlin.views.ExpoView
14
14
  import expo.modules.gaodemap.map.managers.CameraManager
15
15
  import expo.modules.gaodemap.map.managers.UIManager
16
+ import expo.modules.gaodemap.map.modules.SDKInitializer
16
17
  import expo.modules.gaodemap.map.overlays.*
17
18
  import androidx.core.graphics.createBitmap
18
19
  import androidx.core.view.isVisible
@@ -93,22 +94,11 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
93
94
 
94
95
  init {
95
96
  try {
96
- // 确保隐私合规已设置
97
- MapsInitializer.updatePrivacyShow(context, true, true)
98
- MapsInitializer.updatePrivacyAgree(context, true)
97
+ SDKInitializer.applyPrivacyState(context)
99
98
 
100
- // 尝试从预加载池获取 MapView
101
- val preloadedMapView = MapPreloadManager.getPreloadedMapView()
102
-
103
- if (preloadedMapView != null) {
104
- mapView = preloadedMapView
105
- android.util.Log.i("ExpoGaodeMapView", "🚀 使用预加载的 MapView 实例")
106
- } else {
107
- // 创建地图视图
108
- mapView = MapView(context)
109
- mapView.onCreate(null)
110
- android.util.Log.i("ExpoGaodeMapView", "⚠️ 创建新的 MapView 实例 (未命中预加载池)")
111
- }
99
+ // 直接创建地图视图
100
+ mapView = MapView(context)
101
+ mapView.onCreate(null)
112
102
 
113
103
  aMap = mapView.map
114
104
 
@@ -14,24 +14,50 @@ import com.amap.api.maps.MapsInitializer
14
14
  * - 获取 SDK 版本信息
15
15
  */
16
16
  object SDKInitializer {
17
-
18
- /** 隐私协议是否已同意(进程内缓存) */
19
- private var privacyAgreed = true
17
+ private var privacyAgreed = false
18
+ private var privacyShown = false
19
+ private var privacyContains = false
20
20
 
21
+ private fun resolveContext(context: Context): Context {
22
+ return context.applicationContext ?: context
23
+ }
24
+
25
+ fun setPrivacyShow(context: Context, hasShow: Boolean, hasContainsPrivacy: Boolean) {
26
+ privacyShown = hasShow
27
+ privacyContains = hasContainsPrivacy
28
+ applyPrivacyState(resolveContext(context))
29
+ }
30
+
31
+ fun setPrivacyAgree(context: Context, hasAgree: Boolean) {
32
+ privacyAgreed = hasAgree
33
+ applyPrivacyState(resolveContext(context))
34
+ }
21
35
 
22
-
23
- fun restorePrivacyState(context: Context) {
36
+ fun applyPrivacyState(context: Context) {
37
+ val appContext = resolveContext(context)
24
38
  try {
25
- // 同步到 SDK
26
- MapsInitializer.updatePrivacyShow(context, true, true)
27
- AMapLocationClient.updatePrivacyShow(context, true, true)
28
- MapsInitializer.updatePrivacyAgree(context, privacyAgreed)
29
- AMapLocationClient.updatePrivacyAgree(context, privacyAgreed)
39
+ MapsInitializer.updatePrivacyShow(appContext, privacyShown, privacyContains)
40
+ AMapLocationClient.updatePrivacyShow(appContext, privacyShown, privacyContains)
41
+ MapsInitializer.updatePrivacyAgree(appContext, privacyAgreed)
42
+ AMapLocationClient.updatePrivacyAgree(appContext, privacyAgreed)
30
43
  } catch (e: Exception) {
31
- android.util.Log.w("ExpoGaodeMap", "恢复隐私状态失败: ${e.message}")
44
+ android.util.Log.w("ExpoGaodeMap", "同步隐私状态失败: ${e.message}")
32
45
  }
33
46
  }
34
47
 
48
+ fun isPrivacyReady(): Boolean {
49
+ return privacyShown && privacyContains && privacyAgreed
50
+ }
51
+
52
+ fun getPrivacyStatus(): Map<String, Boolean> {
53
+ return mapOf(
54
+ "hasShow" to privacyShown,
55
+ "hasContainsPrivacy" to privacyContains,
56
+ "hasAgree" to privacyAgreed,
57
+ "isReady" to isPrivacyReady()
58
+ )
59
+ }
60
+
35
61
  /**
36
62
  * 初始化高德地图和定位 SDK
37
63
  *
@@ -40,13 +66,14 @@ object SDKInitializer {
40
66
  * @throws Exception 初始化失败时抛出异常
41
67
  */
42
68
  fun initSDK(context: Context, androidKey: String) {
69
+ val appContext = resolveContext(context)
43
70
  // 检查隐私协议状态
44
- if (!privacyAgreed) {
45
- // 使用 Kotlin 模块的 CodedException,让 JS 能收到标准化异常
46
- throw expo.modules.kotlin.exception.CodedException("用户未同意隐私协议,无法初始化 SDK")
71
+ if (!isPrivacyReady()) {
72
+ throw expo.modules.kotlin.exception.CodedException("隐私协议未完成确认,请先调用 setPrivacyShow/setPrivacyAgree")
47
73
  }
48
74
 
49
75
  try {
76
+ applyPrivacyState(appContext)
50
77
  // 设置 API Key
51
78
  MapsInitializer.setApiKey(androidKey)
52
79
  AMapLocationClient.setApiKey(androidKey)
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoGaodeMapNaviView.d.ts","sourceRoot":"","sources":["../src/ExpoGaodeMapNaviView.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,WAAW,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,eAAe,EAAE,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9F;;OAEG;IACH,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,oBAAoB,2GAwB/B,CAAC;AAIH,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"ExpoGaodeMapNaviView.d.ts","sourceRoot":"","sources":["../src/ExpoGaodeMapNaviView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,WAAW,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAC;AAGtE;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,eAAe,EAAE,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9F;;OAEG;IACH,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,oBAAoB,2GAyB/B,CAAC;AAIH,eAAe,oBAAoB,CAAC"}
@@ -1,6 +1,6 @@
1
- import { requireNativeViewManager } from 'expo-modules-core';
2
1
  import * as React from 'react';
3
- const NativeView = requireNativeViewManager('ExpoGaodeMapNaviView');
2
+ import { createLazyNativeViewManager } from './map/utils/lazyNativeViewManager';
3
+ const getNativeView = createLazyNativeViewManager('ExpoGaodeMapNaviView');
4
4
  /**
5
5
  * 高德导航视图组件
6
6
  *
@@ -36,6 +36,7 @@ const NativeView = requireNativeViewManager('ExpoGaodeMapNaviView');
36
36
  */
37
37
  export const ExpoGaodeMapNaviView = React.forwardRef((props, ref) => {
38
38
  const nativeRef = React.useRef(null);
39
+ const NativeView = React.useMemo(() => getNativeView(), []);
39
40
  // 创建 API 引用
40
41
  const apiRef = React.useMemo(() => ({
41
42
  startNavigation: async (start, end, type) => {
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoGaodeMapNaviView.js","sourceRoot":"","sources":["../src/ExpoGaodeMapNaviView.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAmB/B,MAAM,UAAU,GAA8E,wBAAwB,CAAC,sBAAsB,CAAC,CAAC;AAE/I;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,CAAC,UAAU,CAAqD,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACtH,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAM,IAAI,CAAC,CAAC;IAE1C,YAAY;IACZ,MAAM,MAAM,GAA4B,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAC3D,eAAe,EAAE,KAAK,EAAE,KAAyB,EAAE,GAAgB,EAAE,IAAY,EAAE,EAAE;YACnF,IAAI,CAAC,SAAS,CAAC,OAAO;gBAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;YAChF,oBAAoB;YACpB,MAAM,QAAQ,GAAG,KAAK,EAAE,QAAQ,IAAI,CAAC,CAAC;YACtC,MAAM,QAAQ,GAAG,KAAK,EAAE,SAAS,IAAI,CAAC,CAAC;YACvC,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC;YAC5B,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC;YAC7B,OAAO,SAAS,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/E,CAAC;QACD,cAAc,EAAE,KAAK,IAAI,EAAE;YACzB,IAAI,CAAC,SAAS,CAAC,OAAO;gBAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;YAChF,OAAO,SAAS,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAC5C,CAAC;KACF,CAAC,EAAE,EAAE,CAAC,CAAC;IAER,iBAAiB;IACjB,KAAK,CAAC,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEvD,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,KAAK,CAAC,EAAG,CAAC;AACnD,CAAC,CAAC,CAAC;AAEH,oBAAoB,CAAC,WAAW,GAAG,sBAAsB,CAAC;AAE1D,eAAe,oBAAoB,CAAC","sourcesContent":["\nimport { requireNativeViewManager } from 'expo-modules-core';\nimport * as React from 'react';\nimport type { Coordinates, ExpoGaodeMapNaviViewProps } from './types';\n\n/**\n * ExpoGaodeMapNaviView Ref 类型\n */\nexport interface ExpoGaodeMapNaviViewRef {\n /**\n * 开始导航\n */\n startNavigation: (start: Coordinates | null, end: Coordinates, type: number) => Promise<void>;\n \n /**\n * 停止导航\n */\n stopNavigation: () => Promise<void>;\n}\n\n\nconst NativeView: React.ComponentType<ExpoGaodeMapNaviViewProps & { ref?: React.Ref<any> }> = requireNativeViewManager('ExpoGaodeMapNaviView');\n\n/**\n * 高德导航视图组件\n *\n * 使用高德官方的导航界面,提供完整的导航体验,包括:\n * - 路线规划和显示\n * - 实时导航信息(距离、时间、道路名称)\n * - 转向箭头和提示\n * - 路况信息\n * - 摄像头提示\n * - 语音播报\n *\n * @example\n * ```tsx\n * import { ExpoGaodeMapNaviView } from 'expo-gaode-map-navigation';\n *\n * function NavigationScreen() {\n * return (\n * <ExpoGaodeMapNaviView\n * style={{ flex: 1 }}\n * naviType={0} // GPS 导航\n * showCamera={true}\n * enableVoice={true}\n * onNaviInfoUpdate={(e) => {\n * console.log('剩余距离:', e.nativeEvent.pathRetainDistance);\n * }}\n * onArrive={() => {\n * console.log('到达目的地!');\n * }}\n * />\n * );\n * }\n * ```\n */\nexport const ExpoGaodeMapNaviView = React.forwardRef<ExpoGaodeMapNaviViewRef, ExpoGaodeMapNaviViewProps>((props, ref) => {\n const nativeRef = React.useRef<any>(null);\n \n // 创建 API 引用\n const apiRef: ExpoGaodeMapNaviViewRef = React.useMemo(() => ({\n startNavigation: async (start: Coordinates | null, end: Coordinates, type: number) => {\n if (!nativeRef.current) throw new Error('ExpoGaodeMapNaviView not initialized');\n // 将对象解构为单独的参数传递给原生层\n const startLat = start?.latitude ?? 0;\n const startLng = start?.longitude ?? 0;\n const endLat = end.latitude;\n const endLng = end.longitude;\n return nativeRef.current.startNavigation(startLat, startLng, endLat, endLng);\n },\n stopNavigation: async () => {\n if (!nativeRef.current) throw new Error('ExpoGaodeMapNaviView not initialized');\n return nativeRef.current.stopNavigation();\n },\n }), []);\n \n // 暴露 API 给外部 ref\n React.useImperativeHandle(ref, () => apiRef, [apiRef]);\n \n return <NativeView ref={nativeRef} {...props} />;\n});\n\nExpoGaodeMapNaviView.displayName = 'ExpoGaodeMapNaviView';\n\nexport default ExpoGaodeMapNaviView;"]}
1
+ {"version":3,"file":"ExpoGaodeMapNaviView.js","sourceRoot":"","sources":["../src/ExpoGaodeMapNaviView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,2BAA2B,EAAE,MAAM,mCAAmC,CAAC;AAkBhF,MAAM,aAAa,GAAG,2BAA2B,CAAuD,sBAAsB,CAAC,CAAC;AAEhI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,CAAC,UAAU,CAAqD,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACtH,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAM,IAAI,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,aAAa,EAAE,EAAE,EAAE,CAAC,CAAC;IAE5D,YAAY;IACZ,MAAM,MAAM,GAA4B,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAC3D,eAAe,EAAE,KAAK,EAAE,KAAyB,EAAE,GAAgB,EAAE,IAAY,EAAE,EAAE;YACnF,IAAI,CAAC,SAAS,CAAC,OAAO;gBAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;YAChF,oBAAoB;YACpB,MAAM,QAAQ,GAAG,KAAK,EAAE,QAAQ,IAAI,CAAC,CAAC;YACtC,MAAM,QAAQ,GAAG,KAAK,EAAE,SAAS,IAAI,CAAC,CAAC;YACvC,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC;YAC5B,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC;YAC7B,OAAO,SAAS,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/E,CAAC;QACD,cAAc,EAAE,KAAK,IAAI,EAAE;YACzB,IAAI,CAAC,SAAS,CAAC,OAAO;gBAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;YAChF,OAAO,SAAS,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAC5C,CAAC;KACF,CAAC,EAAE,EAAE,CAAC,CAAC;IAER,iBAAiB;IACjB,KAAK,CAAC,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEvD,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,KAAK,CAAC,EAAG,CAAC;AACnD,CAAC,CAAC,CAAC;AAEH,oBAAoB,CAAC,WAAW,GAAG,sBAAsB,CAAC;AAE1D,eAAe,oBAAoB,CAAC","sourcesContent":["import * as React from 'react';\nimport type { Coordinates, ExpoGaodeMapNaviViewProps } from './types';\nimport { createLazyNativeViewManager } from './map/utils/lazyNativeViewManager';\n\n/**\n * ExpoGaodeMapNaviView Ref 类型\n */\nexport interface ExpoGaodeMapNaviViewRef {\n /**\n * 开始导航\n */\n startNavigation: (start: Coordinates | null, end: Coordinates, type: number) => Promise<void>;\n \n /**\n * 停止导航\n */\n stopNavigation: () => Promise<void>;\n}\n\n\nconst getNativeView = createLazyNativeViewManager<ExpoGaodeMapNaviViewProps & { ref?: React.Ref<any> }>('ExpoGaodeMapNaviView');\n\n/**\n * 高德导航视图组件\n *\n * 使用高德官方的导航界面,提供完整的导航体验,包括:\n * - 路线规划和显示\n * - 实时导航信息(距离、时间、道路名称)\n * - 转向箭头和提示\n * - 路况信息\n * - 摄像头提示\n * - 语音播报\n *\n * @example\n * ```tsx\n * import { ExpoGaodeMapNaviView } from 'expo-gaode-map-navigation';\n *\n * function NavigationScreen() {\n * return (\n * <ExpoGaodeMapNaviView\n * style={{ flex: 1 }}\n * naviType={0} // GPS 导航\n * showCamera={true}\n * enableVoice={true}\n * onNaviInfoUpdate={(e) => {\n * console.log('剩余距离:', e.nativeEvent.pathRetainDistance);\n * }}\n * onArrive={() => {\n * console.log('到达目的地!');\n * }}\n * />\n * );\n * }\n * ```\n */\nexport const ExpoGaodeMapNaviView = React.forwardRef<ExpoGaodeMapNaviViewRef, ExpoGaodeMapNaviViewProps>((props, ref) => {\n const nativeRef = React.useRef<any>(null);\n const NativeView = React.useMemo(() => getNativeView(), []);\n \n // 创建 API 引用\n const apiRef: ExpoGaodeMapNaviViewRef = React.useMemo(() => ({\n startNavigation: async (start: Coordinates | null, end: Coordinates, type: number) => {\n if (!nativeRef.current) throw new Error('ExpoGaodeMapNaviView not initialized');\n // 将对象解构为单独的参数传递给原生层\n const startLat = start?.latitude ?? 0;\n const startLng = start?.longitude ?? 0;\n const endLat = end.latitude;\n const endLng = end.longitude;\n return nativeRef.current.startNavigation(startLat, startLng, endLat, endLng);\n },\n stopNavigation: async () => {\n if (!nativeRef.current) throw new Error('ExpoGaodeMapNaviView not initialized');\n return nativeRef.current.stopNavigation();\n },\n }), []);\n \n // 暴露 API 给外部 ref\n React.useImperativeHandle(ref, () => apiRef, [apiRef]);\n \n return <NativeView ref={nativeRef} {...props} />;\n});\n\nExpoGaodeMapNaviView.displayName = 'ExpoGaodeMapNaviView';\n\nexport default ExpoGaodeMapNaviView;\n"]}
@@ -1,9 +1,4 @@
1
1
  import { ExpoGaodeMapNavigationModule as ExpoGaodeMapNavigationModuleType } from './types/native-module.types';
2
- /**
3
- * 高德地图导航模块
4
- *
5
- * 提供路径规划功能,包括驾车、步行、骑行、公交、货车等多种出行方式
6
- */
7
- declare const ExpoGaodeMapNavigationModule: ExpoGaodeMapNavigationModuleType;
8
- export default ExpoGaodeMapNavigationModule;
2
+ declare const _default: ExpoGaodeMapNavigationModuleType;
3
+ export default _default;
9
4
  //# sourceMappingURL=ExpoGaodeMapNavigationModule.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoGaodeMapNavigationModule.d.ts","sourceRoot":"","sources":["../src/ExpoGaodeMapNavigationModule.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,4BAA4B,IAAI,gCAAgC,EAAE,MAAM,6BAA6B,CAAC;AAC/G;;;;GAIG;AACH,QAAA,MAAM,4BAA4B,kCAAkF,CAAC;AAErH,eAAe,4BAA4B,CAAC"}
1
+ {"version":3,"file":"ExpoGaodeMapNavigationModule.d.ts","sourceRoot":"","sources":["../src/ExpoGaodeMapNavigationModule.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,4BAA4B,IAAI,gCAAgC,EAAE,MAAM,6BAA6B,CAAC;;AAe/G,wBAIG"}
@@ -4,6 +4,16 @@ import { requireNativeModule } from 'expo-modules-core';
4
4
  *
5
5
  * 提供路径规划功能,包括驾车、步行、骑行、公交、货车等多种出行方式
6
6
  */
7
- const ExpoGaodeMapNavigationModule = requireNativeModule('ExpoGaodeMapNavigation');
8
- export default ExpoGaodeMapNavigationModule;
7
+ let nativeModuleCache = null;
8
+ function getNativeModule() {
9
+ if (!nativeModuleCache) {
10
+ nativeModuleCache = requireNativeModule('ExpoGaodeMapNavigation');
11
+ }
12
+ return nativeModuleCache;
13
+ }
14
+ export default new Proxy({}, {
15
+ get(_target, prop) {
16
+ return Reflect.get(getNativeModule(), prop);
17
+ },
18
+ });
9
19
  //# sourceMappingURL=ExpoGaodeMapNavigationModule.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoGaodeMapNavigationModule.js","sourceRoot":"","sources":["../src/ExpoGaodeMapNavigationModule.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;;GAIG;AACH,MAAM,4BAA4B,GAAG,mBAAmB,CAAmC,wBAAwB,CAAC,CAAC;AAErH,eAAe,4BAA4B,CAAC","sourcesContent":["\nimport { requireNativeModule } from 'expo-modules-core';\nimport { ExpoGaodeMapNavigationModule as ExpoGaodeMapNavigationModuleType } from './types/native-module.types';\n/**\n * 高德地图导航模块\n * \n * 提供路径规划功能,包括驾车、步行、骑行、公交、货车等多种出行方式\n */\nconst ExpoGaodeMapNavigationModule = requireNativeModule<ExpoGaodeMapNavigationModuleType>('ExpoGaodeMapNavigation');\n\nexport default ExpoGaodeMapNavigationModule;"]}
1
+ {"version":3,"file":"ExpoGaodeMapNavigationModule.js","sourceRoot":"","sources":["../src/ExpoGaodeMapNavigationModule.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;;GAIG;AACH,IAAI,iBAAiB,GAA4C,IAAI,CAAC;AAEtE,SAAS,eAAe;IACtB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,iBAAiB,GAAG,mBAAmB,CAAmC,wBAAwB,CAAC,CAAC;IACtG,CAAC;IACD,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,eAAe,IAAI,KAAK,CAAC,EAAsC,EAAE;IAC/D,GAAG,CAAC,OAAO,EAAE,IAAI;QACf,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,EAAY,EAAE,IAAI,CAAC,CAAC;IACxD,CAAC;CACF,CAAC,CAAC","sourcesContent":["\nimport { requireNativeModule } from 'expo-modules-core';\nimport { ExpoGaodeMapNavigationModule as ExpoGaodeMapNavigationModuleType } from './types/native-module.types';\n/**\n * 高德地图导航模块\n * \n * 提供路径规划功能,包括驾车、步行、骑行、公交、货车等多种出行方式\n */\nlet nativeModuleCache: ExpoGaodeMapNavigationModuleType | null = null;\n\nfunction getNativeModule(): ExpoGaodeMapNavigationModuleType {\n if (!nativeModuleCache) {\n nativeModuleCache = requireNativeModule<ExpoGaodeMapNavigationModuleType>('ExpoGaodeMapNavigation');\n }\n return nativeModuleCache;\n}\n\nexport default new Proxy({} as ExpoGaodeMapNavigationModuleType, {\n get(_target, prop) {\n return Reflect.get(getNativeModule() as object, prop);\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoGaodeMapModule.d.ts","sourceRoot":"","sources":["../../src/map/ExpoGaodeMapModule.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEtE,OAAO,EAAE,SAAS,EAAoB,MAAM,sBAAsB,CAAC;AAqpBnE;;EAEE;AACF,wBAAgB,YAAY,IAAI,SAAS,GAAG,IAAI,CAE/C;AAED;;EAEE;AACF,wBAAgB,SAAS,IAAI,MAAM,GAAG,SAAS,CAE9C;wBAE0D,kBAAkB;AAA7E,wBAA8E"}
1
+ {"version":3,"file":"ExpoGaodeMapModule.d.ts","sourceRoot":"","sources":["../../src/map/ExpoGaodeMapModule.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEtE,OAAO,EAAiB,SAAS,EAAoB,MAAM,sBAAsB,CAAC;AAixBlF;;EAEE;AACF,wBAAgB,YAAY,IAAI,SAAS,GAAG,IAAI,CAE/C;AA4BD;;EAEE;AACF,wBAAgB,SAAS,IAAI,MAAM,GAAG,SAAS,CAE9C;wBAE0D,kBAAkB;AAA7E,wBAA8E"}
@@ -2,30 +2,84 @@ import { requireNativeModule } from 'expo';
2
2
  import { Platform } from 'react-native';
3
3
  import { ErrorHandler, ErrorLogger } from './utils/ErrorHandler';
4
4
  import { normalizeLatLng, normalizeLatLngList } from './utils/GeoUtils';
5
- // 获取原生模块实例 - 添加容错处理
6
- let nativeModule = null;
7
- try {
8
- nativeModule = requireNativeModule('ExpoGaodeMap');
9
- }
10
- catch (error) {
11
- console.error('Failed to load ExpoGaodeMap native module:', error);
12
- const moduleError = ErrorHandler.nativeModuleUnavailable();
13
- ErrorLogger.log(moduleError);
5
+ let nativeModuleCache = null;
6
+ function getNativeModule(optional = false) {
7
+ if (nativeModuleCache) {
8
+ return nativeModuleCache;
9
+ }
10
+ try {
11
+ nativeModuleCache = requireNativeModule('ExpoGaodeMap');
12
+ return nativeModuleCache;
13
+ }
14
+ catch (error) {
15
+ if (optional) {
16
+ return null;
17
+ }
18
+ const moduleError = ErrorHandler.nativeModuleUnavailable();
19
+ ErrorLogger.log(moduleError);
20
+ throw moduleError;
21
+ }
14
22
  }
23
+ const nativeModule = new Proxy({}, {
24
+ get(_target, prop) {
25
+ const module = getNativeModule(true);
26
+ return module ? Reflect.get(module, prop) : undefined;
27
+ },
28
+ });
15
29
  // 记录最近一次 initSDK 的配置(含 webKey)
16
30
  let _sdkConfig = null;
17
31
  let _isSDKInitialized = false;
32
+ const privacySensitiveMethodNames = new Set([
33
+ 'start',
34
+ 'stop',
35
+ 'isStarted',
36
+ 'getCurrentLocation',
37
+ 'coordinateConvert',
38
+ 'setLocatingWithReGeocode',
39
+ 'setLocationMode',
40
+ 'setInterval',
41
+ 'setOnceLocation',
42
+ 'setSensorEnable',
43
+ 'setWifiScan',
44
+ 'setGpsFirst',
45
+ 'setOnceLocationLatest',
46
+ 'setGeoLanguage',
47
+ 'setLocationCacheEnable',
48
+ 'setHttpTimeOut',
49
+ 'setDesiredAccuracy',
50
+ 'setLocationTimeout',
51
+ 'setReGeocodeTimeout',
52
+ 'setDistanceFilter',
53
+ 'setPausesLocationUpdatesAutomatically',
54
+ 'setAllowsBackgroundLocationUpdates',
55
+ 'setLocationProtocol',
56
+ 'startUpdatingHeading',
57
+ 'stopUpdatingHeading',
58
+ 'checkLocationPermission',
59
+ 'requestLocationPermission',
60
+ 'requestBackgroundLocationPermission',
61
+ 'addLocationListener',
62
+ ]);
63
+ function assertPrivacyReady(scene = 'sdk') {
64
+ const nativeModule = getNativeModule();
65
+ if (!nativeModule) {
66
+ throw ErrorHandler.nativeModuleUnavailable();
67
+ }
68
+ const status = nativeModule.getPrivacyStatus();
69
+ if (!status.isReady) {
70
+ throw ErrorHandler.privacyNotAgreed(scene);
71
+ }
72
+ }
18
73
  // 扩展原生模块,添加便捷方法
19
- const ExpoGaodeMapModuleWithHelpers = {
20
- ...(nativeModule || {}),
74
+ const helperMethods = {
21
75
  /**
22
76
  * 初始化 SDK,并缓存配置(包含 webKey)
23
77
  * 注意:允许不提供任何 API Key,因为原生端可能已通过 Config Plugin 配置
24
78
  */
25
79
  initSDK(config) {
26
- if (!nativeModule) {
80
+ const nativeModule = getNativeModule();
81
+ if (!nativeModule)
27
82
  throw ErrorHandler.nativeModuleUnavailable();
28
- }
29
83
  try {
30
84
  // 检查是否有任何 key 被提供
31
85
  const hasJSKeys = !!(config.androidKey || config.iosKey);
@@ -54,19 +108,53 @@ const ExpoGaodeMapModuleWithHelpers = {
54
108
  isSDKInitialized() {
55
109
  return _isSDKInitialized;
56
110
  },
111
+ setPrivacyShow(hasShow, hasContainsPrivacy) {
112
+ const nativeModule = getNativeModule();
113
+ if (!nativeModule)
114
+ throw ErrorHandler.nativeModuleUnavailable();
115
+ nativeModule.setPrivacyShow(hasShow, hasContainsPrivacy);
116
+ },
117
+ setPrivacyAgree(hasAgree) {
118
+ const nativeModule = getNativeModule();
119
+ if (!nativeModule)
120
+ throw ErrorHandler.nativeModuleUnavailable();
121
+ nativeModule.setPrivacyAgree(hasAgree);
122
+ },
123
+ setPrivacyConfig(config) {
124
+ const nativeModule = getNativeModule();
125
+ if (!nativeModule)
126
+ throw ErrorHandler.nativeModuleUnavailable();
127
+ nativeModule.setPrivacyShow(config.hasShow, config.hasContainsPrivacy);
128
+ nativeModule.setPrivacyAgree(config.hasAgree);
129
+ },
130
+ getPrivacyStatus() {
131
+ const nativeModule = getNativeModule();
132
+ if (!nativeModule) {
133
+ return {
134
+ hasShow: false,
135
+ hasContainsPrivacy: false,
136
+ hasAgree: false,
137
+ isReady: false,
138
+ };
139
+ }
140
+ return nativeModule.getPrivacyStatus();
141
+ },
57
142
  calculateDistanceBetweenPoints(p1, p2) {
143
+ const nativeModule = getNativeModule();
58
144
  if (!nativeModule) {
59
145
  throw ErrorHandler.nativeModuleUnavailable();
60
146
  }
61
147
  return nativeModule.distanceBetweenCoordinates(normalizeLatLng(p1), normalizeLatLng(p2));
62
148
  },
63
149
  calculateDistance(lat1, lon1, lat2, lon2) {
150
+ const nativeModule = getNativeModule();
64
151
  if (!nativeModule) {
65
152
  throw ErrorHandler.nativeModuleUnavailable();
66
153
  }
67
154
  return nativeModule.distanceBetweenCoordinates({ latitude: lat1, longitude: lon1 }, { latitude: lat2, longitude: lon2 });
68
155
  },
69
156
  setLoadWorldVectorMap(enabled) {
157
+ const nativeModule = getNativeModule(true);
70
158
  if (!nativeModule)
71
159
  return;
72
160
  try {
@@ -77,6 +165,7 @@ const ExpoGaodeMapModuleWithHelpers = {
77
165
  }
78
166
  },
79
167
  getVersion() {
168
+ const nativeModule = getNativeModule(true);
80
169
  if (!nativeModule)
81
170
  return '0.0.0';
82
171
  try {
@@ -88,6 +177,8 @@ const ExpoGaodeMapModuleWithHelpers = {
88
177
  }
89
178
  },
90
179
  start() {
180
+ assertPrivacyReady('sdk');
181
+ const nativeModule = getNativeModule(true);
91
182
  if (!nativeModule)
92
183
  return;
93
184
  try {
@@ -98,6 +189,8 @@ const ExpoGaodeMapModuleWithHelpers = {
98
189
  }
99
190
  },
100
191
  stop() {
192
+ assertPrivacyReady('sdk');
193
+ const nativeModule = getNativeModule(true);
101
194
  if (!nativeModule)
102
195
  return;
103
196
  try {
@@ -108,6 +201,8 @@ const ExpoGaodeMapModuleWithHelpers = {
108
201
  }
109
202
  },
110
203
  isStarted() {
204
+ assertPrivacyReady('sdk');
205
+ const nativeModule = getNativeModule(true);
111
206
  if (!nativeModule)
112
207
  return Promise.resolve(false);
113
208
  try {
@@ -119,6 +214,8 @@ const ExpoGaodeMapModuleWithHelpers = {
119
214
  }
120
215
  },
121
216
  async getCurrentLocation() {
217
+ assertPrivacyReady('sdk');
218
+ const nativeModule = getNativeModule();
122
219
  if (!nativeModule) {
123
220
  throw ErrorHandler.nativeModuleUnavailable();
124
221
  }
@@ -130,6 +227,8 @@ const ExpoGaodeMapModuleWithHelpers = {
130
227
  }
131
228
  },
132
229
  async coordinateConvert(coordinate, type) {
230
+ assertPrivacyReady('sdk');
231
+ const nativeModule = getNativeModule();
133
232
  if (!nativeModule) {
134
233
  throw ErrorHandler.nativeModuleUnavailable();
135
234
  }
@@ -141,6 +240,8 @@ const ExpoGaodeMapModuleWithHelpers = {
141
240
  }
142
241
  },
143
242
  setLocatingWithReGeocode(isReGeocode) {
243
+ assertPrivacyReady('sdk');
244
+ const nativeModule = getNativeModule(true);
144
245
  if (!nativeModule)
145
246
  return;
146
247
  try {
@@ -151,6 +252,7 @@ const ExpoGaodeMapModuleWithHelpers = {
151
252
  }
152
253
  },
153
254
  get isBackgroundLocationEnabled() {
255
+ const nativeModule = getNativeModule(true);
154
256
  if (!nativeModule)
155
257
  return false;
156
258
  return nativeModule.isBackgroundLocationEnabled === true;
@@ -159,6 +261,8 @@ const ExpoGaodeMapModuleWithHelpers = {
159
261
  * 检查位置权限状态
160
262
  */
161
263
  async checkLocationPermission() {
264
+ assertPrivacyReady('sdk');
265
+ const nativeModule = getNativeModule();
162
266
  if (!nativeModule) {
163
267
  throw ErrorHandler.nativeModuleUnavailable();
164
268
  }
@@ -173,6 +277,8 @@ const ExpoGaodeMapModuleWithHelpers = {
173
277
  * 请求前台位置权限(增强版)
174
278
  */
175
279
  async requestLocationPermission() {
280
+ assertPrivacyReady('sdk');
281
+ const nativeModule = getNativeModule();
176
282
  if (!nativeModule) {
177
283
  throw ErrorHandler.nativeModuleUnavailable();
178
284
  }
@@ -192,6 +298,8 @@ const ExpoGaodeMapModuleWithHelpers = {
192
298
  * 注意:必须在前台权限已授予后才能请求
193
299
  */
194
300
  async requestBackgroundLocationPermission() {
301
+ assertPrivacyReady('sdk');
302
+ const nativeModule = getNativeModule();
195
303
  if (!nativeModule) {
196
304
  throw ErrorHandler.nativeModuleUnavailable();
197
305
  }
@@ -211,6 +319,7 @@ const ExpoGaodeMapModuleWithHelpers = {
211
319
  * 引导用户手动授予权限
212
320
  */
213
321
  openAppSettings() {
322
+ const nativeModule = getNativeModule();
214
323
  if (!nativeModule) {
215
324
  throw ErrorHandler.nativeModuleUnavailable();
216
325
  }
@@ -222,6 +331,8 @@ const ExpoGaodeMapModuleWithHelpers = {
222
331
  }
223
332
  },
224
333
  setAllowsBackgroundLocationUpdates(allows) {
334
+ assertPrivacyReady('sdk');
335
+ const nativeModule = getNativeModule();
225
336
  if (!nativeModule) {
226
337
  throw ErrorHandler.nativeModuleUnavailable();
227
338
  }
@@ -256,13 +367,18 @@ const ExpoGaodeMapModuleWithHelpers = {
256
367
  * 注意:如果使用 Config Plugin 配置了 API Key,无需调用 initSDK()
257
368
  */
258
369
  addLocationListener(listener) {
259
- if (!nativeModule) {
370
+ assertPrivacyReady('sdk');
371
+ const module = getNativeModule();
372
+ if (!module) {
260
373
  throw ErrorHandler.nativeModuleUnavailable();
261
374
  }
262
- if (!nativeModule?.addListener) {
375
+ if (!module.addListener) {
263
376
  ErrorLogger.warn('Native module does not support events');
377
+ return {
378
+ remove: () => { },
379
+ };
264
380
  }
265
- return nativeModule?.addListener?.('onLocationUpdate', listener) || {
381
+ return module.addListener('onLocationUpdate', listener) || {
266
382
  remove: () => { },
267
383
  };
268
384
  },
@@ -617,6 +733,28 @@ const ExpoGaodeMapModuleWithHelpers = {
617
733
  export function getSDKConfig() {
618
734
  return _sdkConfig;
619
735
  }
736
+ ;
737
+ const ExpoGaodeMapModuleWithHelpers = new Proxy(helperMethods, {
738
+ get(target, prop, receiver) {
739
+ if (Reflect.has(target, prop)) {
740
+ return Reflect.get(target, prop, receiver);
741
+ }
742
+ const nativeModule = getNativeModule(true);
743
+ if (!nativeModule) {
744
+ return undefined;
745
+ }
746
+ const value = Reflect.get(nativeModule, prop);
747
+ if (typeof prop === 'string' &&
748
+ privacySensitiveMethodNames.has(prop) &&
749
+ typeof value === 'function') {
750
+ return (...args) => {
751
+ assertPrivacyReady('sdk');
752
+ return value.apply(nativeModule, args);
753
+ };
754
+ }
755
+ return value;
756
+ },
757
+ });
620
758
  /**
621
759
  * 获取用于 Web API 的 webKey(若未初始化或未提供则返回 undefined)
622
760
  */