Geolocation feedback while accepting the request

2019-01-22 04:39发布

the geolocation implementation is quite good and got few steps to observe but only on thing is missing, i guess. Im not able to see if the user accepted the request or not ( before i get the position object ), i dunno if the user just ignores my request ( during my timeout ) or if the request just get lost ( and the failure callback doesnt get called for no reason ).

It would be useful to set a timestamp when the user accepts the request, i couldnt find anything which gives me that kind of response.

3条回答
聊天终结者
2楼-- · 2019-01-22 05:05

Tested it successful in FF 3.5, Opera 10.6, Chrome8, IE6-8..

var succeed = function(obj) {
    navigator.geolocation.received = true;
    !navigator.geolocation.timedout?alert('GOT YAH'):alert('GOT YAH but user was to slow'); 
};
var failed  = function(obj) { 
    navigator.geolocation.received = true;
    !navigator.geolocation.timedout?alert('just failed'):alert('failed and user was to slow as well, tzz ._.'); 
};
var timedout    = function() {
    navigator.geolocation.timedout = true; // could be used for other callbacks to trace if its timed out or not
    !navigator.geolocation.received?alert('Request timed out'):null;    
}

// Extend geolocation object
if ( navigator.geolocation  ) {
    navigator.geolocation.retrievePermission = function retrievePermission(succeed,failed,options,timeout) {
        this.received = false;              // reference for timeout callback
        this.timedout = false;              // reference for other callbacks
        this.getCurrentPosition.apply(this,arguments);  // actual request

        // Trigger timeout with its function; default timeout offset 5000ms
        if ( timeout ) {
            setTimeout(timeout.callback,timeout.offset || 5000);
        }
    }

    // New location request with timeout callback
    navigator.geolocation.retrievePermission(succeed,failed,{},{
        offset: 10000, // miliseconds
        callback: timedout  
    });

// Awesome thingy is not implemented
} else {
    alert('geolocation is not supported');
}

With that workaround we know if the request timedout, even when the succeess / failure callback get called afterwards.

查看更多
戒情不戒烟
3楼-- · 2019-01-22 05:07

Based on my new understanding of what you are after, you want something like this. (Tested: in Opera - works, Firefox 3.6 & Chrome 8 - not so much (I need more time to debug))

Scenario: Page attempts to get location... but user ignores the prompt completely thus there is no (accept or deny) and since the request for the location is never sent, there is no timeout either!

Based on this you may want to add your own logic to handle this scenario. For the sake of this example, I'm going to prototype my own "wrapper" method. (for the picky - I'm not condoning using globals etc. I was just trying to get something to work)

navigator.geolocation.requestCurrentPosition = function(successCB, errorCB, timeoutCB, timeoutThreshold, options){
  var successHandler = successCB;
  var errorHandler = errorCB;
  window.geolocationTimeoutHandler = function(){
    timeoutCB();
  }
  if(typeof(geolocationRequestTimeoutHandler) != 'undefined'){
    clearTimeout(window['geolocationRequestTimeoutHandler']);//clear any previous timers
  }
  var timeout = timeoutThreshold || 30000;//30 seconds
  window['geolocationRequestTimeoutHandler'] = setTimeout('geolocationTimeoutHandler()', timeout);//set timeout handler
  navigator.geolocation.getCurrentPosition(
    function(position){
      clearTimeout(window['geolocationRequestTimeoutHandler']);
      successHandler(position);
    },
    function(error){
      clearTimeout(window['geolocationRequestTimeoutHandler']);
      errorHandler(error);
    },
     options
  );
};
function timeoutCallback(){
  alert('Hi there! we are trying to locate you but you have not answered the security question yet.\n\nPlease choose "Share My Location" to enable us to find you.');
}
function successCallback(position){
  var msg = '';
  msg += 'Success! you are at: ';
  msg += '\nLatitude: ' + position.coords.latitude;
  msg += '\nLongitude: ' + position.coords.longitude;
  msg += '\nAltitude: ' + position.coords.altitude;
  msg += '\nAccuracy: ' + position.coords.accuracy;
  msg += '\nHeading: ' + position.coords.heading;
  msg += '\nSpeed: ' + position.coords.speed;
  alert(msg);
}
function errorCallback(error){
  if(error.PERMISSION_DENIED){
    alert("User denied access!");
  } else if(error.POSITION_UNAVAILABLE){
    alert("You must be hiding in Area 51!");
  } else if(error.TIMEOUT){
    alert("hmmm we timed out trying to find where you are hiding!");
  }
}
navigator.geolocation.requestCurrentPosition(successCallback, errorCallback, timeoutCallback, 7000, {maximumAge:10000, timeout:0});

The concept is to set up a timer first (defaults to 30 seconds if not set). If the user doesn't do anything before the timer expires, a timeoutCallback is called.

Notes:

  1. Some UI's (e.g. iPhone/iPad/iPod Safari) may make the Allow/Deny prompt modal - thus the user can't really continue until they pick something (I'd suggest to leave these users alone and let the default UI handle things
  2. If the user Allows the request (late), the timeout may still fire before the response comes back - I don't think there is anything you can do about this
  3. Code above is an example only... it needs cleaning up.
查看更多
Evening l夕情丶
4楼-- · 2019-01-22 05:23

It is part of the Geolocation API:

// navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options);
navigator.geolocation.getCurrentPosition(
  function(position){
    //do something with position;
  }, function(){
    //handle condition where position is not available
    //more specifically you can check the error code...
    //error.code == 1
    if(error.PERMISSION_DENIED){
      alert("you denied me! ");
    }
});

If you specify the errorCallback... then you can track if the user has declined to provide access.

Possible error codes include:

error.PERMISSION_DENIED    (numeric value 1)
error.POSITION_UNAVAILABLE (numeric value 2)
error.TIMEOUT              (numeric value 3)
查看更多
登录 后发表回答