expo-gaode-map-navigation 1.0.1-next.1 → 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/build/map/ExpoGaodeMapModule.js +5 -5
- 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
|
@@ -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;
|
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",
|
|
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');
|
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ConfigPlugin,
|
|
3
|
-
withInfoPlist,
|
|
4
|
-
withAndroidManifest,
|
|
5
|
-
withAppBuildGradle,
|
|
6
|
-
createRunOncePlugin,
|
|
7
|
-
WarningAggregator,
|
|
8
|
-
} from '@expo/config-plugins';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* 高德地图插件配置类型
|
|
12
|
-
*/
|
|
13
|
-
export type GaodeMapPluginProps = {
|
|
14
|
-
/** iOS 平台 API Key */
|
|
15
|
-
iosApiKey?: string;
|
|
16
|
-
/** Android 平台 API Key */
|
|
17
|
-
androidApiKey?: string;
|
|
18
|
-
/** 是否启用定位功能 */
|
|
19
|
-
enableLocation?: boolean;
|
|
20
|
-
/** iOS 定位权限描述 */
|
|
21
|
-
locationDescription?: string;
|
|
22
|
-
/** 是否启用后台定位(Android & iOS) */
|
|
23
|
-
enableBackgroundLocation?: boolean;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* iOS: 修改 Info.plist 添加 API Key 和权限
|
|
28
|
-
*/
|
|
29
|
-
const withGaodeMapInfoPlist: ConfigPlugin<GaodeMapPluginProps> = (config, props) => {
|
|
30
|
-
return withInfoPlist(config, (config) => {
|
|
31
|
-
// 添加高德地图 API Key
|
|
32
|
-
if (props.iosApiKey) {
|
|
33
|
-
config.modResults.AMapApiKey = props.iosApiKey;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// 添加定位相关权限
|
|
37
|
-
if (props.enableLocation !== false) {
|
|
38
|
-
const description = props.locationDescription || '需要访问您的位置信息以提供地图服务';
|
|
39
|
-
|
|
40
|
-
// 使用时定位权限(必需)
|
|
41
|
-
config.modResults.NSLocationWhenInUseUsageDescription = description;
|
|
42
|
-
|
|
43
|
-
// 后台定位权限(可选)
|
|
44
|
-
if (props.enableBackgroundLocation) {
|
|
45
|
-
config.modResults.NSLocationAlwaysUsageDescription = description;
|
|
46
|
-
config.modResults.NSLocationAlwaysAndWhenInUseUsageDescription = description;
|
|
47
|
-
|
|
48
|
-
// 添加后台定位模式
|
|
49
|
-
if (!config.modResults.UIBackgroundModes) {
|
|
50
|
-
config.modResults.UIBackgroundModes = [];
|
|
51
|
-
}
|
|
52
|
-
if (!config.modResults.UIBackgroundModes.includes('location')) {
|
|
53
|
-
config.modResults.UIBackgroundModes.push('location');
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return config;
|
|
59
|
-
});
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* iOS: 注意 - 不再需要修改 AppDelegate
|
|
64
|
-
*
|
|
65
|
-
* 高德地图 SDK 已经支持从 Info.plist 自动读取 API Key
|
|
66
|
-
* 并且我们在 ExpoGaodeMapModule.swift 中提供了 initSDK 方法
|
|
67
|
-
* 用户可以选择以下任一方式初始化:
|
|
68
|
-
* 1. 通过 Info.plist 中的 AMapApiKey 字段(自动读取)
|
|
69
|
-
* 2. 通过 JavaScript 调用 ExpoGaodeMap.initSDK({ iosKey: 'your-key' })
|
|
70
|
-
*/
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Android: 修改 AndroidManifest.xml 添加 API Key 和权限
|
|
74
|
-
*/
|
|
75
|
-
const withGaodeMapAndroidManifest: ConfigPlugin<GaodeMapPluginProps> = (config, props) => {
|
|
76
|
-
return withAndroidManifest(config, (config) => {
|
|
77
|
-
const androidManifest = config.modResults.manifest;
|
|
78
|
-
|
|
79
|
-
// 添加基础权限(高德地图 SDK 必需)
|
|
80
|
-
const basePermissions = [
|
|
81
|
-
'android.permission.ACCESS_COARSE_LOCATION',
|
|
82
|
-
'android.permission.ACCESS_FINE_LOCATION',
|
|
83
|
-
'android.permission.ACCESS_NETWORK_STATE',
|
|
84
|
-
'android.permission.ACCESS_WIFI_STATE',
|
|
85
|
-
'android.permission.READ_PHONE_STATE',
|
|
86
|
-
'android.permission.BLUETOOTH',
|
|
87
|
-
'android.permission.BLUETOOTH_ADMIN',
|
|
88
|
-
];
|
|
89
|
-
|
|
90
|
-
if (!androidManifest['uses-permission']) {
|
|
91
|
-
androidManifest['uses-permission'] = [];
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
basePermissions.forEach((permission) => {
|
|
95
|
-
const hasPermission = androidManifest['uses-permission']?.some(
|
|
96
|
-
(item) => item.$?.['android:name'] === permission
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
if (!hasPermission) {
|
|
100
|
-
androidManifest['uses-permission']?.push({
|
|
101
|
-
$: { 'android:name': permission },
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
// 后台定位权限(可选,仅在 enableBackgroundLocation 为 true 时添加)
|
|
107
|
-
if (props.enableBackgroundLocation) {
|
|
108
|
-
const backgroundPermissions = [
|
|
109
|
-
'android.permission.ACCESS_BACKGROUND_LOCATION',
|
|
110
|
-
'android.permission.FOREGROUND_SERVICE',
|
|
111
|
-
'android.permission.FOREGROUND_SERVICE_LOCATION',
|
|
112
|
-
];
|
|
113
|
-
|
|
114
|
-
if (!androidManifest['uses-permission']) {
|
|
115
|
-
androidManifest['uses-permission'] = [];
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
backgroundPermissions.forEach((permission) => {
|
|
119
|
-
const hasPermission = androidManifest['uses-permission']?.some(
|
|
120
|
-
(item) => item.$?.['android:name'] === permission
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
if (!hasPermission) {
|
|
124
|
-
androidManifest['uses-permission']?.push({
|
|
125
|
-
$: { 'android:name': permission },
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// 添加前台服务(如果启用后台定位)
|
|
132
|
-
const mainApplication = androidManifest.application?.[0];
|
|
133
|
-
if (mainApplication && props.enableBackgroundLocation) {
|
|
134
|
-
if (!mainApplication['service']) {
|
|
135
|
-
mainApplication['service'] = [];
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// 检查是否已存在 LocationForegroundService
|
|
139
|
-
const hasService = mainApplication['service'].some(
|
|
140
|
-
(item) => item.$?.['android:name'] === 'expo.modules.gaodemap.services.LocationForegroundService'
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
if (!hasService) {
|
|
144
|
-
mainApplication['service'].push({
|
|
145
|
-
$: {
|
|
146
|
-
'android:name': 'expo.modules.gaodemap.services.LocationForegroundService',
|
|
147
|
-
'android:enabled': 'true',
|
|
148
|
-
'android:exported': 'false',
|
|
149
|
-
'android:foregroundServiceType': 'location',
|
|
150
|
-
},
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// 添加 API Key 到 application 标签
|
|
156
|
-
if (mainApplication && props.androidApiKey) {
|
|
157
|
-
if (!mainApplication['meta-data']) {
|
|
158
|
-
mainApplication['meta-data'] = [];
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// 检查是否已存在
|
|
162
|
-
const hasApiKey = mainApplication['meta-data'].some(
|
|
163
|
-
(item) => item.$?.['android:name'] === 'com.amap.api.v2.apikey'
|
|
164
|
-
);
|
|
165
|
-
|
|
166
|
-
if (!hasApiKey) {
|
|
167
|
-
mainApplication['meta-data'].push({
|
|
168
|
-
$: {
|
|
169
|
-
'android:name': 'com.amap.api.v2.apikey',
|
|
170
|
-
'android:value': props.androidApiKey,
|
|
171
|
-
},
|
|
172
|
-
});
|
|
173
|
-
} else {
|
|
174
|
-
// 更新现有的 API Key
|
|
175
|
-
const apiKeyIndex = mainApplication['meta-data'].findIndex(
|
|
176
|
-
(item) => item.$?.['android:name'] === 'com.amap.api.v2.apikey'
|
|
177
|
-
);
|
|
178
|
-
if (apiKeyIndex !== -1) {
|
|
179
|
-
mainApplication['meta-data'][apiKeyIndex].$ = {
|
|
180
|
-
'android:name': 'com.amap.api.v2.apikey',
|
|
181
|
-
'android:value': props.androidApiKey,
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
return config;
|
|
188
|
-
});
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Android: 修改 app/build.gradle(预留扩展)
|
|
193
|
-
*/
|
|
194
|
-
const withGaodeMapAppBuildGradle: ConfigPlugin<GaodeMapPluginProps> = (config, props) => {
|
|
195
|
-
return withAppBuildGradle(config, (config) => {
|
|
196
|
-
// Android 3D 地图 SDK 10.0+ 已内置搜索功能
|
|
197
|
-
// 不需要额外的 Gradle 配置
|
|
198
|
-
return config;
|
|
199
|
-
});
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* 主插件函数 - 组合所有修改器
|
|
204
|
-
*/
|
|
205
|
-
const withGaodeMap: ConfigPlugin<GaodeMapPluginProps> = (config, props = {}) => {
|
|
206
|
-
// 验证配置
|
|
207
|
-
if (!props.iosApiKey && !props.androidApiKey) {
|
|
208
|
-
WarningAggregator.addWarningIOS(
|
|
209
|
-
'expo-gaode-map-navigation',
|
|
210
|
-
'未配置 API Key。请在 app.json 的 plugins 中配置 iosApiKey 和 androidApiKey'
|
|
211
|
-
);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// 应用 iOS 配置
|
|
215
|
-
config = withGaodeMapInfoPlist(config, props);
|
|
216
|
-
// 注意:不再需要修改 AppDelegate,因为:
|
|
217
|
-
// 1. SDK 会自动从 Info.plist 读取 AMapApiKey
|
|
218
|
-
// 2. 可以通过 ExpoGaodeMapModule.initSDK() 方法初始化
|
|
219
|
-
|
|
220
|
-
// 应用 Android 配置
|
|
221
|
-
config = withGaodeMapAndroidManifest(config, props);
|
|
222
|
-
config = withGaodeMapAppBuildGradle(config, props);
|
|
223
|
-
|
|
224
|
-
return config;
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* 导出为可运行一次的插件
|
|
229
|
-
* 这确保插件只会运行一次,即使在配置中被多次引用
|
|
230
|
-
*/
|
|
231
|
-
export default createRunOncePlugin(withGaodeMap, 'expo-gaode-map-navigation', '1.0.0');
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"root":["./src/withgaodemap.ts"],"version":"5.9.3"}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* @Author : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
3
|
-
* @Date : 2025-12-03 20:12:54
|
|
4
|
-
* @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
5
|
-
* @LastEditTime : 2025-12-05 12:37:28
|
|
6
|
-
* @FilePath : /expo-gaode-map/packages/navigation/src/ExpoGaodeMapNaviView.tsx
|
|
7
|
-
* @Description :
|
|
8
|
-
*
|
|
9
|
-
* Copyright (c) 2025 by 尚博信_王强, All Rights Reserved.
|
|
10
|
-
*/
|
|
11
|
-
import { requireNativeViewManager } from 'expo-modules-core';
|
|
12
|
-
import * as React from 'react';
|
|
13
|
-
import type { Coordinates, NaviViewProps } from './types';
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* NaviView Ref 类型
|
|
17
|
-
*/
|
|
18
|
-
export interface NaviViewRef {
|
|
19
|
-
/**
|
|
20
|
-
* 开始导航
|
|
21
|
-
*/
|
|
22
|
-
startNavigation: (start: Coordinates | null, end: Coordinates, type: number) => Promise<void>;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* 停止导航
|
|
26
|
-
*/
|
|
27
|
-
stopNavigation: () => Promise<void>;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const NativeView: React.ComponentType<NaviViewProps & { ref?: React.Ref<any> }> = requireNativeViewManager('ExpoGaodeMapNaviView');
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* 高德导航视图组件
|
|
35
|
-
*
|
|
36
|
-
* 使用高德官方的导航界面,提供完整的导航体验,包括:
|
|
37
|
-
* - 路线规划和显示
|
|
38
|
-
* - 实时导航信息(距离、时间、道路名称)
|
|
39
|
-
* - 转向箭头和提示
|
|
40
|
-
* - 路况信息
|
|
41
|
-
* - 摄像头提示
|
|
42
|
-
* - 语音播报
|
|
43
|
-
*
|
|
44
|
-
* @example
|
|
45
|
-
* ```tsx
|
|
46
|
-
* import { NaviView } from 'expo-gaode-map-navigation';
|
|
47
|
-
*
|
|
48
|
-
* function NavigationScreen() {
|
|
49
|
-
* return (
|
|
50
|
-
* <NaviView
|
|
51
|
-
* style={{ flex: 1 }}
|
|
52
|
-
* naviType={0} // GPS 导航
|
|
53
|
-
* showCamera={true}
|
|
54
|
-
* enableVoice={true}
|
|
55
|
-
* onNaviInfoUpdate={(e) => {
|
|
56
|
-
* console.log('剩余距离:', e.nativeEvent.pathRetainDistance);
|
|
57
|
-
* }}
|
|
58
|
-
* onArrive={() => {
|
|
59
|
-
* console.log('到达目的地!');
|
|
60
|
-
* }}
|
|
61
|
-
* />
|
|
62
|
-
* );
|
|
63
|
-
* }
|
|
64
|
-
* ```
|
|
65
|
-
*/
|
|
66
|
-
export const NaviView = React.forwardRef<NaviViewRef, NaviViewProps>((props, ref) => {
|
|
67
|
-
const nativeRef = React.useRef<any>(null);
|
|
68
|
-
|
|
69
|
-
// 创建 API 引用
|
|
70
|
-
const apiRef: NaviViewRef = React.useMemo(() => ({
|
|
71
|
-
startNavigation: async (start: Coordinates | null, end: Coordinates, type: number) => {
|
|
72
|
-
if (!nativeRef.current) throw new Error('NaviView not initialized');
|
|
73
|
-
// 将对象解构为单独的参数传递给原生层
|
|
74
|
-
const startLat = start?.latitude ?? 0;
|
|
75
|
-
const startLng = start?.longitude ?? 0;
|
|
76
|
-
const endLat = end.latitude;
|
|
77
|
-
const endLng = end.longitude;
|
|
78
|
-
return nativeRef.current.startNavigation(startLat, startLng, endLat, endLng);
|
|
79
|
-
},
|
|
80
|
-
stopNavigation: async () => {
|
|
81
|
-
if (!nativeRef.current) throw new Error('NaviView not initialized');
|
|
82
|
-
return nativeRef.current.stopNavigation();
|
|
83
|
-
},
|
|
84
|
-
}), []);
|
|
85
|
-
|
|
86
|
-
// 暴露 API 给外部 ref
|
|
87
|
-
React.useImperativeHandle(ref, () => apiRef, [apiRef]);
|
|
88
|
-
|
|
89
|
-
return <NativeView ref={nativeRef} {...props} />;
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
NaviView.displayName = 'NaviView';
|
|
93
|
-
|
|
94
|
-
export default NaviView;
|