ReactNative运用插件react-native-amap-geolocation获取Android手机高德经纬度

伍胡媚
2023-12-01

背景

最近在做项目ReactNative项目时需要获取手机的经纬度,刚开始直接使用浏览器的原生方法:navigator.geolocation.getCurrentPosition,在ios手机运行正常,但是在Android部分机型上面会超时。

分析

1,因为ios6以后系统用的都是高德定位服务,而Android手机系统用的是Google定位服务,而且国内手机厂商对操作系统做了不同的定制,在国内基本不支持Google定位服务
2,既然浏览器原生的定位方法在Android机行不通,那能否用ReactNative专门的定位API Geolocation呢?事实证明这个也是行不通的,底层调的也是Google定位服务
3,在native部分移植高德sdk,然后手动暴露接口给ReactNative调用,理论可行,但是复杂度比较高,作为备选方案
4,尝试ReactNative关于高德定位服务插件react-native-amap-geolocation

实现

插件安装:

npm istall react-native-amap-geolocation --save
react-native link react-native-amap-geolocation

JS部分:

import { Geolocation, init } from "react-native-amap-geolocation";

export default class ClockedInList extends React.Component {
async geolocationInit() {
   if (Platform.OS === "android") {
      const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION);
      if (granted === PermissionsAndroid.RESULTS.GRANTED) {
         //设置高德key
         await init({
            // ios: "9bd6c82e77583020a73ef1af59d0c759",
            android: "b53dcb22e8061d27116422b82123bae2"   // 传入AMAP_KEY
         });
         this.requestFetchGetList();
      }
   } else {
      this.requestFetchGetList();
   }
};

componentDidMount() {
   this.geolocationInit();
}

requestFetchGetList() {
   if (Platform.OS === "android") {
      return new Promise(() => {
         Geolocation.getCurrentPosition(
            location => {
               let getCoordinate = wgs84togcj02(location.coords.longitude, location.coords.latitude);
               const { pageNum, strName } = this.state;
               let params = {
                  pageSize: 10,
                  strName,
                  pageNum,
                  lon: getCoordinate[0],
                  lat: getCoordinate[1]
               }
               queryStrList(params).then((res) => {
                  if (+res.success === 1) {
                     this.arr.push(res.result.pageResult.list)
                     this.setState({
                        pageNum,
                        pages: res.result.pageResult.pages
                     })
                  }
               })
            },
         (error) => this.setState({ error: error.message }, alert(error.message)),
         { enableHighAccuracy: true, timeout: 10000, maximumAge: 10000 },);
      })
   } else {
      return new Promise(() => {
         navigator.geolocation.getCurrentPosition(
            location => {
            let getCoordinate = wgs84togcj02(location.coords.longitude, location.coords.latitude);
            const { pageNum, strName } = this.state;
            let params = {
               pageSize: 10,
               strName,
               pageNum,
               lon: getCoordinate[0],
               lat: getCoordinate[1]
            }
            queryStrList(params).then((res) => {
               if (+res.success === 1) {
                  this.arr.push(res.result.pageResult.list)
                  this.setState({
                     pageNum,
                     pages: res.result.pageResult.pages
                  })
               }
            })
         },
         (error) => this.setState({ error: error.message }, alert(error.message)),
         { enableHighAccuracy: true, timeout: 10000, maximumAge: 10000 },);
      })
   }
}

因为服务调用要在初始化之前完成,所以PermissionsAndroid.request和init函数前面添加await

Native部分在MainApplication引入AMapGeolocationPackage,什么都不用动

AMAP_KEY是在高德官网上针对应用申请的key,申请过程详见官网:https://lbs.amap.com/api/android-location-sdk/guide/create-project/get-key

我遇到的一个坑就是有个同事改变了应用的keystore,但是我还是用Android Studio默认的debug.keystore去获取SHA1,导致key值不对,这里跟大家推荐一个好用的apk:Gen_Signature_Android.apk,输入应用程序包名就可以得到证书指纹的MD5值,可以确认自己使用的keystore是否是同一个。例如
证书指纹:
MD5: 0C:1E:2F:37:D4:23:6C:5E:7C:2B:E2:EF:60:81:15:E9
SHA1: 69:45:BF:12:D4:DB:0C:4F:BB:29:14:02:8B:78:F5:25:7C:BD:06:CE
SHA256: 1E:9C:7F:7F:72:B2:16:3C:66:F4:05:54:D3:A9:C9:7F:4A:83:C5:A3:99:B6:27:06:0F:12:F6:C7:5B:22:79:8C

结论

运用插件react-native-amap-geolocation可以完美解决ReactNative在Android手机的定位问题,获取到的经纬度和Android原生集成高德sdk获取到的相同,因为两者的定位服务是相同的:AMapLocationClient

 类似资料: