美文网首页
React Native 高德地图选址

React Native 高德地图选址

作者: KooHead | 来源:发表于2019-06-26 19:04 被阅读0次
    预览

    React Native高德地图SDK插件分析

    • react-native-smart-amap
      这个库比较完美实现了地图选址功能,但是作者好像不再维护了,所以慎用。
    • react-native-amap3d
      这个库做的比较好,功能比较齐全,但是经过分析后,很难实现我们想要的功能。而且作者也建议使用网页实现此类功能。
    • react-native-amap-geolocation
      react-native-amap3d 作者将定位功能抽出来,针对的是使用高德地图进行高精度定位。感谢作者!

    实现思路

    • 根据react-native-amap3d作者的建议,我们使用网页实现主体界面。
    • 使用react-native-amap-geolocation进行高精度定位

    申请高德地图key

    • 在高德地图管理控制台申请Android、iOS和web端key。

    web端实现

    • 使用高德地图选址组件,请按照高德地图说明申请web端key
    • 添加本地html代码
    • map.html
    <!doctype html>
    <html>
    <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
       <meta http-equiv="X-UA-Compatible" content="IE=edge">
       <meta name="apple-mobile-web-app-capable" content="yes" />
       <meta name="apple-mobile-web-app-status-bar-style" content="black" />
       <title>地理位置</title>
       <style>
           body{
               position: absolute;
               top: 0;
               bottom: 0;
               left: 0;
               right: 0;
               margin: 0;
           }
           iframe{
               width: 99%;
               height: 98%;
           }
    
       </style>
    </head>
    <body>
    <iframe id="container" src=''></iframe>
    <script>
           (function(){
               var iframe = document.getElementById('container').contentWindow;
               document.getElementById('container').onload = function(){
                   iframe.postMessage('hello','https://m.amap.com/picker/');
               };
               window.addEventListener("message", function(e){
                   window.postMessage(JSON.stringify({
                       name: e.data.name,
                       location: e.data.location,
                       address: e.data.address
                   }))
               }, false);
           }())
       </script>
    </body>
    </html>
    
    • 需要注意的一点就是,由于React-Native WebView加载本地html文件问题,map.html文件需要分两个目录进行存放,iOS可以直接放在项目任何目录下(如:项目根目录)引用即可,而android必须放在android assets文件下才可以引用。
    • 使用window.postMessage() 将位置选取信息回传给WebView
    • 如图:


      android文件存储目录

    React Native端实现

    //  获取定位权限,由于我写界面的时候,还需要其他权限,这边我使用的是多权限申请方式,定位的单个申请是没问题的。如果觉得别扭,可以自行修改。
    async componentDidMount () {
        await init({
          ios: IOS_MAP_KEY, // iOS key
          android: ANDROID_MAP_KEY // android key
        })
        if (!IS_IOS) {
            try {
              const permissions = [
                PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION
              ]
              // 返回得是对象类型
              const granteds = await PermissionsAndroid.requestMultiple(permissions)
              if (granteds['android.permission.ACCESS_COARSE_LOCATION'] !== 'granted') {
                ToastAndroid.show('请开通定位权限,否则应用定位功能无法正常使用!', ToastAndroid.SHORT)
              } else {
                this.getCurrentPosition()
              }
            } catch (e) {
              ToastAndroid.show('定位权限获取异常', ToastAndroid.SHORT)
            }
        } else {
          this.getCurrentPosition()
        }
      }
    
    // 获取定位信息
    getCurrentPosition () {
        Geolocation.getCurrentPosition(({ location }) => {
          this.setState({
            lat: location.latitude,
            lng: Math.abs(location.longitude), //  国内获取的是一个负值。这里需要注意一下,是否考虑使用{lng:-location.longitude} 请自行验证
            positionGetError: false
          })
        }, () => {
          this.setState({
            positionGetError: true
          })
        }, {
          timeout: 8
        })
      }
    
    • 使用WebView加载网页
    // WEB_CLIENT web端key值
        <WebView
            bounces={false}
            domStorageEnabled={false}
            javaScriptEnabled
            useWebKit
            injectedJavaScript={`document.getElementById("container").src="https://m.amap.com/picker/?center=${this.state.lng},${this.state.lat}&zoom=18&key=${WEB_CLIENT}&keywords=景区,超市,小区"`}
            onMessage={(e) => {
              console.log('data', e.nativeEvent.data)
            }}
            mixedContentMode={'always'}
            renderError={() => this._renderWebViewError()}
            source={IS_IOS ? require('../htmls/map.html') : { uri: 'file:///android_asset/htmls/map.html' }}
          />
    
    • 注意:添加useWebKit,否则iOS可能会出现问题
    • 从代码中我们可以看出,我们使用injectedJavaScript对web端注入了一段javascript代码,目的是将我们的位置信息注入,并且改变web端iframe的src地址。
    • onMessage获取web端postMessage()的回传数据

    相关文章

      网友评论

          本文标题:React Native 高德地图选址

          本文链接:https://www.haomeiwen.com/subject/qyrhcctx.html