【问题标题】:Geolocation watch doesn't fire consistently地理位置手表不会持续触发
【发布时间】:2015-08-01 17:19:38
【问题描述】:

我有一个测试应用程序,它从 HTML5 地理定位服务获取 lat/lng 值。不幸的是,它以相当不一致的时间间隔发射,从 500 毫秒到 10000 毫秒不等。我已经尝试更改手表的 maximimAge 和 timeout 参数,但这些似乎并没有改变任何东西。我正在 Chrome 中以及通过 Android Lollipop 构建上的简单 Cordova 应用程序对其进行测试。下面的代码仅显示手表的时间戳值,以消除可能导致问题的任何其他延迟。似乎该间隔接近 1 秒然后 5 秒的重复模式。我还尝试将地理位置获取函数放在 setInterval 函数中,它的行为具有相同的 1 秒和 5 秒重复间隔。

<html>
<body>
    <h1>Timestamp</h1>
    <div id="mytimestamp"></div>
    <button id="btnstopwatch">Stop GPS</button>
</body>
</html>

<script type="text/javascript">
    var mytimestamp = document.getElementById("mytimestamp");
    //start watching location
    watchPositionId = navigator.geolocation.watchPosition(updateCompass,handleerror,{
        enableHighAccuracy:true, 
        maximumAge:3000, 
        timeout:3000
    });

function updateCompass(p)
{
    mytimestamp.innerHTML = p.timestamp;
}

function handleerror(err)
{
    if(err.code ==1)
    {
        //user said no
        alert('Please allow access to GPS');
    }
    else
    {
        alert(err.code);
    }
}
</script>

【问题讨论】:

    标签: javascript html cordova geolocation


    【解决方案1】:

    关于 watchPosition(),在下面的 link w3 中说“只有在获得新位置时才调用successCallback ......实现可能会对频率施加限制回调,以避免无意中消耗不成比例的资源。”

    这意味着 watchPosition() 正在等待会导致位置发生变化的事件,否则它什么也不做。所以 watchPosition() 不会调用 updateCompass() 除非它看到位置的变化。 另外,关于watchPosition(),maximumAgetimeout参数与获取新位置有关,这些参数与watchPosition()的次数和时间无关被称为...

    WatchPosition() 防止连续调用以查看位置是否发生变化,并且仅在发生与位置变化相关的某些事件时才做出反应,这有助于节省电池等资源。但是如果你真的想看位置,比如说每三秒一次,不管位置是否改变,我认为设置一个间隔是个好方法。

    var watchPositionId;
       //start watching location
        setInterval(function () {
        watchPositionId = navigator.geolocation.watchPosition(updateCompass, handleerror, {
            enableHighAccuracy: true,
            maximumAge: 3000,
            timeout: 3000
        });
        }, 3000);
    
        function updateCompass(p) {
            mytimestamp.innerHTML = p.timestamp;
            // if you have alert message it will counts seconds once you dismiss the alert,
            //this may be part of the issue why you kept getting diffrent intervals.
            //alert(p.timestamp);
            navigator.geolocation.clearWatch(watchPositionId);
        }
    

    您提到您尝试 setInterval 但它不起作用,所以请注意我在上面的代码中注释了 alert() 因为它导致我有延迟,没有它,html 中的时间戳每 3000 毫秒更新一次精度约5ms。

    如果您想使用 watchPosition(),上述方法有效,因为 clearWatch() 会停止 watchPosition() 并进一步回调。基本上,上面的代码每三秒启动一次新的 watchPosition() 并用 clearWatch() 终止它。话虽如此,我认为 watchPosition() 不是在这种方法中使用的最佳方法,除非您预计在此时间间隔内位置会发生重大变化。我宁愿使用 getCurrentPosition() ,因为它可以完成工作并且不等待位置变化。

     var watchPositionId;
       //start watching location
        setInterval(function () {
            watchPositionId = navigator.geolocation.getCurrentPosition(updateCompass, handleerror, {
            enableHighAccuracy: true,
            maximumAge: 3000,
            timeout: 3000
        });
        }, 3000);
    
        function updateCompass(p) {
            mytimestamp.innerHTML = p.timestamp;
        }
    

    【讨论】:

    • 我将代码更改为使用 getCurrentPosition 函数,现在它会在 4.5 到 6.5 秒之间更新。我很快将把它加入到 Cordova 应用程序中,看看它是否会继续以这种方式运行。目前,我可以忍受这种不一致,希望它在编译成本机代码后会变得更加一致。
    • 请记住,如果您的代码中有 alert(),则在您单击警报上的“确定”按钮后,时间间隔的时间就会开始计算,因此您的时间戳将具有比预期更长的时间。
    【解决方案2】:

    我最终将解决方案更改为同时使用地理位置和 deviceOrientationEvent。单独使用地理定位事件会产生非常“生涩”的响应,而设备方向事件可以消除这种情况。

    这里的 setInterval 函数设置为每十秒获取一次地理位置:

    window.onload = function()
    {
        //fetch new GPS info every 10000 milliseconds
        window.setInterval(function ()
        {
            navigator.geolocation.getCurrentPosition(onGeoSuccess, onGeoFailure, {
            enableHighAccuracy: true,
            maximumAge: 0,
            timeout: 30000 //large timeout to accomodate slow GPS lock on some devices
        });
        }, 10000);  //update current location every ten seconds
    };
    

    关于地理上的成功:

    function onGeoSuccess(location)
    {
    
        //call function to calculate bearing
        var cluebearing = geo.bearing(currentlat, currentlng, cluelat, cluelng);
    
        //call function to rotate arrow
        rotateArrow(cluebearing);
    }//end onGeoSuccess()
    

    获取设备方向和进程的功能:

    function rotateArrow(mybearing)
    {
        //Check for support for DeviceOrientation event
        if(window.DeviceOrientationEvent)
        { 
            //orientation listener
            window.addEventListener('deviceorientation', function(event)
            {
                var myalpha = event.alpha; //rotation from north
                //process orientation change
            }//end deviceorientation listener
        }
    }//end rotateArrow()
    

    关于地理故障:

    function onGeoFailure()
    {
        alert('Please turn on your phone\'s GPS');
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-05
      • 1970-01-01
      • 2019-06-08
      • 1970-01-01
      • 1970-01-01
      • 2021-01-27
      相关资源
      最近更新 更多