Catch html5 geolocation events - javascript

Is there a way to catch the html5 geolocation events?
Right now im using geolocator.js
and my problem is:
When the message pops up if i want to allow html5 locations if i accept it takes html5 location if I get ipLocation.
But I want to listen for these clicks so I can set a timeout if the user doesn't click for 10 seconds it automatically takes ip location.
Is there any way to get the event for "accept" and "decline"? Here is my code snippet for it
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(geoSuccess, geoError, html5Options);
} else { // not supported
fallback(new Error('geolocation is not supported.'));
}
EDIT: Im using Chrome on iMac
EDIT 2:
var html5Options = { enableHighAccuracy: true,timeout: 10000, maximumAge: 0 };
EDIT 3: using the solution by kravitz
if (navigator.geolocation) {
waitTooLong=setTimeout(geoError, 15000);
navigator.geolocation.getCurrentPosition(geoSuccess, geoError, html5Options);
} else { // not supported
fallback(new Error('geolocation is not supported.'));
}
function geoSuccess(position) {
clearTimeout(waitTooLong);
//doing my locationstuff
}
function geoError(error) {
//doing my locationstuff
clearTimeout(waitTooLong);
fallback(error);
}

var geoError = function(){
//get location failed so get manually by IP here
};
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(geoSuccess, geoError, html5Options);
} else { // not supported
fallback(new Error('geolocation is not supported.'));
}
Above should work but if you want to be really sure:
var timeOut = setTimeout(geoError, 10000);
var geoSuccess = function(){
clearTimeout(timeOut);
};

Related

Ios mobile doesn't ask geolocation permission

I'm trying to use the Google Maps API and get current location.
my page is being served over HTTPS.
I have no problems on Android devices. The browser wants location permission and I can get my location. But ios phone does not want access permission and gives location permission error.
is there anything i can do to ask for access permission for ios phone?
Here is my code
function findMyPlace() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition, showError, { timeout: 20000 });
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
//do something
}
In the documentation for getCurrentPosition over at MDN
you can see that getCurrentPosition() has an error callback. Apply the error callback and see what type of response you get. I've added a code-sample below.
function findMyPlace() {
if (window.navigator.geolocation) {
window.navigator.geolocation.getCurrentPosition( (position) => {
console.log(position.coords);
}, (e) => {
console.log(e);
});
} else {
console.log("navigator not supported");
}
}
findMyPlace();

Firefox WebExtension options page - How to save/restore preferences from storage.local?

I'll start my saying I'm a JavaScript newbie (I'm more of a Bash guy)...
I'm trying to create a Firefox WebExtension to disable the Ctrl+Q shortcut and play a sound when Ctrl+Q is pressed. I'd also like to have a user choose from a small list of sounds in an options menu. So far, all of that is working.
The only snag I'm hitting is when the user changes a sound and clicks "Save", the new sound isn't played on Ctrl+Q until the extension is reloaded.
Doing some Googling, I think the problem is related to the fact that storage API is asynchronous. From what I can gather, I need to use a callback to get the sound option after it is set. Is that not what I'm doing below? The option is set in options.js and then background.js plays the sound.
I'd appreciate any help.
options.js
// Saves options to browser.storage
function save_options() {
browser.storage.local.set({
favoriteSound: document.getElementById('CtrlQSound').value,
}, function() {
// Update status to let user know options were saved.
var status = document.getElementById('status');
status.textContent = 'Options saved.';
setTimeout(function() {
status.textContent = '';
}, 750);
});
};
// Restores select box state using the preferences stored in browser.storage
function restore_options() {
// Use default value sound = 'Sound0'
browser.storage.local.get({
favoriteSound: 'Sound0',
}, function(items) {
document.getElementById('CtrlQSound').value = items.favoriteSound;
});
};
document.addEventListener('DOMContentLoaded', restore_options);
document.getElementById('save').addEventListener('click', save_options);
background.js
browser.storage.local.get("favoriteSound", function(result) {
browser.commands.onCommand.addListener(function(SoundToggle) {
if (result.favoriteSound == "Sound0"){
new Audio("Sound0.ogg").play();
}
else if (result.favoriteSound == "Sound1"){
new Audio("Sound1.ogg").play();
}
else if (result.favoriteSound == "Sound2"){
new Audio("Sound2.ogg").play();
}
});
});
Firefox uses Promise objects, not callbacks. On a Promise, you can call "then" with a success and failure handler. Like this:
browser.storage.local.set({
favoriteSound: document.getElementById('CtrlQSound').value
}).then(onSuccess, onError);
function onSuccess() {
// Saving into storage.local succeeded
// Update status to let user know options were saved.
var status = document.getElementById('status');
status.textContent = 'Options saved.';
setTimeout(function() {
status.textContent = '';
}, 750);
function onError() {
// Saving into storage local failed.
// You might want to use a notification to display this error / warning to the user.
});
If you're developing for Chrome, you have to use callbacks. Or you could use "chrome." instead of "browser." if you want to use callbacks instead of Promises.

Geolocation for mobile devices

I have a problem with geolocation on idevices on my website.
Actually I just need to get latitude/longitude coordinates.
On PC, android devices everything is cool, on iphone it also fine but only if I use wifi connection. But when i'm on 3g or LTE with my old iPhone 5s I simply get nothing (but starting from iphone 6 it works).
I've read that Safari is not supporting geolocation if wifi is turned off.
But still what I need is to make it work on iDevices such as iPhone 4,5.
I'm using this piece of example code:
<script>
var x = document.getElementById("demo");
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
x.innerHTML = "Latitude: " + position.coords.latitude +
"<br>Longitude: " + position.coords.longitude;
}
</script>
I'm an iPhone 5S owner and tried the geolocation over 3G and it works like a charm. I've tried this CodePen over Wifi and over 3G without any issues.
$(document).ready(function(){
setInterval(function(){
getLocation(function(position) {
//do something cool with position
currentLat = position.coords.latitude;
currentLng = position.coords.longitude;
$("#status").html(currentLat + " " + currentLng);
});
}, 1000);
});
var GPSTimeout = 10; //init global var NOTE: I noticed that 10 gives me the quickest result but play around with this number to your own liking
//function to be called where you want the location with the callback(position)
function getLocation(callback) {
if (navigator.geolocation) {
var clickedTime = (new Date()).getTime(); //get the current time
GPSTimeout = 10; //reset the timeout just in case you call it more then once
ensurePosition(callback, clickedTime); //call recursive function to get position
}
return true;
}
//recursive position function
function ensurePosition(callback, timestamp) {
if (GPSTimeout < 6000) {
//call the geolocation function
navigator.geolocation.getCurrentPosition(
function(position) //on success
{
//if the timestamp that is returned minus the time that was set when called is greater then 0 the position is up to date
if (position.timestamp - timestamp >= 0) {
GPSTimeout = 10; //reset timeout just in case
callback(position); //call the callback function you created
} else //the gps that was returned is not current and needs to be refreshed
{
GPSTimeout += GPSTimeout; //increase the timeout by itself n*2
ensurePosition(callback, timestamp); //call itself to refresh
}
},
function() //error: gps failed so we will try again
{
GPSTimeout += GPSTimeout; //increase the timeout by itself n*2
ensurePosition(callback, timestamp); //call itself to try again
}, {
maximumAge: 0,
timeout: GPSTimeout
}
)
}
}
Thanks to Chris Beckett for the sample.
Maybe you can provide more details if you can't get it working yet?
Ps: just editing to make sure everyone who needs geolocation check if location services for Safari is enabled:
First check if Location Services is enabled under: Settings > Privacy > Location Services
Next check if it is enabled for Safari Websites

Disable button if geolocation is unavaliable

