为啥 PhoneGap Geolocation onSuccess 从来没有第一次触发?

Posted

技术标签:

【中文标题】为啥 PhoneGap Geolocation onSuccess 从来没有第一次触发?【英文标题】:Why does PhoneGap Geolocation onSuccess never fires the first time around?为什么 PhoneGap Geolocation onSuccess 从来没有第一次触发? 【发布时间】:2014-04-25 11:51:58 【问题描述】:

今晚我在 *** 上搜索了几个小时,寻找解决这个问题的方法,我强烈认为这是 Geolocation 的 cordova/phonegap 错误。

我在geoLocation enabling without page-refresh? 遇到了与@Tal 相同的问题

基本上,来自 getLocation 调用的 onSuccess 永远不会在您第一次请求位置时被调用。我已经设置了一个超时来调用 onError 并休息页面,但仍然无法弄清楚为什么它第一次不起作用,只有完全刷新才能解决问题。将其放入循环中,即:

function onError(error) 
  if (error.code === PositionError.TIMEOUT)
    navigator.geolocation.getCurrentPosition(onSuccess, onError,
       maximumAge: 3000, timeout: 1000, enableHighAccuracy: true  );
  
  // Handle other errors here

似乎也从来没有工作过。我尝试重新安排我的代码顺序和功能,但似乎没有任何区别。该应用程序仅在第一次失败后才能成功获取 GPS 坐标。我真的认为它是一个科尔多瓦错误。下面是我的完整 javascript 代码:

<script type="text/javascript" charset="utf-8">
    // onSuccess Geolocation
    //
    function onSuccess(position) 
        var element = document.getElementById('geolocation');
        //OUTPUT COORDINATES INFORMATION INTO html
    element.innerHTML = '<h2>Detailed Gelocation information</h2><table class="geoTable"><tr><td class="noborder"></td><th>Latitude</th><th>Longitude</th><th>Altitude</th><th>Accuracy</th><th>Altitude Accuracy</th><th>Heading</th><th>Speed</th><th>Timestamp</th></tr>' +
            '<tr><td class="head">Data Value</td>' +
            '<td class="centre">' + position.coords.latitude  + '</td>' +
            '<td class="centre">' + position.coords.longitude + '</td>' +
            '<td class="centre">'  + position.coords.altitude + '</td>' +
            '<td class="centre">'  + position.coords.accuracy + '</td>' +
            '<td class="centre">'  + position.coords.altitudeAccuracy + '</td>' +
            '<td class="centre">'  + position.coords.heading + '</td>' +
            '<td class="centre">'  + position.coords.speed   + '</td>' +
            '<td class="centre">' + new Date(position.timestamp) + '</td></tr>'+
            '</table>' +
            '<p align="center"><button data-theme="h" onclick="resetLocation();">Clear GPS Location</button></p>';


                    //GET LOCATION VARIABLES FROM API
                    var lat = position.coords.latitude;
                    var lng = position.coords.longitude;
                    var yourStartLatLng = new google.maps.LatLng(lat, lng);

                    //PUT GMAPS INFORMATION INTO PAGE
                    $('#map_canvas').gmap('center': yourStartLatLng);
                    $('#map_canvas').gmap('option', 'zoom', 19);
                    $('#map_canvas').gmap('option', 'mapTypeId', google.maps.MapTypeId.SATELLITE);
                    $('#map_canvas').gmap('addMarker', 
                                                        'position': yourStartLatLng, 
                                                        'draggable': false, 
                                                        'bounds': false
                                                        );
    
    // onError Callback sends user an alert message and refreshes screen to load all scripts again
    //
    function onError(error) 
        alert('The Freshwater application failed to get your location. Please ensure that you have a successful WIFI or 3G/4G internet connection when using the Geolocation feature. ' +
              'The Locator screen will now be refreshed. Please attempt Geolocation again.');

    //navigator.geolocation.getCurrentPosition(onSuccess, onError,
      // maximumAge: 3000, timeout: 5000, enableHighAccuracy: false  );
        //PUT A TIMER ON ERROR TO REFRESH PAGE FOR GPS
        setTimeout("window.location+='?refreshed';", .1000); 
    

//RESET GEOLOCATION PAGE TO TAKE ANOTHER LOCATION READING
    function resetLocation()
        setTimeout("window.location+='?refreshed';", .1000); 
    

    //ATTACH FUNCTION TO BUTTON TO CALL GEOLOCATION
  function getLocation() 
        navigator.geolocation.getCurrentPosition(onSuccess ,onError,
       timeout: 1000, enableHighAccuracy: true  );
    
</script>

【问题讨论】:

你的科尔多瓦版本? 对不起,忘了说。我正在使用最新版本,3.4 我们已经在 XDK 中看到了一些类似的地理问题(它提供了类似的 webview 环境),并且认为问题是由本地 GPS 实现引起的——结果往往会因功能而异android 版本和 Android 制造商。希望我能提供一个解决方案... 是的,我听说过。我希望我的 beta 测试人员不会遇到同样的问题/错误。我要在这里“飞行”,但我想知道使用 Adob​​e Phonegap 构建服务是否会得到不同的结果?太糟糕了,应用程序超过 15mb... 【参考方案1】:

是 Javascript 的加载时间导致地理定位功能第一次超时。

我对脚本进行了一些修改,并删除了一些我没有使用的 Gmap UI Jquery 库。

jquery.ui.map.extensions.js
jquery.ui.map.microdata.js
jquery.ui.map.microformat.js
jquery.ui.map.overlays.js
jquery.ui.map.rdfa.js
jquery.ui.map.services.js

这可能会产生很小的影响。在使用 ios 模拟器进行一些基于时间的测试时,页面加载后立即询问地理位置永远不会在第一次触发 onSuccess。如果我在单击“获取位置”按钮之前等待大约 10 秒,它会在第一次工作。

显然,这与在请求地理定位之前正确加载所有(内部和外部)脚本有关。我已经像这样预加载了外部谷歌地图脚本:

  function onLoad() 
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = 'https://maps.googleapis.com/maps/api/js?key=AIzaSyDy1bBAiDhmFfuKz6SerLvKyOIUqlFsX7c&sensor=true&' +
  'callback=mapLoaded';
  document.body.appendChild(script);
    

但是如果有人请求地理定位太快,它似乎会超时并在第一次运行 onError。

更新:我决定隐藏请求地理定位的按钮,并在加载外部脚本时显示它(并放置一个加载栏 gif)。请求位置时仍然会出错。很可能是因为 google api 代码本身包含一个 getScript 命令(所以我没有看到真正的加载时间)。

也许是谷歌的摆布?

【讨论】:

【参考方案2】:

我认为这可能是因为您的设备尚未“就绪”。见以下代码:

<script>
    function onDeviceReady() 
        // Do your geolocation call here ...
    
    document.addEventListener("deviceready", onDeviceReady, false);
</script>

如果您将地理定位调用置于设备就绪事件中,那么它们只会在您的设备被视为“就绪”时触发。

【讨论】:

以上是关于为啥 PhoneGap Geolocation onSuccess 从来没有第一次触发?的主要内容,如果未能解决你的问题,请参考以下文章

PhoneGap GeoLocation 变量类型

实现Phonegap Android的Geolocation API

phonegap android中navigator.geolocation.getCurrentLocation的奇怪行为

PhoneGap/Cordova 将 GeoLocation 从 localStorage vars 推送到 MySQL

在 Android 2.0+ 上的 WebView 中使用 navigator.geolocation.getCurrentPosition(PhoneGap 相关)

Android Geolocation onError Phonegap