Обратная связь геолокации при принятии запроса - PullRequest
9 голосов
/ 19 января 2011

реализация геолокации довольно хороша и имеет несколько шагов для наблюдения, но, я думаю, только что-то упущено. Я не в состоянии увидеть, принял ли пользователь запрос или нет (до того, как я получу объект позиции), я не знаю, просто ли пользователь игнорирует мой запрос (во время моего тайм-аута) или если запрос просто теряется (и обратный вызов сбоя не получает звонил без причины).

Было бы полезно установить временную метку, когда пользователь принимает запрос, я не смог найти ничего, что дало бы мне такой ответ.

Ответы [ 3 ]

6 голосов
/ 19 января 2011

Исходя из моего нового понимания того, что вы ищете, вы хотите что-то вроде этого. (Проверено: в Opera - работает, Firefox 3.6 и Chrome 8 - не так уж много (мне нужно больше времени для отладки))

Сценарий: Страница пытается получить местоположение ... но пользователь полностью игнорирует приглашение, поэтому его нет (принять или отклонить), и поскольку запрос на местоположение никогда не отправляется, тайм-аут также не существует!

Исходя из этого, вы можете добавить собственную логику для обработки этого сценария. Ради этого примера я собираюсь создать прототип моего собственного метода-оболочки. (для разборчивых - я не потворствую использованию глобалов и т. д. Я просто пытался заставить что-то работать)

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});

Концепция заключается в том, чтобы сначала установить таймер (по умолчанию 30 секунд, если не установлен). Если пользователь ничего не делает до истечения таймера, вызывается timeoutCallback.

Примечания:

  1. Некоторые пользовательские интерфейсы (например, iPhone / iPad / iPod Safari) могут сделать приглашение «Разрешить / Запретить» модальным - таким образом, пользователь не сможет продолжить, пока не выберет что-то (я бы предложил оставить этих пользователей в покое и оставить пользовательский интерфейс по умолчанию). обращаться с вещами
  2. Если пользователь разрешает запрос (с опозданием), тайм-аут все еще может сработать до возвращения ответа - я не думаю, что с этим можно что-либо сделать
  3. Код выше приведен только в качестве примера ... он нуждается в очистке.
6 голосов
/ 19 января 2011

Это часть 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! ");
    }
});

Если вы укажете errorCallback ..., вы можете отследить, отказался ли пользователь предоставить доступ.

Возможные коды ошибок включают в себя:

error.PERMISSION_DENIED    (numeric value 1)
error.POSITION_UNAVAILABLE (numeric value 2)
error.TIMEOUT              (numeric value 3)
5 голосов
/ 20 января 2011

Успешно протестировано в 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');
}

С помощью этого обходного пути мы узнаем, истек ли тайм-аут запроса, даже если впоследствии вызывается обратный вызов успеха / сбоя.

...