So i've got a main page where there's 3 buttons - login, register and recover account. I want to disable all those buttons and display a message when geolocation is unavaliable or the user has not allowed the browser to share it's location.
$scope.btnDisabled = false;
$scope.errorMsg = null;
$scope.checkBrowser = function () {
if (navigator.geolocation.getCurrentPosition) {
// let's find out where you are!
console.log("Got your location");
$scope.btnDisabled = false;
} else {
$scope.errorMsg = "Warning. Could not locate your position. Please enable your GPS device.";
//disable the buttons
$scope.btnDisabled = true;
//Show errorMessage
return true
}
//errorMessage visibility is set false
return false;
}
So far i haven't managed to disable the buttons or show errorMessage(except for an alert message).
This is how i got the alert message:
function getPosition() {
console.group("geoloc getPosition");
if (window.navigator) {
console.log("api supported");
navigator.geolocation.getCurrentPosition(success, error);
} else {
console.log("api fallback");
}
console.groupEnd();
}
function success(pos) {
console.log("geoloc pos ", pos);
}
function error(err) {
alert("Geolocation identification failed.");
$scope.btnDisabled = true;
}
Why doesn't the $scope.btnDisable work in error() function?
You should use
navigator.geolocation.getCurrentPosition(
function() {
$scope.btnDisabled=false;
$scope.$apply();
}, function() {
$scope.btnDisabled=true;
$scope.$apply();
}
});
It is verry important to know, that getCurrentPosition will call a callback instead of returning something! See https://developer.mozilla.org/en-US/docs/Web/API/Geolocation.getCurrentPosition
You've also to call $scope.$apply() as you'll disable any angular updates while processing non angular callbacks!
Do so in your 2nd example and the button state should get updated

HTML 5 Geolocation watchPosition

I am trying to set up my code to locate the most accurate position on a android phone or tablet. Since getCurrentPosition doesn't give enough time for the GPS to find a location, I am using the watchPosition. This works great but I need to allow the user to stop this watchPostion so I'm using the clearWatch function. This clearWatch function works on my android phone 2.2.2 version but not on the android tablet 3.2.1 version. My other issue is on my android phone, once I stop/clearwatch and I try locating my position again my phone vibrates and the browser closes. What is the issue here? I've tried this on other phones as well and have the same problem. If anyone has any suggestions I would greatly appreciate it. Below is the code I'm using.
//function to locate using GPS
function ShowMyLocation(){
if (navigator.geolocation) {
ShowProgressIndicator('map');
watchID = navigator.geolocation.watchPosition(function(position){
var mapPoint = esri.geometry.geographicToWebMercator(new esri.geometry.Point(position.coords.longitude, position.coords.latitude, new esri.SpatialReference({
wkid: 4326
})));
var graphicCollection = esri.geometry.geographicToWebMercator(new esri.geometry.Multipoint(new esri.SpatialReference({
wkid: 4326
})));
graphicCollection.addPoint(mapPoint);
geometryService.project([graphicCollection], map.spatialReference, function(newPointCollection){
HideProgressIndicator();
if (!map.getLayer(baseMapLayerCollection[0].Key).fullExtent.contains(mapPoint)) {
alert('Data not available for the specified address.');
return;
}
mapPoint = newPointCollection[0].getPoint(0);
AddServiceRequest(mapPoint);
});
}, function(error){
HideProgressIndicator();
switch (error.code) {
case error.TIMEOUT:
alert('Timeout');
break;
case error.POSITION_UNAVAILABLE:
alert('Position unavailable');
break;
case error.PERMISSION_DENIED:
alert('Permission denied');
break;
case error.UNKNOWN_ERROR:
alert('Unknown error');
break;
}
}, {
timeout: 5000,
maximumAge: 90000,
enableHighAccuracy: true
});
}
}
function clearWatch(){
// Cancel the updates when the user clicks a button.
if (watchID > 0) {
navigator.geolocation.clearWatch();
alert("Stop tracking location");
}
}
Your syntax is incorrect. clearWatch takes an argument of which watch ID to cancel.
In your case, you should have clearWatch(watchID), not clearWatch().

Categories