2011-01-19 9 views
9

la implementación de la geolocalización es bastante buena y tengo algunos pasos para observar, pero solo me falta algo, supongo. No puedo ver si el usuario aceptó la solicitud o no (antes de obtener el objeto de posición), no sé si el usuario simplemente ignora mi solicitud (durante mi tiempo de espera) o si la solicitud simplemente se pierde (y la devolución de llamada fallida no ser llamado sin ninguna razón).Retroalimentación de geolocalización al aceptar la solicitud

Sería útil establecer una marca de tiempo cuando el usuario acepte la solicitud, no pude encontrar nada que me brinde ese tipo de respuesta.

Respuesta

6

Con base en mi nueva comprensión de lo que está después, usted quiere algo como esto. (probado en Opera: - obras, Firefox 3.6 & Chrome 8 - no tanto (me necesitan más tiempo para depuración))

Escenario: página intenta obtener la ubicación ... pero el usuario ignora por completo el símbolo por lo tanto, no hay (aceptar o denegar) y dado que la solicitud de la ubicación nunca se envía, ¡tampoco hay tiempo de espera!

En función de esto, es posible que desee agregar su propia lógica para manejar este escenario. Por el bien de este ejemplo, voy a crear un prototipo de mi propio método de "envoltura". (Para el exigente - No estoy tolerar el uso de variables globales, etc. Yo sólo estaba tratando de conseguir algo de trabajo)

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

El concepto es la creación de un temporizador primero (por defecto es de 30 segundos si no se establece). Si el usuario no hace nada antes de que el temporizador caduque, se invoca un timeoutCallback.

Notas:

  1. de algunos interfaz de usuario (por ejemplo, iPhone/iPad/iPod Safari) pueden hacer que el Permitir/Denegar modal pronta - por lo tanto el usuario no puede continuar hasta que realmente recoger algo (que había sugiero dejar estos usuarios solos y dejar que la UI predeterminada maneje las cosas
  2. Si el usuario permite la solicitud (tarde), el tiempo de espera puede dispararse antes de que la respuesta regrese - No creo que haya nada que puedas hacer al respecto
  3. El código anterior es solo un ejemplo ... necesita limpieza.
+0

gran solución, supongo que llenará el caso "faltante" en esa API. Tal vez lo extiendan también, todavía es un borrador y podría ser una retroalimentación importante (no para obligar al usuario a aceptar en lugar de administrar su sitio web). Muchas gracias por dedicarle tiempo, intentaré crear una solución estable de navegador;) – Maertz

+1

+1, solución muy elegante. – fmark

+1

@tetra Por favor, publique de nuevo un enlace a su solución crossbrowser estable cuando esté listo. – fmark

5

Es parte de la 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! "); 
    } 
}); 

Si especifica el errorCallback ... entonces usted puede realizar un seguimiento de si el usuario se ha negado a proporcionar acceso.

Posible error codes incluyen:

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

hi scunliffe, las funciones de devolución de llamada se llaman cuando el usuario acepta o deniega el permiso, pero necesito algo que me dé la respuesta cuando el usuario acepte la solicitud antes de que se active el tiempo de espera.Ese es mi problema, podría desencadenar la solicitud, pero el usuario podría ignorarla y nunca sabrá qué sucedió porque el tiempo de espera solo se dispara cuando el usuario aceptó la solicitud – Maertz

+0

@tetra - tal vez me falta algo en lo que está buscando. Cuando uso el código anterior ... Si NEGO la solicitud, se establece el código de error 'error.PERMISSION_DENIED' (valor de 1), así sé que el usuario lo rechazó. Si el usuario permite que se realice la llamada ... se activará y obtendrá los coords. – scunliffe

+0

@tetra - en realidad creo que sé lo que buscas ahora. (Estoy probando un código para lograr lo que necesita ...) – scunliffe

5

lo probó con éxito en 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'); 
} 

Con esa solución sabemos si la solicitud timedout, incluso cuando la devolución de llamada succeess/insuficiencia ser llamado después.

Cuestiones relacionadas