├── .github
└── workflows
│ ├── build-docs.yml
│ ├── build.yml
│ └── release.yml
├── .gitignore
├── docs
├── index.html
└── readme.md
├── index.js
├── lib
├── android
│ ├── build.gradle
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── cn
│ │ └── qiuxiang
│ │ └── react
│ │ └── geolocation
│ │ ├── AMapGeolocationModule.java
│ │ └── AMapGeolocationPackage.java
└── ios
│ ├── AMapGeolocation.m
│ └── AMapGeolocation.xcodeproj
│ └── project.pbxproj
├── license
├── package.json
├── react-native-amap-geolocation.podspec
├── react-native.config.js
├── readme.md
├── src
├── amap-geolocation.ts
├── geolocation.ts
├── index.ts
└── types.ts
└── tsconfig.json
/.github/workflows/build-docs.yml:
--------------------------------------------------------------------------------
1 | name: build-docs
2 | on:
3 | push:
4 | branches: [main]
5 | jobs:
6 | build-docs:
7 | runs-on: ubuntu-latest
8 | permissions:
9 | contents: write
10 | steps:
11 | - uses: actions/checkout@v3
12 | - run: npm i typescript typedoc
13 | - run: npx typedoc --out docs/api --skipErrorChecking src
14 | - uses: JamesIves/github-pages-deploy-action@v4
15 | with:
16 | folder: docs
17 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: build
2 | on: [push]
3 | jobs:
4 | build:
5 | runs-on: ubuntu-latest
6 | steps:
7 | - uses: actions/checkout@v3
8 | - run: npm i
9 | - run: npx tsc
10 | - run: npm pack
11 | - run: npx react-native init example
12 | - run: cp index.js example/
13 | - run: npm i ../react-native-amap-geolocation-0.0.0.tgz
14 | working-directory: example
15 | - run: sed -i.backup -r 's/(enableSeparateBuildPerCPUArchitecture = )false/\1true/' build.gradle
16 | working-directory: example/android/app
17 | - run: ./gradlew assembleRelease
18 | working-directory: example/android
19 | - uses: actions/upload-artifact@v3
20 | with:
21 | name: example.apk
22 | path: example/android/app/build/outputs/apk/release/app-arm64-v8a-release.apk
23 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: release
2 | on:
3 | release:
4 | types: [published]
5 | jobs:
6 | release:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/checkout@v3
10 | - run: npm i
11 | - run: npx tsc
12 | - run: npm pack
13 | - run: npx react-native init example
14 | - run: cp index.js example/
15 | - run: npm i ../react-native-amap-geolocation-0.0.0.tgz
16 | working-directory: example
17 | - run: sed -i.backup -r 's/(enableSeparateBuildPerCPUArchitecture = )false/\1true/' build.gradle
18 | working-directory: example/android/app
19 | - run: ./gradlew assembleRelease
20 | working-directory: example/android
21 | - uses: bruceadams/get-release@v1.3.2
22 | id: release
23 | env:
24 | GITHUB_TOKEN: ${{ github.token }}
25 | - uses: svenstaro/upload-release-action@v2
26 | with:
27 | file: example/android/app/build/outputs/apk/release/app-arm64-v8a-release.apk
28 | asset_name: example.apk
29 | - uses: actions/setup-node@v3
30 | with:
31 | registry-url: "https://registry.npmjs.org"
32 | - run: npm version ${{ steps.release.outputs.tag_name }} --no-git-tag-version
33 | - run: npm publish
34 | env:
35 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
36 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode/
2 | .idea/
3 | .gradle/
4 | .settings/
5 | node_modules/
6 | build/
7 | xcuserdata/
8 | *.xcworkspace/
9 | Pods/
10 | lib/js/
11 | *.framework/
12 |
13 | .project
14 | .classpath
15 | *.iml
16 | local.properties
17 | Podfile.lock
18 | yarn.lock
19 | package-lock.json
20 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | react-native-amap-geolocation - React Native geolocation module for Android + iOS
6 |
7 |
8 |
9 |
10 |
11 |
12 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/docs/readme.md:
--------------------------------------------------------------------------------
1 | # 快速上手
2 |
3 | ## 获取高德 App Key
4 |
5 | 为了使用高德 SDK,你需要准备高德 App Key,获取方法参考高德地图 SDK 官方文档:
6 |
7 | - [获取 Android App Key](https://lbs.amap.com/api/android-location-sdk/guide/create-project/get-key)
8 | - [获取 iOS App Key](https://lbs.amap.com/api/ios-location-sdk/guide/create-project/get-key)
9 |
10 | ## 安装
11 |
12 | ```
13 | npm i react-native-amap-geolocation
14 | ```
15 |
16 | ## 基本用法
17 |
18 | ```javascript
19 | import { PermissionsAndroid } from "react-native";
20 | import { init, Geolocation } from "react-native-amap-geolocation";
21 |
22 | // 对于 Android 需要自行根据需要申请权限
23 | await PermissionsAndroid.requestMultiple([
24 | PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
25 | PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
26 | ]);
27 |
28 | // 使用自己申请的高德 App Key 进行初始化
29 | await init({
30 | ios: "9bd6c82e77583020a73ef1af59d0c759",
31 | android: "043b24fe18785f33c491705ffe5b6935",
32 | });
33 |
34 | Geolocation.getCurrentPosition(({ coords }) => {
35 | console.log(coords);
36 | });
37 | ```
38 |
39 | # 更多用法
40 |
41 | 该项目除了提供符合 Web 标准的 Geolocation API,同时为了最大程度的发挥高德定位 SDK 的功能,
42 | 会尽可能提供与原生 SDK 一致的接口封装。由于 iOS 和 Android SDK 提供的接口并不一致,
43 | 于是最终实现的接口大部分是并不通用的。这在接口文档或文档注释有注明,
44 | 比如 `@platform android` 表示该接口仅用于 Android。
45 |
46 | 以下是一些常用接口的用法说明以及示例代码,更多接口的具体用法请参考[接口文档]()。
47 |
48 | ## 直接使用原生接口
49 |
50 | ```javascript
51 | import { init, addLocationListener, start, stop } from "react-native-amap-geolocation";
52 |
53 | // 添加定位监听函数
54 | addLocationListener((location) => console.log(location));
55 |
56 | // 开始连续定位
57 | start();
58 |
59 | // 在不需要的时候停止定位
60 | stop();
61 | ```
62 |
63 | ## 逆地理编码
64 |
65 | Android 默认返回逆地理编码,而 iOS 需要手动设置。
66 |
67 | ```javascript
68 | import { setLocatingWithReGeocode, setNeedAddress } from "react-native-amap-geolocation";
69 |
70 | // android
71 | setNeedAddress(true);
72 |
73 | // ios
74 | setLocatingWithReGeocode(true);
75 | ```
76 |
77 | ## 定位回调频率限制
78 |
79 | ```javascript
80 | import { setInterval, setDistanceFilter } from "react-native-amap-geolocation";
81 |
82 | // android,5 秒请求一次定位
83 | setInterval(5000);
84 |
85 | // ios,设备移动超过 10 米才会更新位置信息
86 | setDistanceFilter(10);
87 | ```
88 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import {
3 | AppRegistry,
4 | Button,
5 | PermissionsAndroid,
6 | Platform,
7 | ScrollView,
8 | StyleSheet,
9 | Text,
10 | View,
11 | } from "react-native";
12 | import {
13 | Geolocation,
14 | init,
15 | setInterval,
16 | setLocatingWithReGeocode,
17 | setNeedAddress,
18 | } from "react-native-amap-geolocation";
19 |
20 | const style = StyleSheet.create({
21 | body: {
22 | padding: 16,
23 | paddingTop: Platform.OS === "ios" ? 48 : 16,
24 | },
25 | controls: {
26 | flexWrap: "wrap",
27 | alignItems: "flex-start",
28 | flexDirection: "row",
29 | marginBottom: 16,
30 | },
31 | button: {
32 | flexDirection: "column",
33 | marginRight: 8,
34 | marginBottom: 8,
35 | },
36 | result: {
37 | fontFamily: Platform.OS === "ios" ? "menlo" : "monospace",
38 | },
39 | });
40 |
41 | class App extends React.Component {
42 | state = { location: null };
43 |
44 | async componentDidMount() {
45 | if (Platform.OS === "android") {
46 | const result = await PermissionsAndroid.requestMultiple([
47 | PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
48 | PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
49 | ]);
50 | console.log(result);
51 | }
52 | await init({
53 | ios: "d258237d14f75e2e1bbb1654a22060cf",
54 | android: "c52c7169e6df23490e3114330098aaac",
55 | });
56 | }
57 |
58 | updateLocationState(location) {
59 | if (location) {
60 | this.setState({ location });
61 | console.log(location);
62 | }
63 | }
64 |
65 | getCurrentPosition = () => {
66 | Geolocation.getCurrentPosition(
67 | (position) => this.updateLocationState(position),
68 | (error) => this.updateLocationState(error)
69 | );
70 | };
71 |
72 | watchPosition = () => {
73 | if (!this.watchId) {
74 | this.watchId = Geolocation.watchPosition(
75 | (position) => this.updateLocationState(position),
76 | (error) => this.updateLocationState(error)
77 | );
78 | }
79 | };
80 |
81 | clearWatch = () => {
82 | if (this.watchId) {
83 | Geolocation.clearWatch(this.watchId);
84 | this.watchId = null;
85 | }
86 | this.setState({ location: null });
87 | };
88 |
89 | setInterval2000 = () => setInterval(2000);
90 | setInterval10000 = () => setInterval(10000);
91 | setNeedAddressTrue = () => setNeedAddress(true);
92 | setNeedAddressFalse = () => setNeedAddress(false);
93 | setLocatingWithReGeocodeTrue = () => setLocatingWithReGeocode(true);
94 | setLocatingWithReGeocodeFalse = () => setLocatingWithReGeocode(false);
95 |
96 | render() {
97 | const { location } = this.state;
98 | return (
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
127 |
128 |
129 |
133 |
134 |
135 | {`${JSON.stringify(location, null, 2)}
136 |
137 | `}
138 |
139 | );
140 | }
141 | }
142 |
143 | AppRegistry.registerComponent("example", () => App);
144 |
--------------------------------------------------------------------------------
/lib/android/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion rootProject.ext.compileSdkVersion
5 |
6 | defaultConfig {
7 | minSdkVersion rootProject.ext.minSdkVersion
8 | targetSdkVersion rootProject.ext.targetSdkVersion
9 | }
10 | }
11 |
12 | dependencies {
13 | compileOnly 'com.facebook.react:react-native:+'
14 | implementation 'com.amap.api:location:6.2.0'
15 | }
16 |
--------------------------------------------------------------------------------
/lib/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/lib/android/src/main/java/cn/qiuxiang/react/geolocation/AMapGeolocationModule.java:
--------------------------------------------------------------------------------
1 | package cn.qiuxiang.react.geolocation;
2 |
3 | import androidx.annotation.NonNull;
4 | import com.amap.api.location.AMapLocation;
5 | import com.amap.api.location.AMapLocationClient;
6 | import com.amap.api.location.AMapLocationClientOption;
7 | import com.amap.api.location.AMapLocationListener;
8 | import com.facebook.react.bridge.*;
9 | import com.facebook.react.modules.core.DeviceEventManagerModule;
10 |
11 | @SuppressWarnings("unused")
12 | public class AMapGeolocationModule extends ReactContextBaseJavaModule implements AMapLocationListener {
13 | private final ReactApplicationContext reactContext;
14 | private final AMapLocationClientOption option = new AMapLocationClientOption();
15 | private DeviceEventManagerModule.RCTDeviceEventEmitter eventEmitter;
16 | private AMapLocationClient client;
17 |
18 | AMapGeolocationModule(ReactApplicationContext reactContext) {
19 | super(reactContext);
20 | this.reactContext = reactContext;
21 | }
22 |
23 | @NonNull
24 | @Override
25 | public String getName() {
26 | return "AMapGeolocation";
27 | }
28 |
29 | @Override
30 | public void onLocationChanged(AMapLocation location) {
31 | if (location != null) {
32 | eventEmitter.emit("AMapGeolocation", toJSON(location));
33 | }
34 | }
35 |
36 | @ReactMethod
37 | public void init(String key, Promise promise) throws Exception {
38 | if (client != null) {
39 | client.onDestroy();
40 | }
41 |
42 | AMapLocationClient.setApiKey(key);
43 | AMapLocationClient.updatePrivacyShow(reactContext, true, true);
44 | AMapLocationClient.updatePrivacyAgree(reactContext, true);
45 | client = new AMapLocationClient(reactContext);
46 | client.setLocationListener(this);
47 | eventEmitter = reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
48 | promise.resolve(null);
49 | }
50 |
51 | @ReactMethod
52 | public void start() {
53 | client.startLocation();
54 | }
55 |
56 | @ReactMethod
57 | public void stop() {
58 | client.stopLocation();
59 | }
60 |
61 | @ReactMethod
62 | public void addListener(String name) {
63 | }
64 |
65 | @ReactMethod
66 | public void removeListeners(Integer count) {
67 | }
68 |
69 | @ReactMethod
70 | public void isStarted(Promise promise) {
71 | promise.resolve(client.isStarted());
72 | }
73 |
74 | @ReactMethod
75 | public void getLastKnownLocation(Promise promise) {
76 | promise.resolve(toJSON(client.getLastKnownLocation()));
77 | }
78 |
79 | @ReactMethod
80 | public void setOnceLocation(boolean value) {
81 | option.setOnceLocation(value);
82 | client.setLocationOption(option);
83 | }
84 |
85 | @ReactMethod
86 | public void setWifiScan(boolean value) {
87 | option.setWifiScan(value);
88 | client.setLocationOption(option);
89 | }
90 |
91 | @ReactMethod
92 | public void setInterval(int interval) {
93 | option.setInterval(interval);
94 | client.setLocationOption(option);
95 | }
96 |
97 | @ReactMethod
98 | public void setSensorEnable(boolean value) {
99 | option.setSensorEnable(value);
100 | client.setLocationOption(option);
101 | }
102 |
103 | @ReactMethod
104 | public void setOpenAlwaysScanWifi(boolean value) {
105 | AMapLocationClientOption.setOpenAlwaysScanWifi(value);
106 | client.setLocationOption(option);
107 | }
108 |
109 | @ReactMethod
110 | public void setNeedAddress(boolean value) {
111 | option.setNeedAddress(value);
112 | client.setLocationOption(option);
113 | }
114 |
115 | @ReactMethod
116 | public void setOnceLocationLatest(boolean value) {
117 | option.setOnceLocationLatest(value);
118 | client.setLocationOption(option);
119 | }
120 |
121 | @ReactMethod
122 | public void setMockEnable(boolean value) {
123 | option.setMockEnable(value);
124 | client.setLocationOption(option);
125 | }
126 |
127 | @ReactMethod
128 | public void setLocationCacheEnable(boolean value) {
129 | option.setLocationCacheEnable(value);
130 | client.setLocationOption(option);
131 | }
132 |
133 | @ReactMethod
134 | public void setGpsFirst(boolean value) {
135 | option.setGpsFirst(value);
136 | client.setLocationOption(option);
137 | }
138 |
139 | @ReactMethod
140 | public void setHttpTimeout(int value) {
141 | option.setHttpTimeOut(value);
142 | client.setLocationOption(option);
143 | }
144 |
145 | @ReactMethod
146 | public void setGpsFirstTimeout(int value) {
147 | option.setGpsFirstTimeout(value);
148 | client.setLocationOption(option);
149 | }
150 |
151 | @ReactMethod
152 | public void setLocationMode(String mode) {
153 | option.setLocationMode(AMapLocationClientOption.AMapLocationMode.valueOf(mode));
154 | client.setLocationOption(option);
155 | }
156 |
157 | @ReactMethod
158 | public void setLocationPurpose(String purpose) {
159 | option.setLocationPurpose(AMapLocationClientOption.AMapLocationPurpose.valueOf(purpose));
160 | client.setLocationOption(option);
161 | }
162 |
163 | @ReactMethod
164 | public void setGeoLanguage(String language) {
165 | option.setGeoLanguage(AMapLocationClientOption.GeoLanguage.valueOf(language));
166 | client.setLocationOption(option);
167 | }
168 |
169 | private ReadableMap toJSON(AMapLocation location) {
170 | if (location == null) {
171 | return null;
172 | }
173 | WritableMap map = Arguments.createMap();
174 | map.putInt("errorCode", location.getErrorCode());
175 | map.putString("errorInfo", location.getErrorInfo());
176 | map.putString("locationDetail", location.getLocationDetail());
177 | if (location.getErrorCode() == AMapLocation.LOCATION_SUCCESS) {
178 | map.putDouble("timestamp", location.getTime());
179 | map.putDouble("accuracy", location.getAccuracy());
180 | map.putDouble("latitude", location.getLatitude());
181 | map.putDouble("longitude", location.getLongitude());
182 | map.putDouble("altitude", location.getAltitude());
183 | map.putDouble("speed", location.getSpeed());
184 | map.putDouble("heading", location.getBearing());
185 | map.putInt("locationType", location.getLocationType());
186 | map.putString("coordinateType", location.getCoordType());
187 | map.putInt("gpsAccuracy", location.getGpsAccuracyStatus());
188 | map.putInt("trustedLevel", location.getTrustedLevel());
189 | if (!location.getAddress().isEmpty()) {
190 | map.putString("address", location.getAddress());
191 | map.putString("description", location.getDescription());
192 | map.putString("poiName", location.getPoiName());
193 | map.putString("country", location.getCountry());
194 | map.putString("province", location.getProvince());
195 | map.putString("city", location.getCity());
196 | map.putString("cityCode", location.getCityCode());
197 | map.putString("district", location.getDistrict());
198 | map.putString("street", location.getStreet());
199 | map.putString("streetNumber", location.getStreetNum());
200 | map.putString("adCode", location.getAdCode());
201 | }
202 | }
203 | return map;
204 | }
205 | }
206 |
--------------------------------------------------------------------------------
/lib/android/src/main/java/cn/qiuxiang/react/geolocation/AMapGeolocationPackage.java:
--------------------------------------------------------------------------------
1 | package cn.qiuxiang.react.geolocation;
2 |
3 | import androidx.annotation.NonNull;
4 | import com.facebook.react.ReactPackage;
5 | import com.facebook.react.bridge.NativeModule;
6 | import com.facebook.react.bridge.ReactApplicationContext;
7 | import com.facebook.react.uimanager.ViewManager;
8 |
9 | import java.util.Collections;
10 | import java.util.List;
11 |
12 | public class AMapGeolocationPackage implements ReactPackage {
13 | @NonNull
14 | @Override
15 | public List createViewManagers(@NonNull ReactApplicationContext reactContext) {
16 | return Collections.emptyList();
17 | }
18 |
19 | @NonNull
20 | @Override
21 | public List createNativeModules(@NonNull ReactApplicationContext reactContext) {
22 | return Collections.singletonList(new AMapGeolocationModule(reactContext));
23 | }
24 | }
--------------------------------------------------------------------------------
/lib/ios/AMapGeolocation.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 |
5 | @interface AMapGeolocation
6 | : RCTEventEmitter
7 | @end
8 |
9 | @implementation AMapGeolocation {
10 | AMapLocationManager *_manager;
11 | }
12 |
13 | RCT_EXPORT_MODULE()
14 |
15 | RCT_REMAP_METHOD(init, initWithKey
16 | : (NSString *)key
17 | : (RCTPromiseResolveBlock)resolve
18 | : (RCTPromiseRejectBlock)reject) {
19 | dispatch_async(dispatch_get_main_queue(), ^{
20 | [AMapServices sharedServices].apiKey = key;
21 | [AMapLocationManager updatePrivacyAgree:AMapPrivacyAgreeStatusDidAgree];
22 | [AMapLocationManager updatePrivacyShow:AMapPrivacyShowStatusDidShow privacyInfo:AMapPrivacyInfoStatusDidContain];
23 | if (!(self->_manager)) {
24 | self->_manager = [[AMapLocationManager alloc] init];
25 | self->_manager.delegate = self;
26 | }
27 | resolve(nil);
28 | });
29 | }
30 |
31 | RCT_EXPORT_METHOD(start) { [_manager startUpdatingLocation]; }
32 |
33 | RCT_EXPORT_METHOD(stop) { [_manager stopUpdatingLocation]; }
34 |
35 | RCT_EXPORT_METHOD(setLocatingWithReGeocode : (BOOL)value) {
36 | _manager.locatingWithReGeocode = value;
37 | }
38 |
39 | RCT_EXPORT_METHOD(setAllowsBackgroundLocationUpdates : (BOOL)value) {
40 | _manager.allowsBackgroundLocationUpdates = value;
41 | }
42 |
43 | RCT_EXPORT_METHOD(setPausesLocationUpdatesAutomatically : (BOOL)value) {
44 | _manager.pausesLocationUpdatesAutomatically = value;
45 | }
46 |
47 | RCT_EXPORT_METHOD(setDesiredAccuracy : (int)value) {
48 | _manager.desiredAccuracy = value;
49 | }
50 |
51 | RCT_EXPORT_METHOD(setDistanceFilter : (int)value) {
52 | _manager.distanceFilter = value;
53 | }
54 |
55 | RCT_EXPORT_METHOD(setGeoLanguage : (int)value) {
56 | _manager.reGeocodeLanguage = (AMapLocationReGeocodeLanguage)value;
57 | }
58 |
59 | RCT_EXPORT_METHOD(setReGeocodeTimeout : (int)value) {
60 | _manager.reGeocodeTimeout = value;
61 | }
62 |
63 | RCT_EXPORT_METHOD(setLocationTimeout : (int)value) {
64 | _manager.locationTimeout = value;
65 | }
66 |
67 | - (id)json:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode {
68 | if (reGeocode) {
69 | return @{
70 | @"errorCode" : @(0),
71 | @"accuracy" : @(location.horizontalAccuracy),
72 | @"latitude" : @(location.coordinate.latitude),
73 | @"longitude" : @(location.coordinate.longitude),
74 | @"altitude" : @(location.altitude),
75 | @"speed" : @(location.speed),
76 | @"heading" : @(location.course),
77 | @"timestamp" : @(location.timestamp.timeIntervalSince1970 * 1000),
78 | @"address" : reGeocode.formattedAddress ? reGeocode.formattedAddress
79 | : @"",
80 | @"poiName" : reGeocode.POIName ? reGeocode.POIName : @"",
81 | @"country" : reGeocode.country ? reGeocode.country : @"",
82 | @"province" : reGeocode.province ? reGeocode.province : @"",
83 | @"city" : reGeocode.city ? reGeocode.city : @"",
84 | @"cityCode" : reGeocode.citycode ? reGeocode.citycode : @"",
85 | @"district" : reGeocode.district ? reGeocode.district : @"",
86 | @"street" : reGeocode.street ? reGeocode.street : @"",
87 | @"streetNumber" : reGeocode.number ? reGeocode.number : @"",
88 | @"adCode" : reGeocode.adcode ? reGeocode.adcode : @"",
89 | };
90 | } else {
91 | return @{
92 | @"errorCode" : @(0),
93 | @"accuracy" : @(location.horizontalAccuracy),
94 | @"latitude" : @(location.coordinate.latitude),
95 | @"longitude" : @(location.coordinate.longitude),
96 | @"altitude" : @(location.altitude),
97 | @"speed" : @(location.speed),
98 | @"direction" : @(location.course),
99 | @"timestamp" : @(location.timestamp.timeIntervalSince1970 * 1000),
100 | };
101 | }
102 | }
103 |
104 | - (void)amapLocationManager:(AMapLocationManager *)manager
105 | didUpdateLocation:(CLLocation *)location
106 | reGeocode:(AMapLocationReGeocode *)reGeocode {
107 | id json = [self json:location reGeocode:reGeocode];
108 | [self sendEventWithName:@"AMapGeolocation" body:json];
109 | }
110 |
111 | - (void)amapLocationManager:(AMapLocationManager *)manager
112 | didFailWithError:(NSError *)error {
113 | [self sendEventWithName:@"AMapGeolocation"
114 | body:@{
115 | @"errorCode" : @(error.code),
116 | @"errorInfo" : error.localizedDescription,
117 | }];
118 | }
119 |
120 | - (void)amapLocationManager:(AMapLocationManager *)manager
121 | doRequireLocationAuth:(CLLocationManager *)locationManager {
122 | [locationManager requestAlwaysAuthorization];
123 | }
124 |
125 | - (NSArray *)supportedEvents {
126 | return @[ @"AMapGeolocation" ];
127 | }
128 |
129 | @end
130 |
--------------------------------------------------------------------------------
/lib/ios/AMapGeolocation.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 3965AAF122677BF20024ACCC /* AMapGeolocation.m in Sources */ = {isa = PBXBuildFile; fileRef = 3965AAF022677BF20024ACCC /* AMapGeolocation.m */; };
11 | /* End PBXBuildFile section */
12 |
13 | /* Begin PBXFileReference section */
14 | 3965AAF022677BF20024ACCC /* AMapGeolocation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMapGeolocation.m; sourceTree = ""; };
15 | 832C81801AAF6DEF007FA2F7 /* libAMapGeolocation.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libAMapGeolocation.a; sourceTree = BUILT_PRODUCTS_DIR; };
16 | /* End PBXFileReference section */
17 |
18 | /* Begin PBXGroup section */
19 | 832C81771AAF6DEF007FA2F7 = {
20 | isa = PBXGroup;
21 | children = (
22 | 3965AAF022677BF20024ACCC /* AMapGeolocation.m */,
23 | 832C81811AAF6DEF007FA2F7 /* Products */,
24 | );
25 | indentWidth = 2;
26 | sourceTree = "";
27 | tabWidth = 2;
28 | usesTabs = 0;
29 | };
30 | 832C81811AAF6DEF007FA2F7 /* Products */ = {
31 | isa = PBXGroup;
32 | children = (
33 | 832C81801AAF6DEF007FA2F7 /* libAMapGeolocation.a */,
34 | );
35 | name = Products;
36 | sourceTree = "";
37 | };
38 | /* End PBXGroup section */
39 |
40 | /* Begin PBXNativeTarget section */
41 | 832C817F1AAF6DEF007FA2F7 /* AMapGeolocation */ = {
42 | isa = PBXNativeTarget;
43 | buildConfigurationList = 832C81941AAF6DF0007FA2F7 /* Build configuration list for PBXNativeTarget "AMapGeolocation" */;
44 | buildPhases = (
45 | 832C817C1AAF6DEF007FA2F7 /* Sources */,
46 | );
47 | buildRules = (
48 | );
49 | dependencies = (
50 | );
51 | name = AMapGeolocation;
52 | productName = RCTVibration;
53 | productReference = 832C81801AAF6DEF007FA2F7 /* libAMapGeolocation.a */;
54 | productType = "com.apple.product-type.library.static";
55 | };
56 | /* End PBXNativeTarget section */
57 |
58 | /* Begin PBXProject section */
59 | 832C81781AAF6DEF007FA2F7 /* Project object */ = {
60 | isa = PBXProject;
61 | attributes = {
62 | LastUpgradeCheck = 0940;
63 | ORGANIZATIONNAME = Facebook;
64 | TargetAttributes = {
65 | 832C817F1AAF6DEF007FA2F7 = {
66 | CreatedOnToolsVersion = 6.2;
67 | };
68 | };
69 | };
70 | buildConfigurationList = 832C817B1AAF6DEF007FA2F7 /* Build configuration list for PBXProject "AMapGeolocation" */;
71 | compatibilityVersion = "Xcode 3.2";
72 | developmentRegion = English;
73 | hasScannedForEncodings = 0;
74 | knownRegions = (
75 | en,
76 | );
77 | mainGroup = 832C81771AAF6DEF007FA2F7;
78 | productRefGroup = 832C81811AAF6DEF007FA2F7 /* Products */;
79 | projectDirPath = "";
80 | projectRoot = "";
81 | targets = (
82 | 832C817F1AAF6DEF007FA2F7 /* AMapGeolocation */,
83 | );
84 | };
85 | /* End PBXProject section */
86 |
87 | /* Begin PBXSourcesBuildPhase section */
88 | 832C817C1AAF6DEF007FA2F7 /* Sources */ = {
89 | isa = PBXSourcesBuildPhase;
90 | buildActionMask = 2147483647;
91 | files = (
92 | 3965AAF122677BF20024ACCC /* AMapGeolocation.m in Sources */,
93 | );
94 | runOnlyForDeploymentPostprocessing = 0;
95 | };
96 | /* End PBXSourcesBuildPhase section */
97 |
98 | /* Begin XCBuildConfiguration section */
99 | 832C81921AAF6DF0007FA2F7 /* Debug */ = {
100 | isa = XCBuildConfiguration;
101 | buildSettings = {
102 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
103 | CLANG_CXX_LIBRARY = "libc++";
104 | CLANG_ENABLE_MODULES = YES;
105 | CLANG_ENABLE_OBJC_ARC = YES;
106 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
107 | CLANG_WARN_BOOL_CONVERSION = YES;
108 | CLANG_WARN_COMMA = YES;
109 | CLANG_WARN_CONSTANT_CONVERSION = YES;
110 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
111 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
112 | CLANG_WARN_EMPTY_BODY = YES;
113 | CLANG_WARN_ENUM_CONVERSION = YES;
114 | CLANG_WARN_INFINITE_RECURSION = YES;
115 | CLANG_WARN_INT_CONVERSION = YES;
116 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
117 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
118 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
119 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
120 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
121 | CLANG_WARN_STRICT_PROTOTYPES = YES;
122 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
123 | CLANG_WARN_UNREACHABLE_CODE = YES;
124 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
125 | COPY_PHASE_STRIP = NO;
126 | ENABLE_STRICT_OBJC_MSGSEND = YES;
127 | ENABLE_TESTABILITY = YES;
128 | GCC_C_LANGUAGE_STANDARD = gnu99;
129 | GCC_DYNAMIC_NO_PIC = NO;
130 | GCC_NO_COMMON_BLOCKS = YES;
131 | GCC_OPTIMIZATION_LEVEL = 0;
132 | GCC_PREPROCESSOR_DEFINITIONS = (
133 | "DEBUG=1",
134 | "$(inherited)",
135 | );
136 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
137 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
138 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
139 | GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
140 | GCC_WARN_SHADOW = YES;
141 | GCC_WARN_UNDECLARED_SELECTOR = YES;
142 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
143 | GCC_WARN_UNUSED_FUNCTION = YES;
144 | GCC_WARN_UNUSED_VARIABLE = YES;
145 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
146 | MTL_ENABLE_DEBUG_INFO = YES;
147 | ONLY_ACTIVE_ARCH = YES;
148 | SDKROOT = iphoneos;
149 | SKIP_INSTALL = YES;
150 | WARNING_CFLAGS = (
151 | "-Werror",
152 | "-Wall",
153 | );
154 | };
155 | name = Debug;
156 | };
157 | 832C81931AAF6DF0007FA2F7 /* Release */ = {
158 | isa = XCBuildConfiguration;
159 | buildSettings = {
160 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
161 | CLANG_CXX_LIBRARY = "libc++";
162 | CLANG_ENABLE_MODULES = YES;
163 | CLANG_ENABLE_OBJC_ARC = YES;
164 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
165 | CLANG_WARN_BOOL_CONVERSION = YES;
166 | CLANG_WARN_COMMA = YES;
167 | CLANG_WARN_CONSTANT_CONVERSION = YES;
168 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
169 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
170 | CLANG_WARN_EMPTY_BODY = YES;
171 | CLANG_WARN_ENUM_CONVERSION = YES;
172 | CLANG_WARN_INFINITE_RECURSION = YES;
173 | CLANG_WARN_INT_CONVERSION = YES;
174 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
175 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
176 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
177 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
178 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
179 | CLANG_WARN_STRICT_PROTOTYPES = YES;
180 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
181 | CLANG_WARN_UNREACHABLE_CODE = YES;
182 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
183 | COPY_PHASE_STRIP = NO;
184 | ENABLE_NS_ASSERTIONS = NO;
185 | ENABLE_STRICT_OBJC_MSGSEND = YES;
186 | GCC_C_LANGUAGE_STANDARD = gnu99;
187 | GCC_NO_COMMON_BLOCKS = YES;
188 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
189 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
190 | GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
191 | GCC_WARN_SHADOW = YES;
192 | GCC_WARN_UNDECLARED_SELECTOR = YES;
193 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
194 | GCC_WARN_UNUSED_FUNCTION = YES;
195 | GCC_WARN_UNUSED_VARIABLE = YES;
196 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
197 | MTL_ENABLE_DEBUG_INFO = NO;
198 | SDKROOT = iphoneos;
199 | SKIP_INSTALL = YES;
200 | VALIDATE_PRODUCT = YES;
201 | WARNING_CFLAGS = (
202 | "-Werror",
203 | "-Wall",
204 | );
205 | };
206 | name = Release;
207 | };
208 | 832C81951AAF6DF0007FA2F7 /* Debug */ = {
209 | isa = XCBuildConfiguration;
210 | buildSettings = {
211 | CLANG_STATIC_ANALYZER_MODE = deep;
212 | FRAMEWORK_SEARCH_PATHS = (
213 | "$(PROJECT_DIR)/../../../../ios",
214 | "$(PROJECT_DIR)/../../ios",
215 | );
216 | OTHER_LDFLAGS = "-ObjC";
217 | PRODUCT_NAME = "$(TARGET_NAME)";
218 | RUN_CLANG_STATIC_ANALYZER = YES;
219 | };
220 | name = Debug;
221 | };
222 | 832C81961AAF6DF0007FA2F7 /* Release */ = {
223 | isa = XCBuildConfiguration;
224 | buildSettings = {
225 | CLANG_STATIC_ANALYZER_MODE = deep;
226 | FRAMEWORK_SEARCH_PATHS = (
227 | "$(PROJECT_DIR)/../../../../ios",
228 | "$(PROJECT_DIR)/../../ios",
229 | );
230 | OTHER_LDFLAGS = "-ObjC";
231 | PRODUCT_NAME = "$(TARGET_NAME)";
232 | };
233 | name = Release;
234 | };
235 | /* End XCBuildConfiguration section */
236 |
237 | /* Begin XCConfigurationList section */
238 | 832C817B1AAF6DEF007FA2F7 /* Build configuration list for PBXProject "AMapGeolocation" */ = {
239 | isa = XCConfigurationList;
240 | buildConfigurations = (
241 | 832C81921AAF6DF0007FA2F7 /* Debug */,
242 | 832C81931AAF6DF0007FA2F7 /* Release */,
243 | );
244 | defaultConfigurationIsVisible = 0;
245 | defaultConfigurationName = Release;
246 | };
247 | 832C81941AAF6DF0007FA2F7 /* Build configuration list for PBXNativeTarget "AMapGeolocation" */ = {
248 | isa = XCConfigurationList;
249 | buildConfigurations = (
250 | 832C81951AAF6DF0007FA2F7 /* Debug */,
251 | 832C81961AAF6DF0007FA2F7 /* Release */,
252 | );
253 | defaultConfigurationIsVisible = 0;
254 | defaultConfigurationName = Release;
255 | };
256 | /* End XCConfigurationList section */
257 | };
258 | rootObject = 832C81781AAF6DEF007FA2F7 /* Project object */;
259 | }
260 |
--------------------------------------------------------------------------------
/license:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 7c00
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-amap-geolocation",
3 | "description": "React Native geolocation module for Android + iOS",
4 | "keywords": [
5 | "react-native",
6 | "amap",
7 | "location",
8 | "geolocation"
9 | ],
10 | "version": "0.0.0",
11 | "author": "7c00 ",
12 | "repository": {
13 | "type": "git",
14 | "url": "https://github.com/qiuxiang/react-native-amap-geolocation"
15 | },
16 | "license": "MIT",
17 | "files": [
18 | "src",
19 | "react-native.config.js",
20 | "react-native-amap-geolocation.podspec",
21 | "lib/js",
22 | "lib/ios",
23 | "lib/android/src",
24 | "lib/android/build.gradle"
25 | ],
26 | "main": "lib/js",
27 | "scripts": {
28 | "build-docs": "npx typedoc --out docs/api --excludeNotExported --module commonjs --mode file src",
29 | "start": "react-native start",
30 | "reload": "adb reverse tcp:8081 tcp:8081 && adb shell input text rr",
31 | "android": "react-native run-android",
32 | "release-android": "react-native run-android --variant=release",
33 | "ios": "react-native run-ios"
34 | },
35 | "devDependencies": {
36 | "@types/react-native": "^0.71.2",
37 | "react": "^18.2.0",
38 | "react-native": "^0.71.2",
39 | "typescript": "^5.0.4"
40 | },
41 | "prettier": {
42 | "printWidth": 100
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/react-native-amap-geolocation.podspec:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4 |
5 | Pod::Spec.new do |s|
6 | s.name = package['name']
7 | s.version = package['version']
8 | s.summary = package['description']
9 | s.authors = { '7c00' => 'i@7c00.cc' }
10 | s.homepage = package['repository']['url']
11 | s.license = { :type => package['license']}
12 | s.platform = :ios, "8.0"
13 | s.source = { :git => package['repository']['url'] }
14 | s.source_files = 'lib/ios/**/*.{h,m}'
15 |
16 | s.dependency 'React'
17 | s.dependency 'AMapLocation', "~> 2.9.0"
18 | end
19 |
--------------------------------------------------------------------------------
/react-native.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | dependency: { platforms: { android: { sourceDir: "lib/android" } } },
3 | dependencies: {
4 | "react-native-amap-geolocation": {
5 | root: __dirname,
6 | platforms: {
7 | android: {
8 | sourceDir: __dirname + "/lib/android",
9 | packageImportPath: "import cn.qiuxiang.react.geolocation.AMapGeolocationPackage;",
10 | packageInstance: "new AMapGeolocationPackage()",
11 | },
12 | },
13 | },
14 | },
15 | };
16 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # react-native-amap-geolocation [![][version-badge]][npm] [![][build-badge]][build]
2 |
3 | **注意:该项目目前只维护,不加新功能。**
4 |
5 | React Native 高德地图定位模块,支持 Android + iOS,提供尽可能完善的原生接口,
6 | 同时提供符合 Web 标准的 Geolocation API。
7 |
8 |
9 |
10 | ## 用法
11 |
12 | ```javascript
13 | import { PermissionsAndroid } from "react-native";
14 | import { init, Geolocation } from "react-native-amap-geolocation";
15 |
16 | await PermissionsAndroid.requestMultiple([
17 | PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
18 | PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
19 | ]);
20 |
21 | await init({
22 | ios: "9bd6c82e77583020a73ef1af59d0c759",
23 | android: "043b24fe18785f33c491705ffe5b6935",
24 | });
25 |
26 | Geolocation.getCurrentPosition(({ coords }) => {
27 | console.log(coords);
28 | });
29 | ```
30 |
31 | ## 文档
32 |
33 | - [使用指南](https://qiuxiang.github.io/react-native-amap-geolocation)
34 | - [接口文档](https://qiuxiang.github.io/react-native-amap-geolocation/api/)
35 |
36 | [npm]: https://www.npmjs.com/package/react-native-amap-geolocation
37 | [version-badge]: https://badge.fury.io/js/react-native-amap-geolocation.svg
38 | [build-badge]: https://github.com/qiuxiang/react-native-amap-geolocation/actions/workflows/build.yml/badge.svg
39 | [build]: https://github.com/qiuxiang/react-native-amap-geolocation/actions/workflows/build.yml
40 |
--------------------------------------------------------------------------------
/src/amap-geolocation.ts:
--------------------------------------------------------------------------------
1 | import { NativeModules, NativeEventEmitter, Platform } from "react-native";
2 | import { Location, ReGeocode, AppKey, LocationMode, LocationPurpose, GeoLanguage } from "./types";
3 |
4 | const AMapGeolocation = NativeModules.AMapGeolocation;
5 | const eventEmitter = new NativeEventEmitter(AMapGeolocation);
6 |
7 | /**
8 | * 初始化 SDK
9 | *
10 | * @param key 高德开放平台应用 Key
11 | */
12 | export function init(key: AppKey): Promise {
13 | return AMapGeolocation.init(Platform.select(key));
14 | }
15 |
16 | /**
17 | * 添加定位监听函数
18 | *
19 | * @param listener
20 | */
21 | export function addLocationListener(listener: (location: Location & ReGeocode) => void) {
22 | return eventEmitter.addListener("AMapGeolocation", listener);
23 | }
24 |
25 | /**
26 | * 开始持续定位
27 | */
28 | export function start() {
29 | AMapGeolocation.start();
30 | }
31 |
32 | /**
33 | * 停止持续定位
34 | */
35 | export function stop() {
36 | AMapGeolocation.stop();
37 | }
38 |
39 | /**
40 | * 获取当前是否正在定位的状态
41 | *
42 | * @platform android
43 | */
44 | export function isStarted(): boolean {
45 | return AMapGeolocation.isStarted();
46 | }
47 |
48 | /**
49 | * 设置发起定位请求的时间间隔(毫秒),默认 2000,最小值为 1000
50 | *
51 | * @default 2000
52 | * @platform android
53 | */
54 | export function setInterval(interval: number) {
55 | if (Platform.OS === "android") {
56 | AMapGeolocation.setInterval(interval);
57 | }
58 | }
59 |
60 | /**
61 | * 设置是否单次定位
62 | *
63 | * @default false
64 | * @platform android
65 | */
66 | export function setOnceLocation(isOnceLocation: boolean) {
67 | if (Platform.OS === "android") {
68 | AMapGeolocation.setOnceLocation(isOnceLocation);
69 | }
70 | }
71 |
72 | /**
73 | * 设置是否允许调用 WiFi 刷新
74 | *
75 | * 当设置为 `false` 时会停止主动调用 wifi 刷新,将会极大程度影响定位精度,
76 | * 但可以有效的降低定位耗电。
77 | *
78 | * @default true
79 | * @platform android
80 | */
81 | export function setWifiScan(isWifiScan: boolean) {
82 | if (Platform.OS === "android") {
83 | AMapGeolocation.setWifiScan(isWifiScan);
84 | }
85 | }
86 |
87 | /**
88 | * 设置是否使用设备传感器
89 | *
90 | * @default false
91 | * @platform android
92 | */
93 | export function setSensorEnable(enable: boolean) {
94 | if (Platform.OS === "android") {
95 | AMapGeolocation.setSensorEnable(enable);
96 | }
97 | }
98 |
99 | /**
100 | * 设置是否开启wifi始终扫描
101 | *
102 | * 只有设置了 `android.permission.WRITE_SECURE_SETTINGS` 权限后才会开启。
103 | * 开启后,即使关闭 wifi 开关的情况下也会扫描 wifi。
104 | * 此方法为静态方法,设置一次后其他定位 client 也会生效。
105 | *
106 | * @default true
107 | * @platform android
108 | */
109 | export function setOpenAlwaysScanWifi(isOpen: boolean) {
110 | if (Platform.OS === "android") {
111 | AMapGeolocation.setOpenAlwaysScanWifi(isOpen);
112 | }
113 | }
114 |
115 | /**
116 | * 设置定位是否等待 WiFi 列表刷新
117 | *
118 | * 定位精度会更高,但是定位速度会变慢 1-3 秒,
119 | * 当设置为 `true` 时,连续定位会自动变为单次定位。
120 | *
121 | * @default false
122 | * @platform android
123 | */
124 | export function setOnceLocationLatest(isOnceLocationLatest: boolean) {
125 | if (Platform.OS === "android") {
126 | AMapGeolocation.setOnceLocationLatest(isOnceLocationLatest);
127 | }
128 | }
129 |
130 | /**
131 | * 设置是否返回地址信息,默认返回地址信息
132 | *
133 | * GPS 定位时也可以返回地址信息,但需要网络通畅,第一次有可能没有地址信息返回。
134 | *
135 | * @default true
136 | * @platform android
137 | */
138 | export function setNeedAddress(isNeedAddress: boolean) {
139 | if (Platform.OS === "android") {
140 | AMapGeolocation.setNeedAddress(isNeedAddress);
141 | }
142 | }
143 |
144 | /**
145 | * 设置是否允许模拟位置
146 | *
147 | * @default true
148 | * @platform android
149 | */
150 | export function setMockEnable(enable: boolean) {
151 | if (Platform.OS === "android") {
152 | AMapGeolocation.setMockEnable(enable);
153 | }
154 | }
155 |
156 | /**
157 | * 设置是否使用缓存策略
158 | *
159 | * @default true
160 | * @platform android
161 | */
162 | export function setLocationCacheEnable(enable: boolean) {
163 | if (Platform.OS === "android") {
164 | AMapGeolocation.setLocationCacheEnable(enable);
165 | }
166 | }
167 |
168 | /**
169 | * 设置联网超时时间(毫秒)
170 | *
171 | * @default 30000
172 | * @platform android
173 | */
174 | export function setHttpTimeout(timeout: number) {
175 | if (Platform.OS === "android") {
176 | AMapGeolocation.setHttpTimeout(timeout);
177 | }
178 | }
179 |
180 | /**
181 | * 设置优先返回卫星定位信息时等待卫星定位结果的超时时间(毫秒)
182 | *
183 | * 只有在 `setGpsFirst(true)` 时才有效。
184 | *
185 | * @platform android
186 | */
187 | export function setGpsFirstTimeout(timeout: number) {
188 | if (Platform.OS === "android") {
189 | AMapGeolocation.setGpsFirstTimeout(timeout);
190 | }
191 | }
192 |
193 | /**
194 | * 设置首次定位是否等待卫星定位结果
195 | *
196 | * 只有在单次定位高精度定位模式下有效,设置为 `true` 时,会等待卫星定位结果返回,
197 | * 最多等待 30 秒,若 30 秒后仍无卫星定位结果返回,返回网络定位结果。
198 | * 等待卫星定位结果返回的时间可以通过 [[setGpsFirstTimeout]] 进行设置。
199 | *
200 | * @default false
201 | * @platform android
202 | */
203 | export function setGpsFirst(isGpsFirst: boolean) {
204 | if (Platform.OS === "android") {
205 | AMapGeolocation.setGpsFirst(isGpsFirst);
206 | }
207 | }
208 |
209 | /**
210 | * 设置定位模式
211 | *
212 | * @platform android
213 | */
214 | export function setLocationMode(mode: LocationMode) {
215 | if (Platform.OS === "android") {
216 | AMapGeolocation.setLocationMode(mode);
217 | }
218 | }
219 |
220 | /**
221 | * 设置定位场景
222 | *
223 | * 根据场景快速修改 option,不支持动态改变,修改后需要调用 [[start]] 使其生效,当不需要场景时,可以设置为 `null`。
224 | *
225 | * 注意:不建议设置场景和自定义 option 混合使用。设置场景后,如果已经开始定位了,建议调用一次 [[stop]],然后主动调用一次 [[start]]
226 | * 以保证 option 正确生效。当主动设置的 option 和场景中的 option 有冲突时,以后设置的为准,比如:签到场景中默认的为单次定位,
227 | * 当主动设置 option 为连续定位时,如果先设置的场景,后改变的 option,这时如果不调用 [[start]] 不会变为连续定位,
228 | * 如果调用了 [[start]] 则会变为连续定位,如果先改变 option,后设置场景为签到场景,则会变为单次定位。
229 | *
230 | * @platform android
231 | */
232 | export function setLocationPurpose(purpose: LocationPurpose) {
233 | if (Platform.OS === "android") {
234 | AMapGeolocation.setLocationPurpose(purpose);
235 | }
236 | }
237 |
238 | /**
239 | * 设置逆地理信息的语言,目前支持中文和英文
240 | *
241 | * @default GeoLanguage.DEFAULT
242 | */
243 | export function setGeoLanguage(language: GeoLanguage) {
244 | AMapGeolocation.setGeoLanguage(language);
245 | }
246 |
247 | /**
248 | * 设定定位的最小更新距离(米)
249 | *
250 | * 默认为 `kCLDistanceFilterNone`,表示只要检测到设备位置发生变化就会更新位置信息。
251 | *
252 | * @platform ios
253 | */
254 | export function setDistanceFilter(distance: number) {
255 | if (Platform.OS === "ios") {
256 | AMapGeolocation.setDistanceFilter(distance);
257 | }
258 | }
259 |
260 | /**
261 | * 设定期望的定位精度(米)
262 | *
263 | * 默认为 `kCLLocationAccuracyBest`。
264 | * 定位服务会尽可能去获取满足 `desiredAccuracy` 的定位结果,但不保证一定会得到满足期望的结果。
265 | *
266 | * 注意:设置为 `kCLLocationAccuracyBest` 或 `kCLLocationAccuracyBestForNavigation` 时,
267 | * 单次定位会在达到 `locationTimeout` 设定的时间后,将时间内获取到的最高精度的定位结果返回。
268 | *
269 | * @platform ios
270 | */
271 | export function setDesiredAccuracy(desiredAccuracy: number) {
272 | if (Platform.OS === "ios") {
273 | AMapGeolocation.setDesiredAccuracy(desiredAccuracy);
274 | }
275 | }
276 |
277 | /**
278 | * 指定定位是否会被系统自动暂停
279 | *
280 | * @default false
281 | * @platform ios
282 | */
283 | export function setPausesLocationUpdatesAutomatically(isPause: boolean) {
284 | if (Platform.OS === "ios") {
285 | AMapGeolocation.setPausesLocationUpdatesAutomatically(isPause);
286 | }
287 | }
288 |
289 | /**
290 | * 是否允许后台定位
291 | *
292 | * 只在iOS 9.0 及之后起作用。
293 | * 设置为YES的时候必须保证 `Background Modes` 中的 `Location updates` 处于选中状态,否则会抛出异常。
294 | * 由于iOS系统限制,需要在定位未开始之前或定位停止之后,修改该属性的值才会有效果。
295 | *
296 | * @default false
297 | * @platform ios
298 | */
299 | export function setAllowsBackgroundLocationUpdates(isAllow: boolean) {
300 | if (Platform.OS === "ios") {
301 | AMapGeolocation.setAllowsBackgroundLocationUpdates(isAllow);
302 | }
303 | }
304 |
305 | /**
306 | * 指定单次定位超时时间(秒)
307 | *
308 | * 最小值是 2s。注意在单次定位请求前设置。
309 | *
310 | * 注意: 单次定位超时时间从确定了定位权限(非 `kCLAuthorizationStatusNotDetermined` 状态)后开始计算。
311 | *
312 | * @default 10
313 | * @platform ios
314 | */
315 | export function setLocationTimeout(timeout: number) {
316 | if (Platform.OS === "ios") {
317 | AMapGeolocation.setLocationTimeout(timeout);
318 | }
319 | }
320 |
321 | /**
322 | * 指定单次定位逆地理超时时间(秒)
323 | *
324 | * 最小值是 2s。注意在单次定位请求前设置。
325 | *
326 | * @default 5
327 | * @platform ios
328 | */
329 | export function setReGeocodeTimeout(timeout: number) {
330 | if (Platform.OS === "ios") {
331 | AMapGeolocation.setReGeocodeTimeout(timeout);
332 | }
333 | }
334 |
335 | interface Options {
336 | locatingWithReGeocode?: boolean;
337 | }
338 |
339 | export const _options: Options = {};
340 |
341 | /**
342 | * 连续定位是否返回逆地理编码
343 | *
344 | * @default false
345 | * @platform ios
346 | */
347 | export function setLocatingWithReGeocode(withReGeocode: boolean) {
348 | _options.locatingWithReGeocode = withReGeocode;
349 | if (Platform.OS === "ios") {
350 | AMapGeolocation.setLocatingWithReGeocode(withReGeocode);
351 | }
352 | }
353 |
--------------------------------------------------------------------------------
/src/geolocation.ts:
--------------------------------------------------------------------------------
1 | import { EmitterSubscription } from "react-native";
2 | import { addLocationListener, start, stop, _options } from "./amap-geolocation";
3 | import { Location } from "./types";
4 |
5 | /**
6 | * 坐标信息
7 | *
8 | * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Coordinates
9 | */
10 | export interface Coordinates {
11 | latitude: number;
12 | longitude: number;
13 | altitude: number;
14 | accuracy: number;
15 | altitudeAccuracy: number;
16 | heading: number;
17 | speed: number;
18 | }
19 |
20 | /**
21 | * 定位信息
22 | *
23 | * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Position
24 | */
25 | export interface Position {
26 | coords: Coordinates;
27 | timestamp: number;
28 | location: Location;
29 | }
30 |
31 | /**
32 | * 定位错误信息
33 | *
34 | * @see https://developer.mozilla.org/zh-CN/docs/Web/API/PositionError
35 | */
36 | export class PositionError {
37 | static PERMISSION_DENIED: 1;
38 | static POSITION_UNAVAILABLE: 2;
39 | static TIMEOUT: 3;
40 |
41 | code: number;
42 | message: string;
43 | location: Location;
44 |
45 | constructor(code: number, message: string, location: Location) {
46 | this.code = code;
47 | this.message = message;
48 | this.location = location;
49 | }
50 | }
51 |
52 | /**
53 | * 定位选项
54 | *
55 | * @see https://developer.mozilla.org/zh-CN/docs/Web/API/PositionOptions
56 | */
57 | export interface PositionOptions {
58 | timeout?: number;
59 | maximumAge?: number;
60 | enableHighAccuracy?: boolean;
61 |
62 | /**
63 | * @see [[setDistanceFilter]]
64 | */
65 | distanceFilter?: number;
66 | }
67 |
68 | let watchId = 0;
69 | const watchMap: { [watchId: number]: EmitterSubscription } = {};
70 |
71 | /**
72 | * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Geolocation
73 | */
74 | export default class Geolocation {
75 | /**
76 | * 获取当前位置信息
77 | *
78 | * 注意:使用该方法会停止持续定位
79 | *
80 | * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Geolocation/getCurrentPosition
81 | */
82 | static getCurrentPosition(
83 | success: (position: Position) => void,
84 | error?: (error: PositionError) => void
85 | // options: PositionOptions = {}
86 | ) {
87 | const listener = addLocationListener((location) => {
88 | if (location.errorCode) {
89 | error && error(new PositionError(location.errorCode, location.errorInfo ?? "", location));
90 | stop();
91 | return listener.remove();
92 | }
93 | if (_options.locatingWithReGeocode && typeof location.address !== "string") {
94 | return;
95 | }
96 | success(toPosition(location));
97 | stop();
98 | return listener.remove();
99 | });
100 | start();
101 | }
102 |
103 | /**
104 | * 注册监听器进行持续定位
105 | *
106 | * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Geolocation/watchPosition
107 | */
108 | static watchPosition(
109 | success: (position: Position) => void,
110 | error?: (error: PositionError) => void
111 | // options?: PositionOptions
112 | ) {
113 | watchMap[++watchId] = addLocationListener((location) => {
114 | if (location.errorCode) {
115 | error && error(new PositionError(location.errorCode, location.errorInfo ?? "", location));
116 | } else {
117 | success(toPosition(location));
118 | }
119 | });
120 | start();
121 | return watchId;
122 | }
123 |
124 | /**
125 | * 移除位置监听
126 | *
127 | * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Geolocation/clearWatch
128 | */
129 | static clearWatch(id: number) {
130 | const listener = watchMap[id];
131 | if (listener) {
132 | listener.remove();
133 | }
134 | }
135 | }
136 |
137 | function toPosition(location: Location) {
138 | return {
139 | location,
140 | coords: {
141 | latitude: location.latitude,
142 | longitude: location.longitude,
143 | altitude: location.altitude ?? 0,
144 | accuracy: location.accuracy,
145 | altitudeAccuracy: 0, // 高德定位接口没有找到对应的数据
146 | heading: location.heading ?? 0,
147 | speed: location.speed ?? 0,
148 | },
149 | timestamp: location.timestamp ?? 0,
150 | };
151 | }
152 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./types";
2 | export * from "./geolocation";
3 | export * from "./amap-geolocation";
4 | export { default as Geolocation } from "./geolocation";
5 |
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * 高德开放平台应用 Key
3 | */
4 | export interface AppKey {
5 | ios: string;
6 | android: string;
7 | }
8 |
9 | /**
10 | * 定位结果类型
11 | *
12 | * @platform android
13 | */
14 | export enum LocationType {
15 | /**
16 | * 卫星定位结果
17 | *
18 | * 通过设备卫星定位模块返回的定位结果
19 | */
20 | GPS = 1,
21 |
22 | /**
23 | * 前次定位结果
24 | *
25 | * 网络定位请求低于1秒、或两次定位之间设备位置变化非常小时返回,设备位移通过传感器感知
26 | */
27 | SAME_REQ,
28 |
29 | /**
30 | * @deprecated
31 | */
32 | FAST,
33 |
34 | /**
35 | * 缓存定位结果
36 | *
37 | * 返回一段时间前设备在相同的环境中缓存下来的网络定位结果,节省无必要的设备定位消耗
38 | */
39 | FIX_CACHE,
40 |
41 | /**
42 | * Wifi定位结果
43 | *
44 | * 属于网络定位,定位精度相对基站定位会更好
45 | */
46 | WIFI,
47 |
48 | /**
49 | * 基站定位结果
50 | *
51 | * 属于网络定位
52 | */
53 | CELL,
54 |
55 | AMAP,
56 |
57 | /**
58 | * 离线定位结果
59 | */
60 | OFFLINE,
61 |
62 | /**
63 | * 最后位置缓存
64 | */
65 | LAST_LOCATION_CACHE
66 | }
67 |
68 | /**
69 | * iOS 错误代码
70 | *
71 | * @platform ios
72 | */
73 | export enum ErrorCodeIOS {}
74 |
75 | /**
76 | * Android 错误代码
77 | *
78 | * @platform android
79 | */
80 | export enum ErrorCodeAndroid {
81 | /**
82 | * 定位成功
83 | */
84 | LOCATION_SUCCESS,
85 |
86 | /**
87 | * 一些重要参数为空,可以通过 [[Location.locationDetail]] 获取详细信息
88 | */
89 | INVALID_PARAMETER,
90 |
91 | /**
92 | * 定位失败,由于设备仅扫描到单个 wifi,不能精准的计算出位置信息
93 | */
94 | FAILURE_WIFI_INFO,
95 |
96 | /**
97 | * 获取到的请求参数为空,可能获取过程中出现异常,可以通过 [[Location.locationDetail]] 获取详细信息
98 | */
99 | FAILURE_LOCATION_PARAMETER,
100 |
101 | /**
102 | * 网络连接异常,可以通过 [[Location.locationDetail]] 获取详细信息
103 | */
104 | FAILURE_CONNECTION,
105 |
106 | /**
107 | * 解析 XML 出错,可以通过 [[Location.locationDetail]] 获取详细信息
108 | */
109 | FAILURE_PARSER,
110 |
111 | /**
112 | * 定位结果错误,可以通过 [[Location.locationDetail]] 获取详细信息
113 | */
114 | FAILURE_LOCATION,
115 |
116 | /**
117 | * Key 错误,可以通过 [[Location.locationDetail]] 获取详细信息来跟注册的 Key 信息进行对照
118 | */
119 | FAILURE_AUTH,
120 |
121 | /**
122 | * 其他错误,可以通过 [[Location.locationDetail]] 获取详细信息
123 | */
124 | UNKNOWN,
125 |
126 | /**
127 | * 初始化异常,可以通过 [[Location.locationDetail]] 获取详细信息
128 | */
129 | FAILURE_INIT,
130 |
131 | /**
132 | * 定位服务启动失败,请检查是否配置 service 并且 manifest 中 service 标签是否配置在 application 标签内
133 | */
134 | SERVICE_FAIL,
135 |
136 | /**
137 | * 错误的基站信息,请检查是否安装 sim 卡
138 | */
139 | FAILURE_CELL,
140 |
141 | /**
142 | * 缺少定位权限,请检查是否配置定位权限,并在安全软件和设置中给应用打开定位权限
143 | */
144 | FAILURE_LOCATION_PERMISSION,
145 |
146 | /**
147 | * 网络定位失败,请检查设备是否插入 sim 卡、开启移动网络或开启了 wifi 模块
148 | */
149 | FAILURE_NOWIFIANDAP,
150 |
151 | /**
152 | * 卫星定位失败,可用卫星数不足
153 | */
154 | FAILURE_NOENOUGHSATELLITES,
155 |
156 | /**
157 | * 定位位置可能被模拟
158 | */
159 | FAILURE_SIMULATION_LOCATION,
160 |
161 | /**
162 | * 定位失败,飞行模式下关闭了 wifi 开关,请关闭飞行模式或者打开 wifi 开关
163 | */
164 | AIRPLANEMODE_WIFIOFF = 18,
165 |
166 | /**
167 | * 定位失败,没有检查到 sim 卡,并且关闭了 wifi 开关,请打开 wifi 开关或者插入 sim 卡
168 | */
169 | NOCGI_WIFIOFF
170 | }
171 |
172 | export type ErrorCode = ErrorCodeAndroid | ErrorCodeIOS;
173 |
174 | /**
175 | * 定位模式,目前支持三种定位模式
176 | *
177 | * @platform android
178 | */
179 | export enum LocationMode {
180 | /**
181 | * 低功耗模式,在这种模式下,将只使用高德网络定位。
182 | */
183 | Battery_Saving = "Battery_Saving",
184 |
185 | /**
186 | * 仅设备模式,只使用卫星定位,不支持室内环境的定位
187 | */
188 | Device_Sensors = "Device_Sensors",
189 |
190 | /**
191 | * 高精度模式,在这种定位模式下,将同时使用高德网络定位和卫星定位,优先返回精度高的定位
192 | */
193 | Hight_Accuracy = "Hight_Accuracy"
194 | }
195 |
196 | /**
197 | * 定位场景
198 | *
199 | * @platform android
200 | */
201 | export enum LocationPurpose {
202 | /**
203 | * 签到场景
204 | *
205 | * 只进行一次定位返回最接近真实位置的定位结果(定位速度可能会延迟 1-3s)。
206 | */
207 | SignIn = "SignIn",
208 |
209 | /**
210 | * 运动场景
211 | *
212 | * 高精度连续定位,适用于有户内外切换的场景,卫星定位和网络定位相互切换,卫星定位成功之后网络定位不再返回,卫星信号断开之后一段时间才会返回网络结果。
213 | */
214 | Sport = "Sport",
215 |
216 | /**
217 | * 出行场景
218 | *
219 | * 高精度连续定位,适用于有户内外切换的场景,卫星定位和网络定位相互切换,卫星定位成功之后网络定位不再返回,卫星信号断开之后一段时间才会返回网络结果。
220 | */
221 | Transport = "Transport"
222 | }
223 |
224 | /**
225 | * 逆地理编码语言
226 | */
227 | export enum GeoLanguage {
228 | /**
229 | * 默认,根据位置按照相应的语言返回逆地理信息,在国外按英语返回,在国内按中文返回
230 | */
231 | DEFAULT = "DEFAULT",
232 |
233 | /**
234 | * 中文,无论在国外还是国内都为返回中文的逆地理信息
235 | */
236 | ZH = "ZH",
237 |
238 | /**
239 | * 英文,无论在国外还是国内都为返回英文的逆地理信息
240 | */
241 | EN = "EN"
242 | }
243 |
244 | /**
245 | * 卫星信号强度
246 | *
247 | * @platform android
248 | */
249 | export enum GpsAccuracy {
250 | UNKNOWN,
251 | BAD,
252 | GOOD
253 | }
254 |
255 | /**
256 | * 定位结果的可信度
257 | */
258 | export enum TrustedLevel {
259 | HIGH = 1,
260 | NORMAL,
261 | LOW,
262 | BAD
263 | }
264 |
265 | /**
266 | * 定位信息
267 | */
268 | export interface Location {
269 | /**
270 | * 定位精度 (米)
271 | */
272 | accuracy: number;
273 |
274 | /**
275 | * 经度,[-180, 180]
276 | */
277 | latitude: number;
278 |
279 | /**
280 | * 纬度,[-90, 90]
281 | */
282 | longitude: number;
283 |
284 | /**
285 | * 海拔(米),需要 GPS
286 | */
287 | altitude?: number;
288 |
289 | /**
290 | * 移动速度(米/秒),需要 GPS
291 | */
292 | speed?: number;
293 |
294 | /**
295 | * 移动方向,需要 GPS
296 | */
297 | heading?: number;
298 |
299 | /**
300 | * 定位时间(毫秒)
301 | */
302 | timestamp?: number;
303 |
304 | /**
305 | * 错误码
306 | */
307 | errorCode?: ErrorCode;
308 |
309 | /**
310 | * 错误信息
311 | */
312 | errorInfo?: string;
313 |
314 | /**
315 | * 定位信息描述
316 | *
317 | * @platform android
318 | */
319 | locationDetail?: string;
320 |
321 | /**
322 | * 定位结果来源
323 | *
324 | * @platform android
325 | */
326 | locationType?: LocationType;
327 |
328 | /**
329 | * 卫星信号强度,仅在卫星定位时有效
330 | *
331 | * @platform android
332 | */
333 | gpsAccuracy?: GpsAccuracy;
334 |
335 | /**
336 | * 坐标系类型
337 | *
338 | * @platform android
339 | */
340 | coordinateType?: "WGS84" | "GCJ02";
341 |
342 | /**
343 | * 定位结果的可信度,只有在定位结果正确时,才有意义
344 | *
345 | * @platform android
346 | */
347 | trustedLevel?: TrustedLevel;
348 | }
349 |
350 | /**
351 | * 逆地理编码信息
352 | */
353 | export interface ReGeocode {
354 | /**
355 | * 详细地址
356 | */
357 | address?: string;
358 |
359 | /**
360 | * 国家
361 | */
362 | country?: string;
363 |
364 | /**
365 | * 省份
366 | */
367 | province?: string;
368 |
369 | /**
370 | * 城市
371 | */
372 | city?: string;
373 |
374 | /**
375 | * 城市编码
376 | */
377 | cityCode?: string;
378 |
379 | /**
380 | * 地区
381 | */
382 | district?: string;
383 |
384 | /**
385 | * 街道
386 | */
387 | street?: string;
388 |
389 | /**
390 | * 门牌号
391 | */
392 | streetNumber?: string;
393 |
394 | /**
395 | * 兴趣点
396 | */
397 | poiName?: string;
398 | }
399 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [
3 | "src/index.ts"
4 | ],
5 | "compilerOptions": {
6 | "strict": true,
7 | "skipLibCheck": true,
8 | "lib": [
9 | "esnext"
10 | ],
11 | "outDir": "lib/js",
12 | "declaration": true,
13 | "declarationMap": true,
14 | "jsx": "react-native"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------