2011-01-19 2 views
9

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

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

ответ

6

Основываясь на моем новом понимании того, что вы после этого, вы хотите что-то вроде этого. (Испытано: в 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 секунд, если не установлен). Если пользователь ничего не делает до истечения таймера, вызывается тайм-аут Callback.

Примечание:

  1. Some UI (например iPhone/IPad/IPod Safari) может сделать Разрешить/Запретить быструю модальность - таким образом, пользователь не может реально продолжать, пока они не выбрать что-то (я бы предлагайте оставить этих пользователей в покое и позволить стандартным пользовательским интерфейсам обрабатывать вещи
  2. Если пользователь разрешает запрос (позднее), тайм-аут может по-прежнему срабатывать до того, как ответ вернется - я не думаю, что вы можете что-то сделать с этим
  3. Код, приведенный выше, является примером только ... он нуждается в очистке.
+0

отличное решение, я думаю, что он заполнит «недостающий» случай в этом API. Возможно, они также расширят его, его еще черновик и может быть важной обратной связью (чтобы не заставить пользователя принимать скорее управление вашим сайтом). Большое спасибо за то, что потратили на это время, старайтесь создать стабильное решение для кроссбраузеров;) – Maertz

+1

+1, очень элегантное решение. – fmark

+1

@tetra Пожалуйста, отправьте ссылку на свое стабильное решение для кроссбраузеров, когда это будет сделано. – fmark

5

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

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

Возможные error codes включают в себя:

error.PERMISSION_DENIED (numeric value 1) 
error.POSITION_UNAVAILABLE (numeric value 2) 
error.TIMEOUT    (numeric value 3) 
+1

hi scunliffe, функции обратного вызова вызываются только тогда, когда пользователь принимает или отклоняет разрешение, но мне нужно что-то, что дает мне ответ, когда пользователь принимает запрос до того, как тайм-аут будет запущен.Это моя проблема, вы можете вызвать запрос, но пользователь может игнорировать его, и вы никогда не узнаете, что произошло, потому что тайм-аут просто запускается, когда пользователь принял запрос – Maertz

+0

@tetra - возможно, я чего-то не хватает в том, что вам нужно. Когда я использую приведенный выше код ... Если я DENY запроса, будет установлен код ошибки error.PERMISSION_DENIED' (значение 1), поэтому я знаю, что пользователь отклонил его. Если пользователь позволяет сделать вызов, тогда он погаснет и получит координаты. – scunliffe

+0

@tetra - на самом деле, я думаю, что знаю, что ты сейчас делаешь. (Я тестирую код, чтобы выполнить то, что вам нужно ...) – scunliffe

5

Испытано его успешным в 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'); 
} 

С этого обходного мы знаем, если запрос timedout, даже если обратный вызов succeess/отказ дозвонились впоследствии.

Смежные вопросы