├── .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 |