expo-gaode-map 2.2.0-beta.0 → 2.2.2-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.
- package/android/build.gradle +2 -3
- package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapModule.kt +33 -2
- package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapView.kt +1 -1
- package/android/src/main/java/expo/modules/gaodemap/modules/SDKInitializer.kt +46 -9
- package/build/ExpoGaodeMapModule.d.ts +16 -0
- package/build/ExpoGaodeMapModule.d.ts.map +1 -1
- package/build/ExpoGaodeMapModule.js +21 -0
- package/build/ExpoGaodeMapModule.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +12 -0
- package/build/index.js.map +1 -1
- package/ios/ExpoGaodeMap.podspec +2 -4
- package/ios/ExpoGaodeMapModule.swift +87 -6
- package/ios/managers/CameraManager.swift +1 -1
- package/package.json +1 -1
- package/plugin/build/withGaodeMap.js +31 -23
- package/src/ExpoGaodeMapModule.ts +51 -15
- package/src/index.ts +13 -0
package/android/build.gradle
CHANGED
|
@@ -22,6 +22,17 @@ class ExpoGaodeMapModule : Module() {
|
|
|
22
22
|
override fun definition() = ModuleDefinition {
|
|
23
23
|
Name("ExpoGaodeMap")
|
|
24
24
|
|
|
25
|
+
// ==================== 隐私合规管理 ====================
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 更新隐私合规状态
|
|
29
|
+
* 必须在用户同意隐私协议后调用
|
|
30
|
+
* @param hasAgreed 用户是否已同意隐私协议
|
|
31
|
+
*/
|
|
32
|
+
Function("updatePrivacyCompliance") { hasAgreed: Boolean ->
|
|
33
|
+
SDKInitializer.updatePrivacyCompliance(appContext.reactContext!!, hasAgreed)
|
|
34
|
+
}
|
|
35
|
+
|
|
25
36
|
// ==================== SDK 初始化 ====================
|
|
26
37
|
|
|
27
38
|
/**
|
|
@@ -31,8 +42,16 @@ class ExpoGaodeMapModule : Module() {
|
|
|
31
42
|
Function("initSDK") { config: Map<String, String> ->
|
|
32
43
|
val androidKey = config["androidKey"]
|
|
33
44
|
if (androidKey != null) {
|
|
34
|
-
|
|
35
|
-
|
|
45
|
+
try {
|
|
46
|
+
SDKInitializer.initSDK(appContext.reactContext!!, androidKey)
|
|
47
|
+
getLocationManager() // 初始化定位管理器
|
|
48
|
+
} catch (e: SecurityException) {
|
|
49
|
+
android.util.Log.e("ExpoGaodeMap", "隐私协议未同意: ${e.message}")
|
|
50
|
+
throw e
|
|
51
|
+
} catch (e: Exception) {
|
|
52
|
+
android.util.Log.e("ExpoGaodeMap", "SDK 初始化失败: ${e.message}")
|
|
53
|
+
throw e
|
|
54
|
+
}
|
|
36
55
|
}
|
|
37
56
|
}
|
|
38
57
|
|
|
@@ -50,6 +69,12 @@ class ExpoGaodeMapModule : Module() {
|
|
|
50
69
|
* 开始连续定位
|
|
51
70
|
*/
|
|
52
71
|
Function("start") {
|
|
72
|
+
// 检查隐私协议状态
|
|
73
|
+
if (!SDKInitializer.isPrivacyAgreed()) {
|
|
74
|
+
android.util.Log.w("ExpoGaodeMap", "用户未同意隐私协议,无法开始定位")
|
|
75
|
+
throw expo.modules.kotlin.exception.CodedException("用户未同意隐私协议,无法开始定位")
|
|
76
|
+
}
|
|
77
|
+
|
|
53
78
|
getLocationManager().start()
|
|
54
79
|
}
|
|
55
80
|
|
|
@@ -73,6 +98,12 @@ class ExpoGaodeMapModule : Module() {
|
|
|
73
98
|
* @return 位置信息对象
|
|
74
99
|
*/
|
|
75
100
|
AsyncFunction("getCurrentLocation") { promise: expo.modules.kotlin.Promise ->
|
|
101
|
+
// 检查隐私协议状态
|
|
102
|
+
if (!SDKInitializer.isPrivacyAgreed()) {
|
|
103
|
+
promise.reject("PRIVACY_NOT_AGREED", "用户未同意隐私协议,无法获取位置", null)
|
|
104
|
+
return@AsyncFunction
|
|
105
|
+
}
|
|
106
|
+
|
|
76
107
|
getLocationManager().getCurrentLocation(promise)
|
|
77
108
|
}
|
|
78
109
|
|
|
@@ -14,27 +14,64 @@ import com.amap.api.maps.MapsInitializer
|
|
|
14
14
|
* - 获取 SDK 版本信息
|
|
15
15
|
*/
|
|
16
16
|
object SDKInitializer {
|
|
17
|
-
|
|
17
|
+
|
|
18
|
+
/** 隐私协议是否已同意 */
|
|
19
|
+
private var privacyAgreed = false
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 更新隐私合规状态
|
|
23
|
+
* 必须在用户同意隐私协议后调用
|
|
24
|
+
*
|
|
25
|
+
* @param context 应用上下文
|
|
26
|
+
* @param hasAgreed 用户是否已同意隐私协议
|
|
27
|
+
*/
|
|
28
|
+
fun updatePrivacyCompliance(context: Context, hasAgreed: Boolean) {
|
|
29
|
+
privacyAgreed = hasAgreed
|
|
30
|
+
|
|
31
|
+
// 先更新隐私信息显示状态
|
|
32
|
+
MapsInitializer.updatePrivacyShow(context, true, true)
|
|
33
|
+
AMapLocationClient.updatePrivacyShow(context, true, true)
|
|
34
|
+
|
|
35
|
+
// 根据用户选择更新同意状态
|
|
36
|
+
if (hasAgreed) {
|
|
37
|
+
MapsInitializer.updatePrivacyAgree(context, true)
|
|
38
|
+
AMapLocationClient.updatePrivacyAgree(context, true)
|
|
39
|
+
android.util.Log.d("ExpoGaodeMap", "✅ 用户已同意隐私协议,可以使用 SDK")
|
|
40
|
+
} else {
|
|
41
|
+
MapsInitializer.updatePrivacyAgree(context, false)
|
|
42
|
+
AMapLocationClient.updatePrivacyAgree(context, false)
|
|
43
|
+
android.util.Log.w("ExpoGaodeMap", "⚠️ 用户未同意隐私协议,SDK 功能将受限")
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 检查隐私协议是否已同意
|
|
49
|
+
*
|
|
50
|
+
* @return 是否已同意隐私协议
|
|
51
|
+
*/
|
|
52
|
+
fun isPrivacyAgreed(): Boolean = privacyAgreed
|
|
18
53
|
|
|
19
54
|
/**
|
|
20
55
|
* 初始化高德地图和定位 SDK
|
|
21
|
-
*
|
|
56
|
+
*
|
|
22
57
|
* @param context 应用上下文
|
|
23
58
|
* @param androidKey Android 平台的 API Key
|
|
24
59
|
* @throws Exception 初始化失败时抛出异常
|
|
25
60
|
*/
|
|
26
61
|
fun initSDK(context: Context, androidKey: String) {
|
|
62
|
+
// 检查隐私协议状态
|
|
63
|
+
if (!privacyAgreed) {
|
|
64
|
+
// 使用 Kotlin 模块的 CodedException,让 JS 能收到标准化异常
|
|
65
|
+
throw expo.modules.kotlin.exception.CodedException("用户未同意隐私协议,无法初始化 SDK")
|
|
66
|
+
}
|
|
67
|
+
|
|
27
68
|
try {
|
|
28
|
-
//
|
|
29
|
-
MapsInitializer.updatePrivacyShow(context, true, true)
|
|
30
|
-
MapsInitializer.updatePrivacyAgree(context, true)
|
|
69
|
+
// 设置 API Key
|
|
31
70
|
MapsInitializer.setApiKey(androidKey)
|
|
32
|
-
|
|
33
|
-
// 更新定位隐私合规
|
|
34
|
-
AMapLocationClient.updatePrivacyShow(context, true, true)
|
|
35
|
-
AMapLocationClient.updatePrivacyAgree(context, true)
|
|
36
71
|
AMapLocationClient.setApiKey(androidKey)
|
|
37
72
|
|
|
73
|
+
android.util.Log.d("ExpoGaodeMap", "✅ SDK 初始化成功")
|
|
74
|
+
|
|
38
75
|
} catch (e: Exception) {
|
|
39
76
|
throw Exception("SDK 初始化失败: ${e.message}")
|
|
40
77
|
}
|
|
@@ -13,6 +13,8 @@ export interface SDKConfig {
|
|
|
13
13
|
androidKey?: string;
|
|
14
14
|
/** iOS 平台的高德地图 API Key */
|
|
15
15
|
iosKey?: string;
|
|
16
|
+
/** web api key 如果要使用expo-gaode-map-web-api相关的功能,需要配置web api key*/
|
|
17
|
+
webKey?: string;
|
|
16
18
|
}
|
|
17
19
|
/**
|
|
18
20
|
* 权限状态
|
|
@@ -31,6 +33,12 @@ export interface PermissionStatus {
|
|
|
31
33
|
* 高德地图原生模块类声明
|
|
32
34
|
*/
|
|
33
35
|
declare class ExpoGaodeMapModule extends NativeModule<ExpoGaodeMapModuleEvents> {
|
|
36
|
+
/**
|
|
37
|
+
* 更新隐私合规状态
|
|
38
|
+
* 必须在用户同意隐私协议后调用
|
|
39
|
+
* @param hasAgreed 用户是否已同意隐私协议
|
|
40
|
+
*/
|
|
41
|
+
updatePrivacyCompliance(hasAgreed: boolean): void;
|
|
34
42
|
/**
|
|
35
43
|
* 初始化高德地图 SDK
|
|
36
44
|
* @param config SDK 配置参数,包含 Android 和 iOS 的 API Key
|
|
@@ -191,6 +199,14 @@ declare class ExpoGaodeMapModule extends NativeModule<ExpoGaodeMapModuleEvents>
|
|
|
191
199
|
remove: () => void;
|
|
192
200
|
};
|
|
193
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* 获取最近一次 initSDK 的配置
|
|
204
|
+
*/
|
|
205
|
+
export declare function getSDKConfig(): SDKConfig | null;
|
|
206
|
+
/**
|
|
207
|
+
* 获取用于 Web API 的 webKey(若未初始化或未提供则返回 undefined)
|
|
208
|
+
*/
|
|
209
|
+
export declare function getWebKey(): string | undefined;
|
|
194
210
|
declare const _default: ExpoGaodeMapModule;
|
|
195
211
|
export default _default;
|
|
196
212
|
//# sourceMappingURL=ExpoGaodeMapModule.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoGaodeMapModule.d.ts","sourceRoot":"","sources":["../src/ExpoGaodeMapModule.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ExpoGaodeMapModule.d.ts","sourceRoot":"","sources":["../src/ExpoGaodeMapModule.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,9 +15,18 @@ catch (error) {
|
|
|
15
15
|
if (!nativeModule) {
|
|
16
16
|
console.error('ExpoGaodeMap: 原生模块不可用,请检查配置');
|
|
17
17
|
}
|
|
18
|
+
// 记录最近一次 initSDK 的配置(含 webKey)
|
|
19
|
+
let _sdkConfig = null;
|
|
18
20
|
// 扩展原生模块,添加便捷方法
|
|
19
21
|
const ExpoGaodeMapModuleWithHelpers = {
|
|
20
22
|
...(nativeModule || {}),
|
|
23
|
+
/**
|
|
24
|
+
* 初始化 SDK,并缓存配置(包含 webKey)
|
|
25
|
+
*/
|
|
26
|
+
initSDK(config) {
|
|
27
|
+
_sdkConfig = config ?? null;
|
|
28
|
+
nativeModule?.initSDK?.(config);
|
|
29
|
+
},
|
|
21
30
|
/**
|
|
22
31
|
* 添加定位监听器(便捷方法)
|
|
23
32
|
* 自动订阅 onLocationUpdate 事件,提供容错处理
|
|
@@ -32,5 +41,17 @@ const ExpoGaodeMapModuleWithHelpers = {
|
|
|
32
41
|
};
|
|
33
42
|
},
|
|
34
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* 获取最近一次 initSDK 的配置
|
|
46
|
+
*/
|
|
47
|
+
export function getSDKConfig() {
|
|
48
|
+
return _sdkConfig;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 获取用于 Web API 的 webKey(若未初始化或未提供则返回 undefined)
|
|
52
|
+
*/
|
|
53
|
+
export function getWebKey() {
|
|
54
|
+
return _sdkConfig?.webKey;
|
|
55
|
+
}
|
|
35
56
|
export default ExpoGaodeMapModuleWithHelpers;
|
|
36
57
|
//# sourceMappingURL=ExpoGaodeMapModule.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoGaodeMapModule.js","sourceRoot":"","sources":["../src/ExpoGaodeMapModule.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAgB,mBAAmB,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ExpoGaodeMapModule.js","sourceRoot":"","sources":["../src/ExpoGaodeMapModule.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAgB,mBAAmB,EAAE,MAAM,MAAM,CAAC;AA2PzD,oBAAoB;AACpB,IAAI,YAAY,GAA8B,IAAI,CAAC;AAEnD,IAAI,CAAC;IACH,YAAY,GAAG,mBAAmB,CAAqB,cAAc,CAAC,CAAC;AACzE,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;AAChD,CAAC;AAED,0BAA0B;AAC1B,IAAI,CAAC,YAAY,EAAE,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;AAC/C,CAAC;AAED,+BAA+B;AAC/B,IAAI,UAAU,GAAqB,IAAI,CAAC;AAExC,gBAAgB;AAChB,MAAM,6BAA6B,GAAG;IACrC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;IAEvB;;OAEG;IACH,OAAO,CAAC,MAAiB;QACvB,UAAU,GAAG,MAAM,IAAI,IAAI,CAAC;QAC5B,YAAY,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAED;;;;;;OAMG;IACH,mBAAmB,CAAC,QAA0B;QAC5C,4BAA4B;QAC5B,OAAO,YAAY,EAAE,WAAW,EAAE,CAAC,kBAAkB,EAAE,QAAQ,CAAC,IAAI;YAClE,MAAM,EAAE,GAAG,EAAE,GAAE,CAAC;SACjB,CAAC;IACJ,CAAC;CACD,CAAC;AAEF;;EAEE;AACF,MAAM,UAAU,YAAY;IAC3B,OAAO,UAAU,CAAC;AACnB,CAAC;AAED;;EAEE;AACF,MAAM,UAAU,SAAS;IACxB,OAAO,UAAU,EAAE,MAAM,CAAC;AAC3B,CAAC;AAED,eAAe,6BAAmD,CAAC","sourcesContent":["/**\n * 高德地图原生模块\n * 提供 SDK 初始化、定位、权限管理等功能\n */\n\nimport { NativeModule, requireNativeModule } from 'expo';\nimport type { ExpoGaodeMapModuleEvents } from './ExpoGaodeMap.types';\nimport type {\n LatLng,\n CoordinateType,\n Coordinates,\n ReGeocode,\n LocationMode,\n LocationAccuracy,\n LocationListener,\n} from './types';\n\n/**\n * SDK 配置参数\n */\nexport interface SDKConfig {\n /** Android 平台的高德地图 API Key */\n androidKey?: string;\n /** iOS 平台的高德地图 API Key */\n iosKey?: string;\n /** web api key 如果要使用expo-gaode-map-web-api相关的功能,需要配置web api key*/\n webKey?: string;\n}\n\n/**\n * 权限状态\n */\nexport interface PermissionStatus {\n /** 是否已授权 */\n granted: boolean;\n /** iOS 权限状态字符串 */\n status?: 'notDetermined' | 'restricted' | 'denied' | 'authorizedAlways' | 'authorizedWhenInUse' | 'unknown';\n /** Android 精确位置权限 */\n fineLocation?: boolean;\n /** Android 粗略位置权限 */\n coarseLocation?: boolean;\n}\n\n/**\n * 高德地图原生模块类声明\n */\ndeclare class ExpoGaodeMapModule extends NativeModule<ExpoGaodeMapModuleEvents> {\n // ==================== 隐私合规管理 ====================\n \n /**\n * 更新隐私合规状态\n * 必须在用户同意隐私协议后调用\n * @param hasAgreed 用户是否已同意隐私协议\n */\n updatePrivacyCompliance(hasAgreed: boolean): void;\n \n // ==================== SDK 初始化 ====================\n \n /**\n * 初始化高德地图 SDK\n * @param config SDK 配置参数,包含 Android 和 iOS 的 API Key\n */\n initSDK(config: SDKConfig): void;\n \n /**\n * 获取高德地图 SDK 版本号\n * @returns SDK 版本字符串\n */\n getVersion(): string;\n \n // ==================== 定位控制 ====================\n \n /**\n * 开始连续定位\n * 启动后会持续接收位置更新,通过 onLocationUpdate 事件回调\n */\n start(): void;\n \n /**\n * 停止定位\n * 停止接收位置更新\n */\n stop(): void;\n \n /**\n * 检查是否正在定位\n * @returns Promise<boolean> 是否正在定位\n */\n isStarted(): Promise<boolean>;\n \n /**\n * 获取当前位置(单次定位)\n * @returns Promise<Coordinates | ReGeocode> 位置信息,包含坐标和可选的逆地理编码信息\n */\n getCurrentLocation(): Promise<Coordinates | ReGeocode>;\n \n /**\n * 坐标转换\n * 将其他坐标系的坐标转换为高德地图使用的 GCJ-02 坐标系\n * @param coordinate 需要转换的坐标\n * @param type 原坐标系类型\n * @returns Promise<LatLng> 转换后的 GCJ-02 坐标\n */\n coordinateConvert(coordinate: LatLng, type: CoordinateType): Promise<LatLng>;\n \n // ==================== 定位配置 ====================\n \n /**\n * 设置是否返回逆地理编码信息\n * @param isReGeocode true: 返回地址信息; false: 只返回坐标\n */\n setLocatingWithReGeocode(isReGeocode: boolean): void;\n \n /**\n * 设置定位模式(Android)\n * @param mode 定位模式:0-低功耗, 1-仅设备, 2-高精度\n */\n setLocationMode(mode: LocationMode): void;\n \n /**\n * 设置定位间隔(毫秒)\n * @param interval 定位间隔时间,单位毫秒,默认 2000ms\n */\n setInterval(interval: number): void;\n \n /**\n * 设置是否单次定位(Android)\n * @param isOnceLocation true: 单次定位; false: 连续定位\n */\n setOnceLocation(isOnceLocation: boolean): void;\n \n /**\n * 设置是否使用设备传感器(Android)\n * @param sensorEnable true: 使用传感器; false: 不使用\n */\n setSensorEnable(sensorEnable: boolean): void;\n \n /**\n * 设置是否允许 WiFi 扫描(Android)\n * @param wifiScan true: 允许; false: 不允许\n */\n setWifiScan(wifiScan: boolean): void;\n \n /**\n * 设置是否 GPS 优先(Android)\n * @param gpsFirst true: GPS 优先; false: 网络优先\n */\n setGpsFirst(gpsFirst: boolean): void;\n \n /**\n * 设置是否等待 WiFi 列表刷新(Android)\n * @param onceLocationLatest true: 等待; false: 不等待\n */\n setOnceLocationLatest(onceLocationLatest: boolean): void;\n \n /**\n * 设置逆地理编码语言\n * @param language 语言代码,如 \"zh-CN\", \"en\"\n */\n setGeoLanguage(language: string): void;\n \n /**\n * 设置是否使用缓存策略(Android)\n * @param locationCacheEnable true: 使用缓存; false: 不使用\n */\n setLocationCacheEnable(locationCacheEnable: boolean): void;\n \n /**\n * 设置网络请求超时时间(Android)\n * @param httpTimeOut 超时时间,单位毫秒\n */\n setHttpTimeOut(httpTimeOut: number): void;\n \n /**\n * 设置期望的定位精度(iOS)\n * @param accuracy 精度级别:0-最佳, 1-10米, 2-100米, 3-1公里, 4-3公里\n */\n setDesiredAccuracy(accuracy: LocationAccuracy): void;\n \n /**\n * 设置定位超时时间(秒)\n * @param timeout 超时时间,单位秒,默认 10 秒\n */\n setLocationTimeout(timeout: number): void;\n \n /**\n * 设置逆地理编码超时时间(秒)\n * @param timeout 超时时间,单位秒,默认 5 秒\n */\n setReGeocodeTimeout(timeout: number): void;\n \n /**\n * 设置距离过滤器(米)(iOS)\n * 只有移动超过指定距离才会更新位置\n * @param distance 距离阈值,单位米\n */\n setDistanceFilter(distance: number): void;\n \n /**\n * 设置是否自动暂停位置更新(iOS)\n * @param pauses true: 自动暂停; false: 不暂停\n */\n setPausesLocationUpdatesAutomatically(pauses: boolean): void;\n \n /**\n * 设置是否允许后台定位(iOS)\n * @param allows true: 允许; false: 不允许\n */\n setAllowsBackgroundLocationUpdates(allows: boolean): void;\n \n /**\n * 设置定位协议\n * @param protocol 协议类型\n */\n setLocationProtocol(protocol: string): void;\n \n // ==================== 方向更新 (iOS) ====================\n \n /**\n * 开始更新设备方向(罗盘朝向)\n * 通过 onHeadingUpdate 事件接收方向更新\n * @platform ios\n */\n startUpdatingHeading(): void;\n \n /**\n * 停止更新设备方向\n * @platform ios\n */\n stopUpdatingHeading(): void;\n \n // ==================== 权限管理 ====================\n \n /**\n * 检查位置权限状态\n * @returns Promise<PermissionStatus> 权限状态\n */\n checkLocationPermission(): Promise<PermissionStatus>;\n \n /**\n * 请求位置权限\n * @returns Promise<PermissionStatus> 请求后的权限状态\n */\n requestLocationPermission(): Promise<PermissionStatus>;\n \n // ==================== 便捷方法 ====================\n \n /**\n * 添加定位监听器(便捷方法)\n * 封装了 addListener,提供更简洁的 API\n * @param listener 定位回调函数\n * @returns 订阅对象,调用 remove() 取消监听\n */\n addLocationListener(listener: LocationListener): { remove: () => void };\n}\n\n// 获取原生模块实例 - 添加容错处理\nlet nativeModule: ExpoGaodeMapModule | null = null;\n\ntry {\n nativeModule = requireNativeModule<ExpoGaodeMapModule>('ExpoGaodeMap');\n} catch (error) {\n console.warn('ExpoGaodeMap 原生模块加载失败:', error);\n}\n\n// 如果模块加载失败,创建一个空的代理对象防止崩溃\nif (!nativeModule) {\n console.error('ExpoGaodeMap: 原生模块不可用,请检查配置');\n}\n\n// 记录最近一次 initSDK 的配置(含 webKey)\nlet _sdkConfig: SDKConfig | null = null;\n\n// 扩展原生模块,添加便捷方法\nconst ExpoGaodeMapModuleWithHelpers = {\n ...(nativeModule || {}),\n\n /**\n * 初始化 SDK,并缓存配置(包含 webKey)\n */\n initSDK(config: SDKConfig): void {\n _sdkConfig = config ?? null;\n nativeModule?.initSDK?.(config);\n },\n\n /**\n * 添加定位监听器(便捷方法)\n * 自动订阅 onLocationUpdate 事件,提供容错处理\n * @param listener 定位回调函数\n * @returns 订阅对象,调用 remove() 取消监听\n * @throws 如果底层模块不可用,返回一个空操作的订阅对象\n */\n addLocationListener(listener: LocationListener): { remove: () => void } {\n // 使用可选链和空值合并,确保即使模块不可用也不会崩溃\n return nativeModule?.addListener?.('onLocationUpdate', listener) || {\n remove: () => {},\n };\n },\n};\n\n/**\n* 获取最近一次 initSDK 的配置\n*/\nexport function getSDKConfig(): SDKConfig | null {\n return _sdkConfig;\n}\n\n/**\n* 获取用于 Web API 的 webKey(若未初始化或未提供则返回 undefined)\n*/\nexport function getWebKey(): string | undefined {\n return _sdkConfig?.webKey;\n}\n\nexport default ExpoGaodeMapModuleWithHelpers as ExpoGaodeMapModule;\n"]}
|
package/build/index.d.ts
CHANGED
|
@@ -6,5 +6,6 @@ export { default as MapView } from './ExpoGaodeMapView';
|
|
|
6
6
|
export type { MapViewRef } from './ExpoGaodeMapView';
|
|
7
7
|
export { Marker, Polyline, Polygon, Circle, HeatMap, MultiPoint, Cluster, } from './components/overlays';
|
|
8
8
|
export { requireModule, OptionalModules, getInstalledModules, printModuleInfo, createLazyLoader, } from './utils/ModuleLoader';
|
|
9
|
+
export { getSDKConfig, getWebKey } from './ExpoGaodeMapModule';
|
|
9
10
|
export { default } from './ExpoGaodeMapModule';
|
|
10
11
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAYA,cAAc,sBAAsB,CAAC;AACrC,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAGrE,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGxE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACxD,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,EACL,MAAM,EACN,QAAQ,EACR,OAAO,EACP,MAAM,EACN,OAAO,EACP,UAAU,EACV,OAAO,GACR,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC"}
|
package/build/index.js
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
3
|
+
* @Date : 2025-12-03 14:27:06
|
|
4
|
+
* @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
5
|
+
* @LastEditTime : 2025-12-09 11:32:54
|
|
6
|
+
* @FilePath : /expo-gaode-map/packages/core/src/index.ts
|
|
7
|
+
* @Description :
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2025 by 尚博信_王强, All Rights Reserved.
|
|
10
|
+
*/
|
|
1
11
|
// 导出类型定义
|
|
2
12
|
export * from './ExpoGaodeMap.types';
|
|
3
13
|
export * from './types';
|
|
@@ -9,6 +19,8 @@ export { default as MapView } from './ExpoGaodeMapView';
|
|
|
9
19
|
export { Marker, Polyline, Polygon, Circle, HeatMap, MultiPoint, Cluster, } from './components/overlays';
|
|
10
20
|
// 导出模块检测工具
|
|
11
21
|
export { requireModule, OptionalModules, getInstalledModules, printModuleInfo, createLazyLoader, } from './utils/ModuleLoader';
|
|
22
|
+
// 导出便捷读取的 SDK 配置与 webKey
|
|
23
|
+
export { getSDKConfig, getWebKey } from './ExpoGaodeMapModule';
|
|
12
24
|
// 默认导出原生模块
|
|
13
25
|
export { default } from './ExpoGaodeMapModule';
|
|
14
26
|
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,SAAS;AACT,cAAc,sBAAsB,CAAC;AACrC,cAAc,SAAS,CAAC;AAExB,qBAAqB;AACrB,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAKrE,WAAW;AACX,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAGxD,UAAU;AACV,OAAO,EACL,MAAM,EACN,QAAQ,EACR,OAAO,EACP,MAAM,EACN,OAAO,EACP,UAAU,EACV,OAAO,GACR,MAAM,uBAAuB,CAAC;AAE/B,WAAW;AACX,OAAO,EACL,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAE9B,yBAAyB;AACzB,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAE/D,WAAW;AACX,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC","sourcesContent":["/*\n * @Author : 尚博信_王强 wangqiang03@sunboxsoft.com\n * @Date : 2025-12-03 14:27:06\n * @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com\n * @LastEditTime : 2025-12-09 11:32:54\n * @FilePath : /expo-gaode-map/packages/core/src/index.ts\n * @Description : \n * \n * Copyright (c) 2025 by 尚博信_王强, All Rights Reserved. \n */\n\n// 导出类型定义\nexport * from './ExpoGaodeMap.types';\nexport * from './types';\n\n// 导出原生模块 - 直接使用,无需封装\nexport { default as ExpoGaodeMapModule } from './ExpoGaodeMapModule';\n\n// 从 ExpoGaodeMapModule 重新导出类型,方便使用\nexport type { SDKConfig, PermissionStatus } from './ExpoGaodeMapModule';\n\n// 导出地图视图组件\nexport { default as MapView } from './ExpoGaodeMapView';\nexport type { MapViewRef } from './ExpoGaodeMapView';\n\n// 导出覆盖物组件\nexport {\n Marker,\n Polyline,\n Polygon,\n Circle,\n HeatMap,\n MultiPoint,\n Cluster,\n} from './components/overlays';\n\n// 导出模块检测工具\nexport {\n requireModule,\n OptionalModules,\n getInstalledModules,\n printModuleInfo,\n createLazyLoader,\n} from './utils/ModuleLoader';\n\n// 导出便捷读取的 SDK 配置与 webKey\nexport { getSDKConfig, getWebKey } from './ExpoGaodeMapModule';\n\n// 默认导出原生模块\nexport { default } from './ExpoGaodeMapModule';\n"]}
|
package/ios/ExpoGaodeMap.podspec
CHANGED
|
@@ -19,12 +19,10 @@ Pod::Spec.new do |s|
|
|
|
19
19
|
s.static_framework = true
|
|
20
20
|
|
|
21
21
|
s.dependency 'ExpoModulesCore'
|
|
22
|
-
|
|
23
|
-
# 核心依赖 - 3D地图和定位
|
|
24
|
-
s.dependency 'AMap3DMap', '10.0.600'
|
|
22
|
+
s.dependency 'AMapFoundation'
|
|
25
23
|
s.dependency 'AMapLocation'
|
|
24
|
+
s.dependency 'AMap3DMap'
|
|
26
25
|
|
|
27
|
-
|
|
28
26
|
# Swift/Objective-C compatibility
|
|
29
27
|
s.pod_target_xcconfig = {
|
|
30
28
|
'DEFINES_MODULE' => 'YES',
|
|
@@ -16,16 +16,46 @@ public class ExpoGaodeMapModule: Module {
|
|
|
16
16
|
private var locationManager: LocationManager?
|
|
17
17
|
/// 权限管理器实例
|
|
18
18
|
private var permissionManager: PermissionManager?
|
|
19
|
+
/// 隐私协议是否已同意(模块级别跟踪)
|
|
20
|
+
private static var privacyAgreed: Bool = false
|
|
19
21
|
|
|
20
22
|
public func definition() -> ModuleDefinition {
|
|
21
23
|
Name("ExpoGaodeMap")
|
|
22
24
|
|
|
23
|
-
//
|
|
25
|
+
// 模块初始化时不设置隐私合规
|
|
26
|
+
// 需要在用户同意隐私协议后手动调用 updatePrivacyCompliance 方法
|
|
24
27
|
OnCreate {
|
|
25
|
-
|
|
28
|
+
// 仅更新隐私信息显示状态,不表示用户已同意
|
|
26
29
|
MAMapView.updatePrivacyShow(AMapPrivacyShowStatus.didShow, privacyInfo: AMapPrivacyInfoStatus.didContain)
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
print("ℹ️ ExpoGaodeMap: 隐私信息已更新,但需要用户同意隐私协议才能使用 SDK")
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ==================== 隐私合规管理 ====================
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 更新隐私合规状态
|
|
37
|
+
* 必须在用户同意隐私协议后调用
|
|
38
|
+
*/
|
|
39
|
+
Function("updatePrivacyCompliance") { (hasAgreed: Bool) in
|
|
40
|
+
ExpoGaodeMapModule.privacyAgreed = hasAgreed
|
|
41
|
+
if hasAgreed {
|
|
42
|
+
MAMapView.updatePrivacyAgree(AMapPrivacyAgreeStatus.didAgree)
|
|
43
|
+
print("✅ ExpoGaodeMap: 用户已同意隐私协议,可以使用 SDK")
|
|
44
|
+
|
|
45
|
+
// 在用户同意后,如果尚未设置 API Key,则尝试从 Info.plist 读取并设置
|
|
46
|
+
if AMapServices.shared().apiKey == nil || AMapServices.shared().apiKey?.isEmpty == true {
|
|
47
|
+
if let plistKey = Bundle.main.infoDictionary?["AMapApiKey"] as? String, !plistKey.isEmpty {
|
|
48
|
+
AMapServices.shared().apiKey = plistKey
|
|
49
|
+
AMapServices.shared().enableHTTPS = true
|
|
50
|
+
print("✅ ExpoGaodeMap: 从 Info.plist 读取并设置 AMapApiKey 成功")
|
|
51
|
+
} else {
|
|
52
|
+
print("⚠️ ExpoGaodeMap: Info.plist 未找到 AMapApiKey,后续需通过 initSDK 提供 iosKey")
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
MAMapView.updatePrivacyAgree(AMapPrivacyAgreeStatus.notAgree)
|
|
57
|
+
print("⚠️ ExpoGaodeMap: 用户未同意隐私协议,SDK 功能将受限")
|
|
58
|
+
}
|
|
29
59
|
}
|
|
30
60
|
|
|
31
61
|
// ==================== SDK 初始化 ====================
|
|
@@ -35,10 +65,37 @@ public class ExpoGaodeMapModule: Module {
|
|
|
35
65
|
* @param config 配置字典,包含 iosKey
|
|
36
66
|
*/
|
|
37
67
|
Function("initSDK") { (config: [String: String]) in
|
|
38
|
-
|
|
39
|
-
|
|
68
|
+
// 检查是否已同意隐私协议
|
|
69
|
+
if !ExpoGaodeMapModule.privacyAgreed {
|
|
70
|
+
print("⚠️ ExpoGaodeMap: 用户未同意隐私协议,无法初始化 SDK")
|
|
71
|
+
return
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 1) 优先使用传入的 iosKey;2) 否则回退读取 Info.plist 的 AMapApiKey
|
|
75
|
+
let providedKey = config["iosKey"]?.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
76
|
+
var finalKey: String? = (providedKey?.isEmpty == false) ? providedKey : nil
|
|
77
|
+
if finalKey == nil {
|
|
78
|
+
if let plistKey = Bundle.main.infoDictionary?["AMapApiKey"] as? String, !plistKey.isEmpty {
|
|
79
|
+
finalKey = plistKey
|
|
80
|
+
print("ℹ️ ExpoGaodeMap: initSDK 未提供 iosKey,已从 Info.plist 使用 AMapApiKey")
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
guard let keyToUse = finalKey, !keyToUse.isEmpty else {
|
|
85
|
+
print("⚠️ ExpoGaodeMap: 未提供 iosKey 且 Info.plist 中也无 AMapApiKey,无法初始化 SDK")
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// 设置 API Key(若与现有不同或尚未设置)
|
|
90
|
+
if AMapServices.shared().apiKey != keyToUse {
|
|
91
|
+
AMapServices.shared().apiKey = keyToUse
|
|
92
|
+
}
|
|
40
93
|
AMapServices.shared().enableHTTPS = true
|
|
94
|
+
|
|
95
|
+
// 初始化定位管理器(触发原生侧懒加载)
|
|
41
96
|
self.getLocationManager()
|
|
97
|
+
|
|
98
|
+
print("✅ ExpoGaodeMap: 已设置 API Key 并完成初始化(来源:\(providedKey != nil ? "入参 iosKey" : "Info.plist"))")
|
|
42
99
|
}
|
|
43
100
|
|
|
44
101
|
/**
|
|
@@ -54,6 +111,18 @@ public class ExpoGaodeMapModule: Module {
|
|
|
54
111
|
* 开始连续定位
|
|
55
112
|
*/
|
|
56
113
|
Function("start") {
|
|
114
|
+
// 检查隐私协议状态
|
|
115
|
+
if !ExpoGaodeMapModule.privacyAgreed {
|
|
116
|
+
print("⚠️ ExpoGaodeMap: 用户未同意隐私协议,无法开始定位")
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 检查是否已设置 API Key
|
|
121
|
+
if AMapServices.shared().apiKey == nil || AMapServices.shared().apiKey?.isEmpty == true {
|
|
122
|
+
print("⚠️ ExpoGaodeMap: 未设置 API Key,无法开始定位")
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
|
|
57
126
|
self.getLocationManager().start()
|
|
58
127
|
}
|
|
59
128
|
|
|
@@ -76,6 +145,18 @@ public class ExpoGaodeMapModule: Module {
|
|
|
76
145
|
* 返回位置信息和逆地理编码结果
|
|
77
146
|
*/
|
|
78
147
|
AsyncFunction("getCurrentLocation") { (promise: Promise) in
|
|
148
|
+
// 检查隐私协议状态
|
|
149
|
+
if !ExpoGaodeMapModule.privacyAgreed {
|
|
150
|
+
promise.reject("PRIVACY_NOT_AGREED", "用户未同意隐私协议,无法获取位置")
|
|
151
|
+
return
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// 检查是否已设置 API Key
|
|
155
|
+
if AMapServices.shared().apiKey == nil || AMapServices.shared().apiKey?.isEmpty == true {
|
|
156
|
+
promise.reject("API_KEY_NOT_SET", "未设置 API Key,无法获取位置")
|
|
157
|
+
return
|
|
158
|
+
}
|
|
159
|
+
|
|
79
160
|
let status = CLLocationManager.authorizationStatus()
|
|
80
161
|
|
|
81
162
|
if status == .authorizedAlways || status == .authorizedWhenInUse {
|
package/package.json
CHANGED
|
@@ -32,29 +32,14 @@ const withGaodeMapInfoPlist = (config, props) => {
|
|
|
32
32
|
});
|
|
33
33
|
};
|
|
34
34
|
/**
|
|
35
|
-
* iOS:
|
|
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' })
|
|
36
42
|
*/
|
|
37
|
-
const withGaodeMapAppDelegate = (config, props) => {
|
|
38
|
-
return (0, config_plugins_1.withAppDelegate)(config, (config) => {
|
|
39
|
-
if (!props.iosApiKey) {
|
|
40
|
-
return config;
|
|
41
|
-
}
|
|
42
|
-
let contents = config.modResults.contents;
|
|
43
|
-
// 添加 import 语句
|
|
44
|
-
if (!contents.includes('#import <AMapFoundationKit/AMapFoundationKit.h>')) {
|
|
45
|
-
// 在 #import "AppDelegate.h" 之后添加
|
|
46
|
-
contents = contents.replace(/#import "AppDelegate.h"/g, `#import "AppDelegate.h"\n#import <AMapFoundationKit/AMapFoundationKit.h>`);
|
|
47
|
-
}
|
|
48
|
-
// 在 didFinishLaunchingWithOptions 方法中添加初始化代码
|
|
49
|
-
const initCode = ` [AMapServices sharedServices].apiKey = @"${props.iosApiKey}";`;
|
|
50
|
-
if (!contents.includes(initCode)) {
|
|
51
|
-
// 在 didFinishLaunchingWithOptions 方法的开始处添加
|
|
52
|
-
contents = contents.replace(/(- \(BOOL\)application:\(UIApplication \*\)application didFinishLaunchingWithOptions:\(NSDictionary \*\)launchOptions\s*\{)/g, `$1\n${initCode}`);
|
|
53
|
-
}
|
|
54
|
-
config.modResults.contents = contents;
|
|
55
|
-
return config;
|
|
56
|
-
});
|
|
57
|
-
};
|
|
58
43
|
/**
|
|
59
44
|
* Android: 修改 AndroidManifest.xml 添加 API Key 和权限
|
|
60
45
|
*/
|
|
@@ -64,6 +49,27 @@ const withGaodeMapAndroidManifest = (config, props) => {
|
|
|
64
49
|
// 基础权限(库中已包含,这里不重复添加)
|
|
65
50
|
// INTERNET, ACCESS_NETWORK_STATE, ACCESS_WIFI_STATE
|
|
66
51
|
// ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION
|
|
52
|
+
// 添加基础权限(高德地图 SDK 必需)
|
|
53
|
+
const basePermissions = [
|
|
54
|
+
'android.permission.ACCESS_COARSE_LOCATION',
|
|
55
|
+
'android.permission.ACCESS_FINE_LOCATION',
|
|
56
|
+
'android.permission.ACCESS_NETWORK_STATE',
|
|
57
|
+
'android.permission.ACCESS_WIFI_STATE',
|
|
58
|
+
'android.permission.READ_PHONE_STATE',
|
|
59
|
+
'android.permission.BLUETOOTH',
|
|
60
|
+
'android.permission.BLUETOOTH_ADMIN',
|
|
61
|
+
];
|
|
62
|
+
if (!androidManifest['uses-permission']) {
|
|
63
|
+
androidManifest['uses-permission'] = [];
|
|
64
|
+
}
|
|
65
|
+
basePermissions.forEach((permission) => {
|
|
66
|
+
const hasPermission = androidManifest['uses-permission']?.some((item) => item.$?.['android:name'] === permission);
|
|
67
|
+
if (!hasPermission) {
|
|
68
|
+
androidManifest['uses-permission']?.push({
|
|
69
|
+
$: { 'android:name': permission },
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
});
|
|
67
73
|
// 后台定位权限(可选)
|
|
68
74
|
if (props.enableBackgroundLocation) {
|
|
69
75
|
const backgroundPermissions = [
|
|
@@ -151,7 +157,9 @@ const withGaodeMap = (config, props = {}) => {
|
|
|
151
157
|
}
|
|
152
158
|
// 应用 iOS 配置
|
|
153
159
|
config = withGaodeMapInfoPlist(config, props);
|
|
154
|
-
|
|
160
|
+
// 注意:不再需要修改 AppDelegate,因为:
|
|
161
|
+
// 1. SDK 会自动从 Info.plist 读取 AMapApiKey
|
|
162
|
+
// 2. 可以通过 ExpoGaodeMapModule.initSDK() 方法初始化
|
|
155
163
|
// 应用 Android 配置
|
|
156
164
|
config = withGaodeMapAndroidManifest(config, props);
|
|
157
165
|
config = withGaodeMapAppBuildGradle(config, props);
|
|
@@ -23,6 +23,8 @@ export interface SDKConfig {
|
|
|
23
23
|
androidKey?: string;
|
|
24
24
|
/** iOS 平台的高德地图 API Key */
|
|
25
25
|
iosKey?: string;
|
|
26
|
+
/** web api key 如果要使用expo-gaode-map-web-api相关的功能,需要配置web api key*/
|
|
27
|
+
webKey?: string;
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
/**
|
|
@@ -43,6 +45,15 @@ export interface PermissionStatus {
|
|
|
43
45
|
* 高德地图原生模块类声明
|
|
44
46
|
*/
|
|
45
47
|
declare class ExpoGaodeMapModule extends NativeModule<ExpoGaodeMapModuleEvents> {
|
|
48
|
+
// ==================== 隐私合规管理 ====================
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 更新隐私合规状态
|
|
52
|
+
* 必须在用户同意隐私协议后调用
|
|
53
|
+
* @param hasAgreed 用户是否已同意隐私协议
|
|
54
|
+
*/
|
|
55
|
+
updatePrivacyCompliance(hasAgreed: boolean): void;
|
|
56
|
+
|
|
46
57
|
// ==================== SDK 初始化 ====================
|
|
47
58
|
|
|
48
59
|
/**
|
|
@@ -257,23 +268,48 @@ if (!nativeModule) {
|
|
|
257
268
|
console.error('ExpoGaodeMap: 原生模块不可用,请检查配置');
|
|
258
269
|
}
|
|
259
270
|
|
|
271
|
+
// 记录最近一次 initSDK 的配置(含 webKey)
|
|
272
|
+
let _sdkConfig: SDKConfig | null = null;
|
|
273
|
+
|
|
260
274
|
// 扩展原生模块,添加便捷方法
|
|
261
275
|
const ExpoGaodeMapModuleWithHelpers = {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
276
|
+
...(nativeModule || {}),
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* 初始化 SDK,并缓存配置(包含 webKey)
|
|
280
|
+
*/
|
|
281
|
+
initSDK(config: SDKConfig): void {
|
|
282
|
+
_sdkConfig = config ?? null;
|
|
283
|
+
nativeModule?.initSDK?.(config);
|
|
284
|
+
},
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* 添加定位监听器(便捷方法)
|
|
288
|
+
* 自动订阅 onLocationUpdate 事件,提供容错处理
|
|
289
|
+
* @param listener 定位回调函数
|
|
290
|
+
* @returns 订阅对象,调用 remove() 取消监听
|
|
291
|
+
* @throws 如果底层模块不可用,返回一个空操作的订阅对象
|
|
292
|
+
*/
|
|
293
|
+
addLocationListener(listener: LocationListener): { remove: () => void } {
|
|
294
|
+
// 使用可选链和空值合并,确保即使模块不可用也不会崩溃
|
|
295
|
+
return nativeModule?.addListener?.('onLocationUpdate', listener) || {
|
|
296
|
+
remove: () => {},
|
|
297
|
+
};
|
|
298
|
+
},
|
|
277
299
|
};
|
|
278
300
|
|
|
301
|
+
/**
|
|
302
|
+
* 获取最近一次 initSDK 的配置
|
|
303
|
+
*/
|
|
304
|
+
export function getSDKConfig(): SDKConfig | null {
|
|
305
|
+
return _sdkConfig;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* 获取用于 Web API 的 webKey(若未初始化或未提供则返回 undefined)
|
|
310
|
+
*/
|
|
311
|
+
export function getWebKey(): string | undefined {
|
|
312
|
+
return _sdkConfig?.webKey;
|
|
313
|
+
}
|
|
314
|
+
|
|
279
315
|
export default ExpoGaodeMapModuleWithHelpers as ExpoGaodeMapModule;
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
3
|
+
* @Date : 2025-12-03 14:27:06
|
|
4
|
+
* @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
5
|
+
* @LastEditTime : 2025-12-09 11:32:54
|
|
6
|
+
* @FilePath : /expo-gaode-map/packages/core/src/index.ts
|
|
7
|
+
* @Description :
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2025 by 尚博信_王强, All Rights Reserved.
|
|
10
|
+
*/
|
|
1
11
|
|
|
2
12
|
// 导出类型定义
|
|
3
13
|
export * from './ExpoGaodeMap.types';
|
|
@@ -33,5 +43,8 @@ export {
|
|
|
33
43
|
createLazyLoader,
|
|
34
44
|
} from './utils/ModuleLoader';
|
|
35
45
|
|
|
46
|
+
// 导出便捷读取的 SDK 配置与 webKey
|
|
47
|
+
export { getSDKConfig, getWebKey } from './ExpoGaodeMapModule';
|
|
48
|
+
|
|
36
49
|
// 默认导出原生模块
|
|
37
50
|
export { default } from './ExpoGaodeMapModule';
|