I got strange behavior when I tried to test my
"navigator.geolocation.getCurrentPosition" web page. Here is my
testing result and code:
my code:
function detectLocation()
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(geocodePosition, onError, { timeout: 30000 });
navigator.geolocation.watchPosition(watchGeocodePosition);
}
else
{
onError();
}
}
this function was run when "body" onload event was called. I had tried to change the timeout to 10000 and 20000, but I still got same result. I also allowed crome and firefox to get my location.
result:
Using chrome (v 17.0.963.79 m), result always went to onError
function when navigator.geolocation.getCurrentPosition was called.
Using Firefox (v 10.0.2), result always went to onError function
when navigator.geolocation.getCurrentPosition was called.
Using IE (v 9), result was fantastic, I got my current location.
can anyone help me in this strange situation? I really didn't have any idea to solve this problem and I was in hurry on my project deadline. Thanks before.
EDIT :
For this couple days I got some progress, the error code code is 2 with a message "Network location provider at 'https://maps.googleapis.com/maps/api/browserlocation/json?browser=chromium&sensor=true' : Response was malformed". Still unsolved, does anyone know how to solve this?
I simulated this problem and found that the success callback functions were only called when the html page was hosted on a web server and not when opened from a filesystem.
To test I opened the file directly from my C: drive and it the callbacks didn't work and then hosted the file on Internet Information Services (IIS) and the callbacks did work.
<html>
<body onload="detectLocation()">
<!-- This html must be hosted on a server for navigator.geolocation callbacks to work -->
<div id="status"></div>
<script type="text/javascript">
function detectLocation()
{
log("detectLocation() starting");
if (navigator.geolocation)
{
log("navigator.geolocation is supported");
navigator.geolocation.getCurrentPosition(geocodePosition, onError, { timeout: 30000 });
navigator.geolocation.watchPosition(watchGeocodePosition);
}
else
{
log("navigator.geolocation not supported");
}
}
function geocodePosition(){
log("geocodePosition() starting");
}
function watchGeocodePosition(){
log("watchGeocodePosition() starting");
}
function onError(error){
log("error " + error.code);
}
function log(msg){
document.getElementById("status").innerHTML = new Date() + " :: " + msg + "<br/>" + document.getElementById("status").innerHTML;
}
</script>
</body>
</html>
I also got this message:
message: "Network location provider at 'https://www.googleapis.com/' : Returned error code 404.", code: 2
I could solve it by switching on my wifi adapter
I had the same issue. Chrome browser wan not returning a position on 30000 miliseconds timeout. Firefox was not returning a position too. I added the option enableHighAccuracy and set it to false but nothing changed(false is the default option). When i change it to true then geolocation started working!
This is my final code,
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function(position) {
// Get current cordinates.
positionCords = {"lat": position.coords.latitude, "lng": position.coords.longitude};
},
function(error) {
// On error code..
},
{timeout: 30000, enableHighAccuracy: true, maximumAge: 75000}
);
}
You need to be using https, not http.
The Chrome reference for this is here - https://developers.google.com/web/updates/2016/04/geolocation-on-secure-contexts-only
I know this is old topic but recently I had this error also:
message: "Network location provider at 'https://www.googleapis.com/' : Returned error code 404.", code: 2
The fix is to get api key for google maps and use it in your code
<script src='https://maps.googleapis.com/maps/api/jscallback=initMap
&signed_in=true&key=YOUR-API-KEY' async defer></script>
Here you can get API KEY: https://developers.google.com/maps/documentation/javascript/get-api-key#key
I had same issue and solution was to increase the timeout duration as mobile network are slower than wired network
{timeout: 30000, enableHighAccuracy: true, maximumAge: 75000}
along with enabling cellular positioning
In the Device Settings turn on "Wifi and Cellular positioning" option.
This will print the Latitude and Longitude of your Location
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script>
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
alert("Geolocation is not supported by this browser.");
}
}
function showPosition(position) {
document.getElementById('idLatitude').value = position.coords.latitude;
document.getElementById('idLongitude').value = position.coords.longitude;
}
</script>
</head>
<body onload="getLocation()">
<form action="HelloWorld" method="post">
<input id="idLatitude" type="text" name="strLatitude">
<input id="idLongitude" type="text" name="strLongitude">
</form>
</body>
</html>
Related
I am using the code to get the geo-location on my site. for example
https://subdomain.domain.com/pwa
<script type = "text/javascript">
function showLocation(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
alert("Latitude : " + latitude + " Longitude: " + longitude);
}
function errorHandler(err) {
if(err.code == 1) {
alert("Error: Access is denied!");
} else if( err.code == 2) {
alert("Error: Position is unavailable!");
}
}
function getLocation() {
if(navigator.geolocation) {
// timeout at 60000 milliseconds (60 seconds)
var options = {timeout:60000};
navigator.geolocation.getCurrentPosition(showLocation, errorHandler, options);
} else {
alert("Sorry, browser does not support geolocation!");
}
}
</script>
<form>
<input type = "button" onclick = "getLocation();" value = "Get Location"/>
</form>
I added the above code in geoWatch.html.
when I visit the page and click on - get location. I am prompted to allow for - Geolocation, which I accept and I can see the same in settings for website the geolocation is allowed.
but immediately after I click on accept the allow notification - I get the error alert - Error: Access is denied.
I remember it was working fine, what and where I messed up, can't figure out what went wrong, so I took this sample code and put this both in pwa folder as well as in the root of the site to test, if any other code is conflicting, but it didn't helped.
Additional Note:
I installed chrome canary and there it(same code) is working fine.
Edit: Even Chrome Canary worked for the first try only. any subsequent try getting same error.
but Samsung Mobile browser working fine even after multiple tries.
I have a specific issue with the Geolocation api. This is my scenario:
User landed on a page ( in Chrome - Android ) with GPS location disabled.
There is a button on the page, and onClick of the button triggers the Geolocation.getCurrentPosition
Geolocation goes to the error callback with error message “User denied Geolocation”
User goes to Android settings ( mostly in notification drawer ) and turn on the location
User click the button again ( at this time, location is available ) to get the coordinates
However, Geolocation api still throws the error “User denied Geolocation”
—
At this time, the geolocation request will work only if the user refreshes the page and press the button ( note: the location is still enabled )
Is there a way to make this work without the browser refresh ?
Here is the jsbin link: https://output.jsbin.com/pihenud
Finally, I was able to solve this problem using an iFrame hack.
Here is the solution:
Instead of asking the permission in the main window, create an iFrame dynamically and call the geolocation.getCurrentPosition inside it. Now, we can use the window.postMessage to pass the position data to the parent browser window.
When we have to retry the geolocation request again, we just need to reload the iframe -- This will have the new site settings.
Here is the iframe code if anyone wants to try:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Namshi Geolocation</title>
</head>
<body>
<script type="text/javascript">
var sendMessage = function(result){
window.postMessage(JSON.stringify(result), window.location.origin);
};
var triggerGeolocationRequest = function(){
var options = {
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 0
};
var result;
if(window.navigator.geolocation){
window.navigator.geolocation.getCurrentPosition(function(position){
var result = {
type: 'success',
data: {lat: position.coords.latitude, lng: position.coords.longitude}
};
sendMessage(result);
}, function(err){
var result = {
type: 'error',
data: { message: err.message, code: err.code }
};
sendMessage(result);
}, options)
} else {
result = {
type: 'error',
data: { message: 'No Geolocation API' }
};
sendMessage(result);
}
};
window.addEventListener('load', triggerGeolocationRequest);
</script>
</body>
</html>
And in your application code, you can have a utility to inject the iFrame. See the below code:
utils.getCurrentPosition = function(){
return new Promise(function(resolve, reject){
var ifr = document.createElement('iframe');
ifr.style.opacity = '0';
ifr.style.pointerEvents = 'none';
ifr.src = location.origin + '/geo.html'; // the previous html code.
document.body.appendChild(ifr);
ifr.contentWindow.addEventListener('message', function(message){
message = JSON.parse(message.data);
if(message.type === 'success'){
resolve(message.data);
} else {
reject(message.data);
}
document.body.removeChild(ifr);
});
});
};
Edit - I plotted the reuslt using mapcustomizer
I took the code from these geolocation docs, hooked up my phone and went around the block:
Here's the code (barely modified from this geoloc tutorial page):
<!DOCTYPE html>
<html>
<head>
<title>Device Properties Example</title>
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script type="text/javascript" charset="utf-8">
// Wait for device API libraries to load
//
// document.addEventListener("deviceready", onDeviceReady, false);
var watchID = null;
// device APIs are available
//
function onDeviceReady() {
// Get the most accurate position updates available on the
// device.
var options = { maximumAge: 3000, timeout: 10000, enableHighAccuracy: true };
navigator.geolocation.getCurrentPosition(onSuccess, onError, options);
}
// onSuccess Geolocation
//
function onSuccess(position) {
var element = document.getElementById('geolocation');
element.innerHTML = position.coords.latitude + ',' + position.coords.longitude +
'<hr />' + element.innerHTML;
}
// clear the watch that was started earlier
//
function clearWatch() {
alert('STOPPING!');
if (watchID != null) {
navigator.geolocation.clearWatch(watchID);
watchID = null;
}
}
// onError Callback receives a PositionError object
//
function onError(error) {
var element = document.getElementById('geolocation');
element.innerHTML = '<h1 style="color:red;">ERRORED!</h1>' +
'<hr />' + element.innerHTML;
}
</script>
</head>
<body>
<button onclick="clearInterval(intervalio);alert('I WIN', 'SHOULD HAVE STOPPED')" style="color:red;font-size:25px;">STOP RECORDING YOU TARD</button>
<script type="text/javascript">
intervalio = setInterval(function() {
onDeviceReady();
}, 1000);
</script>
<p id="geolocation">Watching geolocation...</p>
<button onclick="ondeviceReady();" style="color:green;font-size:25px;">STOP YOU IDIOT</button>
</body>
</html>
tl;dr I used a setInterval and clearInterval on my own instead of using the example; I'd prefer to have used .watchPosition and .clearWatch, but to my surprise .watchPosition returns undefined and therefore I can't stop it that way.
Questions:
With the interval of 1000ms, the entire route (I was going like 10-20 mph like a responsible citizen) should be LITTERED with endpoints. Instead, my house is full of tags but the rest of the route is sparse.
Is it because I lost WiFi connectivity? How does a router know my position in 3D? Do the options I've specified:
var options = { maximumAge: 3000, timeout: 10000, enableHighAccuracy: true };
Have something to do with the few points I'm seeing there? Does the GPS satellite have some kind of a ping with which it gets back to one's phone?
I discovered this strange behavior with the web application that I am developing using html5's geolocation API. The problem only occurs if the website is bookmarked and then run in the full screen mode on the iPad using
<meta name="apple-mobile-web-app-capable" content="yes" />
in the header.
The code I am using:
function getLocation() {
if (navigator.geolocation) {
alert("No problem up to here");
navigator.geolocation.getCurrentPosition(showPosition, noLocation, { timeout: 10000 });
}
else {
alert("Geolocation is not supported by this browser.");
}
}
function showPosition(position) {
alert("position: " + position.coords.latitude + ', ' + position.coords.longitude);
}
function noLocation(error) {
alert("error.code:" + error.code);
}
And then I am calling getLocation() from another function:
timer = window.setInterval(function () { getLocation() }, 10000);
(and yes, I already have declared timer)
I used the word "choke" because I can see "No problem up to here" alert every 10 seconds, the "position:" alert just once, and after then neither of the "position:" or "error.code:" alerts are showing up.
Any ideas why this is happening?
I use easyXDM to make cross-domain POST request and receive a response. When the request reaches a timeout, easyXDM executes the ErrorHandler function twice when I run it on Firefox. On Chrome and IE7 it works fine (i.e. just one execution). Why is that? Any ideas how can I prevent it?
Firefox version 6.0.2
EasyXDM version 2.4.15.118
Hosted on IIS
Example code (this works as described above on my computer, the "Error" alert appears twice on Firefox and once on Chrome and IE7): (obviously, the timeout is set so low so that it would always happen)
<html>
<head>
<script type="text/javascript" src="easyXDM.js"></script>
<script type="text/javascript">
var rpc = new easyXDM.Rpc({
remote: "http://myserver.com/Cors.html"
}, {
remote: {
request: {}
}
});
request = {
url: "http://myserver.com/DoSomething.aspx",
method: "POST",
timeout: 1,
data: {
SomeData: "SomeInformation"
}
};
var responseHandler = function(response) {
alert("Responded");
};
var errorHandler = function(error) {
alert("Error");
};
rpc.request(request, responseHandler, errorHandler);
</script>
</head>
<body>
</body>
This was fixed in https://github.com/oyvindkinsey/easyXDM/commit/c6da9f074606f153769d8be61aca804a02a7acb9
based on the discussion in https://groups.google.com/forum/#!topic/easyxdm/DI470RVe8hk