1
votes

in my Ionic app, I implemented the geolocation watchPosition with the following options. My options are set to fire every 10 seconds, but its firing every second. And often it fires two times per second.

function watchPosition() {
   var options = {
      maximumAge: 10000,
      timeout: 10000,
      enableHighAccuracy: true,
   }
   watchID = navigator.geolocation.watchPosition(onSuccess, onError, options);

   function onSuccess(pos) {
      ...
   }
   function onError(error) {
      ...
   }
}

And when my device is ready, I trigger the watchPosition function with an addListener:

Original call was like this: var watchID = null ; document.addEventListener("deviceready", watchPosition);

I then changed to this: document.addEventListener("deviceready",setupWatch) ;

function setupWatch() {
    // global var here so it can be cleared on logout (or whenever).
    activeWatch = setInterval(watchPosition, 5000);
}

And it is still firing every second.

Then I replaced the addEventListener simply with, I realized the eventListener was already inside of Ionics $ionicPlatform.ready() { .. } thus an eventListener wasn't needed. However, just calling this now triggers the watchPosition like 5 times per second, not once per 5 seconds.:

setupWatch() ;

Additional question regarding best practices for watchPosition. What is the ideal timeout for continuing to call this function...is every second OK, is it too much load/processing, does it drain batteries faster, etc?

3
Could you clarify what you mean please? Where am I calling it multiple times? I think with addEventListener, once device is ready, call the function. Once function is in memory, call itself every 10 seconds.rolinger

3 Answers

0
votes

The timeout and maximumAge you're using are not defining how frequently you have an answer from the browser. Here is what MDN says about these properties:

PositionOptions.timeout Is a positive long value representing the maximum length of time (in milliseconds) the device is allowed to take in order to return a position.

PositionOptions.maximumAge Is a positive long value indicating the maximum age in milliseconds of a possible cached position that is acceptable to return.

source

I would advice you to store the value from the callback in a variable and user another setInterval to return the value at a rate you can define.

EDIT

If you want to handle the rate of answer, you can use the function getCurrentPosition, that will fire the callback only once (source)

0
votes

In my code the watchPosition was firing twice in succession but the getCurrentPostion always just fires once for obvious reasons.

Solution 1 would be to use getCurrentPosition, and then set a timer to re-check that position X milliseconds later and update as required.

Solution 2 (which I used, for various other reasons) would be to use watchPosition but have the callback double-check that the long/lat has actually changed. If not then ignore the rest of the function. So as an example:

var oldlong = "";
var oldlat = "";

navigator.geolocation.watchPosition(onGpsChangeSuccess,onGpsError,{
   maximumAge: 10000, 
   enableHighAccuracy: false, 
   timeout: 15000 
 }
);

var onGpsChangeSuccess = function(){
    //Watch was triggered...

    if(oldlong != position.coords.longitude && oldlat!=position.coords.longitude){

        //Changes detected
        oldlong = position.coords.longitude;
        oldlat = position.coords.latitude; 
        performTheRestOfYourFunctionHere

   }else{
       //No changes detected
   }
}

We shouldn't have to perform this additional check, but if the watcher has a bug then it's better to be safe.

0
votes

I would be surprised that your successive Lat/Lng readings are identical. Perhaps the "accuracy" meters have varied or one source was GPS and another Telco Tower. Outdoors or indoors?

Regardless I recommend filtering readings as appropriate for your App. Ignoring inaccurate or uninteresting readings is IMHO something ALL GPS Apps have to cater for.