expo-gaode-map 2.0.0 → 2.1.0-beta.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.
@@ -13,17 +13,19 @@ const withGaodeMapInfoPlist = (config, props) => {
13
13
  // 添加定位相关权限
14
14
  if (props.enableLocation !== false) {
15
15
  const description = props.locationDescription || '需要访问您的位置信息以提供地图服务';
16
+ // 使用时定位权限(必需)
16
17
  config.modResults.NSLocationWhenInUseUsageDescription = description;
17
- config.modResults.NSLocationAlwaysUsageDescription = description;
18
- config.modResults.NSLocationAlwaysAndWhenInUseUsageDescription = description;
19
- }
20
- // 添加后台定位模式(如果需要)
21
- if (props.enableLocation !== false) {
22
- if (!config.modResults.UIBackgroundModes) {
23
- config.modResults.UIBackgroundModes = [];
24
- }
25
- if (!config.modResults.UIBackgroundModes.includes('location')) {
26
- config.modResults.UIBackgroundModes.push('location');
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
+ }
27
29
  }
28
30
  }
29
31
  return config;
@@ -59,23 +61,20 @@ const withGaodeMapAppDelegate = (config, props) => {
59
61
  const withGaodeMapAndroidManifest = (config, props) => {
60
62
  return (0, config_plugins_1.withAndroidManifest)(config, (config) => {
61
63
  const androidManifest = config.modResults.manifest;
62
- // 添加权限
63
- if (props.enableLocation !== false) {
64
- const permissions = [
65
- 'android.permission.ACCESS_COARSE_LOCATION',
66
- 'android.permission.ACCESS_FINE_LOCATION',
67
- 'android.permission.ACCESS_WIFI_STATE',
68
- 'android.permission.ACCESS_NETWORK_STATE',
69
- 'android.permission.CHANGE_WIFI_STATE',
70
- 'android.permission.INTERNET',
71
- 'android.permission.WRITE_EXTERNAL_STORAGE',
72
- 'android.permission.READ_EXTERNAL_STORAGE',
73
- 'android.permission.ACCESS_LOCATION_EXTRA_COMMANDS',
64
+ // 基础权限(库中已包含,这里不重复添加)
65
+ // INTERNET, ACCESS_NETWORK_STATE, ACCESS_WIFI_STATE
66
+ // ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION
67
+ // 后台定位权限(可选)
68
+ if (props.enableBackgroundLocation) {
69
+ const backgroundPermissions = [
70
+ 'android.permission.ACCESS_BACKGROUND_LOCATION',
71
+ 'android.permission.FOREGROUND_SERVICE',
72
+ 'android.permission.FOREGROUND_SERVICE_LOCATION',
74
73
  ];
75
74
  if (!androidManifest['uses-permission']) {
76
75
  androidManifest['uses-permission'] = [];
77
76
  }
78
- permissions.forEach((permission) => {
77
+ backgroundPermissions.forEach((permission) => {
79
78
  const hasPermission = androidManifest['uses-permission']?.some((item) => item.$?.['android:name'] === permission);
80
79
  if (!hasPermission) {
81
80
  androidManifest['uses-permission']?.push({
@@ -84,8 +83,26 @@ const withGaodeMapAndroidManifest = (config, props) => {
84
83
  }
85
84
  });
86
85
  }
87
- // 添加 API Key 到 application 标签
86
+ // 添加前台服务(如果启用后台定位)
88
87
  const mainApplication = androidManifest.application?.[0];
88
+ if (mainApplication && props.enableBackgroundLocation) {
89
+ if (!mainApplication['service']) {
90
+ mainApplication['service'] = [];
91
+ }
92
+ // 检查是否已存在 LocationForegroundService
93
+ const hasService = mainApplication['service'].some((item) => item.$?.['android:name'] === 'expo.modules.gaodemap.services.LocationForegroundService');
94
+ if (!hasService) {
95
+ mainApplication['service'].push({
96
+ $: {
97
+ 'android:name': 'expo.modules.gaodemap.services.LocationForegroundService',
98
+ 'android:enabled': 'true',
99
+ 'android:exported': 'false',
100
+ 'android:foregroundServiceType': 'location',
101
+ },
102
+ });
103
+ }
104
+ }
105
+ // 添加 API Key 到 application 标签
89
106
  if (mainApplication && props.androidApiKey) {
90
107
  if (!mainApplication['meta-data']) {
91
108
  mainApplication['meta-data'] = [];
@@ -115,12 +132,12 @@ const withGaodeMapAndroidManifest = (config, props) => {
115
132
  });
116
133
  };
117
134
  /**
118
- * Android: 修改 app/build.gradle 添加依赖
135
+ * Android: 修改 app/build.gradle(预留扩展)
119
136
  */
120
137
  const withGaodeMapAppBuildGradle = (config, props) => {
121
138
  return (0, config_plugins_1.withAppBuildGradle)(config, (config) => {
122
- // 这里可以添加额外的 Gradle 配置,如果需要的话
123
- // 例如添加 maven 仓库或其他依赖
139
+ // Android 3D 地图 SDK 10.0+ 已内置搜索功能
140
+ // 不需要额外的 Gradle 配置
124
141
  return config;
125
142
  });
126
143
  };
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+
1
2
  // 导出类型定义
2
3
  export * from './ExpoGaodeMap.types';
3
4
  export * from './types';
@@ -23,5 +24,14 @@ export {
23
24
  Cluster,
24
25
  } from './components/overlays';
25
26
 
27
+ // 导出模块检测工具
28
+ export {
29
+ requireModule,
30
+ OptionalModules,
31
+ getInstalledModules,
32
+ printModuleInfo,
33
+ createLazyLoader,
34
+ } from './utils/ModuleLoader';
35
+
26
36
  // 默认导出原生模块
27
37
  export { default } from './ExpoGaodeMapModule';
@@ -0,0 +1,115 @@
1
+ /**
2
+ * 模块检测器 - 用于检测可选模块是否已安装
3
+ */
4
+
5
+ /**
6
+ * 可选模块名称常量
7
+ */
8
+ export const OptionalModules = {
9
+ SEARCH: '@expo-gaode-map/search',
10
+ NAVIGATION: '@expo-gaode-map/navigation',
11
+ ROUTE: '@expo-gaode-map/route',
12
+ GEOCODER: '@expo-gaode-map/geocoder',
13
+ } as const;
14
+
15
+ /**
16
+ * 延迟加载可选模块
17
+ * 使用示例:
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * import { OptionalModules, lazyLoad } from 'expo-gaode-map';
22
+ *
23
+ * let SearchModule = null;
24
+ *
25
+ * function loadSearch() {
26
+ * if (SearchModule == null) {
27
+ * try {
28
+ * SearchModule = require('expo-gaode-map-search');
29
+ * } catch (error) {
30
+ * console.warn('搜索模块未安装');
31
+ * return null;
32
+ * }
33
+ * }
34
+ * return SearchModule;
35
+ * }
36
+ *
37
+ * // 使用
38
+ * const search = loadSearch();
39
+ * if (search) {
40
+ * const results = await search.searchPOI({ keyword: '餐厅' });
41
+ * }
42
+ * ```
43
+ */
44
+
45
+ /**
46
+ * 检查必需模块,如果未安装则抛出错误
47
+ * @param moduleName 模块名称
48
+ * @param featureName 功能名称(用于错误提示)
49
+ */
50
+ export function requireModule(moduleName: string, featureName: string): void {
51
+ console.warn(
52
+ `[expo-gaode-map] 使用 ${featureName} 需要安装 ${moduleName}。\n` +
53
+ `请运行: npm install ${moduleName}\n` +
54
+ `然后使用 try-catch 包裹 require('${moduleName}') 来加载`
55
+ );
56
+ }
57
+
58
+ /**
59
+ * 获取已安装的可选模块列表
60
+ * 注意: 此函数无法在运行时准确检测,仅作为文档说明
61
+ */
62
+ export function getInstalledModules(): string[] {
63
+ console.warn(
64
+ '[expo-gaode-map] getInstalledModules() 无法在运行时检测。\n' +
65
+ '请在编译时检查 package.json 中安装的模块'
66
+ );
67
+ return [];
68
+ }
69
+
70
+ /**
71
+ * 打印已安装模块信息(用于调试)
72
+ */
73
+ export function printModuleInfo(): void {
74
+ console.log('[expo-gaode-map] 核心模块: 已加载');
75
+ console.log('[expo-gaode-map] 可选模块检测:');
76
+ console.log(' - 使用 try-catch 包裹 require() 来检测可选模块');
77
+ console.log(' - 可用的可选模块:');
78
+ Object.entries(OptionalModules).forEach(([key, value]) => {
79
+ console.log(` - ${key}: ${value}`);
80
+ });
81
+ }
82
+
83
+ /**
84
+ * 创建延迟加载器
85
+ *
86
+ * @example
87
+ * ```typescript
88
+ * import { createLazyLoader } from 'expo-gaode-map';
89
+ *
90
+ * const loadSearch = createLazyLoader(() => require('expo-gaode-map-search'));
91
+ *
92
+ * // 使用时
93
+ * const SearchModule = loadSearch();
94
+ * if (SearchModule) {
95
+ * const results = await SearchModule.searchPOI({ keyword: '餐厅' });
96
+ * }
97
+ * ```
98
+ */
99
+ export function createLazyLoader<T>(loader: () => T): () => T | null {
100
+ let cached: T | null = null;
101
+ let attempted = false;
102
+
103
+ return () => {
104
+ if (!attempted) {
105
+ attempted = true;
106
+ try {
107
+ cached = loader();
108
+ } catch (error) {
109
+ console.warn('[expo-gaode-map] 模块加载失败:', error);
110
+ cached = null;
111
+ }
112
+ }
113
+ return cached;
114
+ };
115
+ }
package/DEPLOY_DOCS.md DELETED
@@ -1,209 +0,0 @@
1
- # 📚 文档网站部署指南
2
-
3
- 本文档说明如何部署 expo-gaode-map 的文档网站到 GitHub Pages。
4
-
5
- ## 🌟 项目结构
6
-
7
- ```
8
- expo-gaode-map/
9
- ├── website/ # 文档网站目录
10
- │ ├── docs/ # 文档源文件
11
- │ │ ├── .vitepress/ # VitePress 配置
12
- │ │ │ └── config.mts # 网站配置文件
13
- │ │ ├── guide/ # 指南文档
14
- │ │ ├── api/ # API 文档
15
- │ │ ├── examples/ # 示例文档
16
- │ │ └── index.md # 首页
17
- │ ├── package.json # 依赖配置
18
- │ └── README.md # 网站说明
19
- └── .github/
20
- └── workflows/
21
- └── deploy-docs.yml # 自动部署配置
22
- ```
23
-
24
- ## 🚀 快速部署
25
-
26
- ### 方式一:GitHub Actions 自动部署(推荐)
27
-
28
- 1. **启用 GitHub Pages**
29
-
30
- 进入你的 GitHub 仓库设置:
31
- - 点击 `Settings` > `Pages`
32
- - 在 **Source** 下选择 `GitHub Actions`
33
-
34
- 2. **推送代码**
35
-
36
- ```bash
37
- git add .
38
- git commit -m "Add documentation website"
39
- git push origin main
40
- ```
41
-
42
- 3. **等待部署完成**
43
-
44
- - 进入仓库的 `Actions` 标签页
45
- - 查看 "Deploy Docs" 工作流的运行状态
46
- - 部署成功后,访问: `https://<your-username>.github.io/expo-gaode-map/`
47
-
48
- ### 方式二:本地构建后手动部署
49
-
50
- 1. **安装依赖**
51
-
52
- ```bash
53
- cd website
54
- npm install
55
- ```
56
-
57
- 2. **构建网站**
58
-
59
- ```bash
60
- npm run docs:build
61
- ```
62
-
63
- 3. **部署到 GitHub Pages**
64
-
65
- ```bash
66
- # 进入构建产物目录
67
- cd docs/.vitepress/dist
68
-
69
- # 初始化 git 仓库
70
- git init
71
- git add -A
72
- git commit -m 'Deploy documentation'
73
-
74
- # 推送到 gh-pages 分支
75
- git push -f git@github.com:<your-username>/expo-gaode-map.git main:gh-pages
76
-
77
- cd ../../../..
78
- ```
79
-
80
- 4. **配置 GitHub Pages**
81
-
82
- - 进入 `Settings` > `Pages`
83
- - Source 选择 `Deploy from a branch`
84
- - Branch 选择 `gh-pages` 和 `/ (root)`
85
-
86
- ## 🔧 配置说明
87
-
88
- ### 修改 Base URL
89
-
90
- 如果你的 GitHub 仓库名不是 `expo-gaode-map`,需要修改配置:
91
-
92
- **文件:** `website/docs/.vitepress/config.mts`
93
-
94
- ```ts
95
- export default defineConfig({
96
- base: '/your-repo-name/', // 修改为你的仓库名
97
- // ...
98
- })
99
- ```
100
-
101
- **文件:** `.github/workflows/deploy-docs.yml`
102
-
103
- 确保工作流配置正确(当前配置已经是通用的,通常不需要修改)。
104
-
105
- ### 自定义域名(可选)
106
-
107
- 如果要使用自定义域名:
108
-
109
- 1. 在 `website/docs/public/` 目录下创建 `CNAME` 文件
110
- 2. 文件内容为你的域名,例如: `docs.yoursite.com`
111
- 3. 在你的域名 DNS 设置中添加 CNAME 记录指向 `<username>.github.io`
112
-
113
- ## 📝 本地开发
114
-
115
- ### 启动开发服务器
116
-
117
- ```bash
118
- cd website
119
- npm install
120
- npm run docs:dev
121
- ```
122
-
123
- 访问 http://localhost:5173 查看文档。
124
-
125
- ### 预览生产版本
126
-
127
- ```bash
128
- npm run docs:build
129
- npm run docs:preview
130
- ```
131
-
132
- ## 🎨 自定义文档
133
-
134
- ### 添加新页面
135
-
136
- 1. 在相应目录下创建 `.md` 文件
137
- 2. 在 `config.mts` 中添加导航和侧边栏配置
138
- 3. 编写文档内容
139
-
140
- ### 修改主题
141
-
142
- VitePress 支持主题自定义,详见 [VitePress 文档](https://vitepress.dev/guide/custom-theme)。
143
-
144
- ## ✅ 验证部署
145
-
146
- 部署完成后,访问以下 URL 验证:
147
-
148
- - **首页:** `https://<username>.github.io/expo-gaode-map/`
149
- - **快速开始:** `https://<username>.github.io/expo-gaode-map/guide/getting-started`
150
- - **API 文档:** `https://<username>.github.io/expo-gaode-map/api/`
151
-
152
- ## 🐛 常见问题
153
-
154
- ### 1. 页面样式丢失或 404
155
-
156
- **问题:** 部署后页面样式丢失或资源 404
157
-
158
- **解决方案:** 检查 `base` 配置是否正确设置为 `/your-repo-name/`
159
-
160
- ### 2. GitHub Actions 部署失败
161
-
162
- **问题:** Actions 工作流运行失败
163
-
164
- **解决方案:**
165
- - 检查 GitHub Pages 是否已启用
166
- - 确保选择了 "GitHub Actions" 作为 Source
167
- - 查看 Actions 日志获取详细错误信息
168
-
169
- ### 3. 本地可以访问,部署后无法访问
170
-
171
- **问题:** 本地开发正常,部署后无法访问
172
-
173
- **解决方案:**
174
- - 确认 GitHub Pages 设置正确
175
- - 等待几分钟让 DNS 传播
176
- - 清除浏览器缓存
177
-
178
- ### 4. 中文路径问题
179
-
180
- **问题:** 包含中文的文件名导致 URL 编码问题
181
-
182
- **解决方案:** 使用英文文件名,在文档内容中使用中文标题
183
-
184
- ## 📚 参考资源
185
-
186
- - [VitePress 官方文档](https://vitepress.dev/)
187
- - [GitHub Pages 文档](https://docs.github.com/en/pages)
188
- - [GitHub Actions 文档](https://docs.github.com/en/actions)
189
-
190
- ## 🤝 贡献文档
191
-
192
- 欢迎改进文档!
193
-
194
- 1. Fork 本仓库
195
- 2. 创建特性分支
196
- 3. 修改文档内容
197
- 4. 提交 Pull Request
198
-
199
- ## 📄 许可证
200
-
201
- MIT
202
-
203
- ---
204
-
205
- **需要帮助?**
206
-
207
- - 📝 [提交 Issue](https://github.com/TomWq/expo-gaode-map/issues)
208
- - 💬 [参与讨论](https://github.com/TomWq/expo-gaode-map/discussions)
209
- - 💬 加入 QQ 群: 952241387
@@ -1,119 +0,0 @@
1
- import ExpoModulesCore
2
-
3
- public class ExpoSmartrefreshlayoutModule: Module {
4
- public func definition() -> ModuleDefinition {
5
- // 模块名称
6
- Name("ExpoSmartrefreshlayout")
7
-
8
- // 定义事件
9
- Events(
10
- "onRefresh",
11
- "onLoadMore",
12
- "onStateChanged",
13
- "onHeaderMoving",
14
- "onFooterMoving"
15
- )
16
-
17
- // 注册 View 组件
18
- View(ExpoSmartrefreshlayoutView.self) {
19
-
20
- // ------------------- Events -------------------
21
- Events(
22
- "onRefresh",
23
- "onLoadMore",
24
- "onStateChanged",
25
- "onHeaderMoving",
26
- "onFooterMoving"
27
- )
28
-
29
- // ------------------- Props -------------------
30
-
31
- // 基础配置
32
- Prop("enableRefresh") { (view: ExpoSmartrefreshlayoutView, value: Bool) in
33
- view.setEnableRefresh(value)
34
- }
35
-
36
- Prop("enableLoadMore") { (view: ExpoSmartrefreshlayoutView, value: Bool) in
37
- view.setEnableLoadMore(value)
38
- }
39
-
40
- Prop("enableAutoLoadMore") { (view: ExpoSmartrefreshlayoutView, value: Bool) in
41
- view.setEnableAutoLoadMore(value)
42
- }
43
-
44
- // Header 类型
45
- Prop("headerType") { (view: ExpoSmartrefreshlayoutView, value: String) in
46
- view.setHeaderType(value)
47
- }
48
-
49
- // 经典样式配置
50
- Prop("classicRefreshHeaderProps") { (view: ExpoSmartrefreshlayoutView, value: [String: Any]) in
51
- view.setClassicRefreshHeaderProps(value)
52
- }
53
-
54
- Prop("classicLoadMoreFooterProps") { (view: ExpoSmartrefreshlayoutView, value: [String: Any]) in
55
- view.setClassicLoadMoreFooterProps(value)
56
- }
57
-
58
- // 自定义 Header 标志
59
- Prop("hasCustomHeader") { (view: ExpoSmartrefreshlayoutView, value: Bool) in
60
- view.setHasCustomHeader(value)
61
- }
62
-
63
- // 触觉反馈
64
- Prop("enableHapticFeedback") { (view: ExpoSmartrefreshlayoutView, value: Bool) in
65
- view.setEnableHapticFeedback(value)
66
- }
67
- }
68
-
69
- // ------------------- Commands/Functions -------------------
70
-
71
- /**
72
- * 完成刷新操作
73
- * @param view 视图实例
74
- * @param success 是否刷新成功
75
- * @param delay 延迟时间(毫秒)
76
- */
77
- Function("finishRefresh") { (view: ExpoSmartrefreshlayoutView, success: Bool, delay: Int) in
78
- view.finishRefresh(success: success, delay: delay)
79
- }
80
-
81
- /**
82
- * 完成加载更多操作
83
- * @param view 视图实例
84
- * @param success 是否加载成功
85
- * @param delay 延迟时间(毫秒)
86
- * @param noMoreData 是否没有更多数据
87
- */
88
- Function("finishLoadMore") { (view: ExpoSmartrefreshlayoutView, success: Bool, delay: Int, noMoreData: Bool) in
89
- view.finishLoadMore(success: success, delay: delay, noMoreData: noMoreData)
90
- }
91
-
92
- /**
93
- * 自动刷新
94
- * @param view 视图实例
95
- * @param delay 延迟时间(毫秒)
96
- */
97
- Function("autoRefresh") { (view: ExpoSmartrefreshlayoutView, delay: Int) in
98
- view.autoRefresh(delay: delay)
99
- }
100
-
101
- /**
102
- * 自动加载更多
103
- * @param view 视图实例
104
- * @param delay 延迟时间(毫秒)
105
- */
106
- Function("autoLoadMore") { (view: ExpoSmartrefreshlayoutView, delay: Int) in
107
- view.autoLoadMore(delay: delay)
108
- }
109
-
110
- /**
111
- * 设置是否没有更多数据
112
- * @param view 视图实例
113
- * @param noMore 是否没有更多数据
114
- */
115
- Function("setNoMoreData") { (view: ExpoSmartrefreshlayoutView, noMore: Bool) in
116
- view.setNoMoreData(noMore: noMore)
117
- }
118
- }
119
- }