最近在做项目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