Accessing the GPS in iPhone Safari

Finally with the release of the 3.0 firmware update to the iPhone we now have access to the GPS coordinates in Safari. Using the W3C Geolocation API we can access the users position much the same way a native app would. The user can either allow or disallow the current websites’ access to your location.

This demo will need the iPhone 3G with the 3.0 firmware update or Firefox 3.5 in order to work. The iPhone will give the better results as it has access to the GPS where as Firefox depends on the hardware available.

Some hurdles

You may have noticed that I’m not using Google or Yahoo Maps APIs to plot my location, this is due to both having restrictions on using it in conjunction with real time locations. In Google Maps Terms of Use.

use the Service or Content with any products, systems, or applications for or in connection with (i) real time navigation or route guidance, including but not limited to turn-by-turn route guidance that is synchronized to the position of a user’s sensor-enabled device; or (ii) any systems or functions for automatic or autonomous control of vehicle behaviour.

Yahoo’s terms are a bit different they still restrict use of real time location abilities to be no younger than 6 hours, essentially making the safari’s location awareness a no go zone for these 2 services.

…use the Yahoo! Maps APIs with location information that is less than 6 hours old and derived from a GPS device or any other location sensing device;

CloudMade to the rescue

Thanks to CloudMade who is putting a rock solid set of tools and API’s in various languages so we can access the OpenStreetMap map data. Only difference is that these maps are created by the community and are licensed under the Creative Commons Attribution/ShareAlike licence, version 2 which means there are no such restrictions that we would of had with Google or Yahoo maps. I highly recommend you read where they are heading in terms of their licensing and help in giving back to their community by creating maps.

How it works

Now we have a maps API where we won’t be abusing the terms of use by using it in conjunction with real time locations. We’ll get stuck into how to use the W3C Geolocation API.

Request the users location

navigator.geolocation.getCurrentPosition(success, fail);

The above line will try to obtain the users current location using the getCurrentPosition method this can be passed up to 3 arguments; the success callback function, the error callback function and the position options: enableHighAccurracy, timeout & maximumAge.

Upon successfully obtaining the users location the success function will get passed the position object which will contain the coords and timestamp attributes. The coords attribute is the one we need to extract information about the user location and has the following properties available:

  • latitude
  • longitude
  • altitude
  • accuracy
  • altitudeAccuracy
  • heading
  • speed
navigator.geolocation.getCurrentPosition(success, fail);
// success callback, gets passed position object
success(position) // 'position' can be named anything
{
	alert("Your latitude: " + position.coords.latitude + "longitude: "
 		+ position.coords.longitude);
}

Not all of the geolocation information in the coords attribute is available to the iPhone, heading and speed currently return null but I suspect that both will be functional in the iPhone 3G S thanks to the compass and coreLocation updates. Both these attributes still return null on the iPhone 3GS which is surprising. Speed can alternatively be calculated by using the Haversine formula to obtain the distance travelled between two points which can then be used to compare time and distance to make a pretty accurate speed approximation.

The options available as the 3rd argument that can be passed to the getCurrentPosition method are:

  • enableHighAccuracy
  • timeout
  • maximumAge

These options can help in forcing the error callback and having a fallback option if the request cannot be obtained before the timeout ends or the location wasn’t obtained within the maximumAge set. enableHighAccuracy will force the GPS to get the most accurate results possible this will take longer and chew through the battery.

navigator.geolocation.getCurrentPosition(success, fail,{maximumAge: 300000, timeout:0});

Both maximumAge and timeout are expressed in milliseconds. This is basically saying get the last known location that is no older than 5 minutes, if no position is found timeout immediately and fire the error callback function.

Updating location

Getting the users initial location is great and all but what we really need is a way to get constant updates of any changes in the users’ location. Thankfully the geolocation API also has the watchPosition method which will fire upon a change in the users’ location.

var updateLocation = navigator.geolocation.watchPosition(success, fail);

This, like the getCurrentPosition method, takes the same arguments the only difference above is that I have stored the watchPosition method in a variable, this is so we can cancel it at anytime if we no longer need to watch for any changes in position.

navigator.geolocation.clearWatch(updateLocation);

This will cancel the watchPosition and stop it from firing the success or error callback. It works in much the same way the clearTimeout method works for the setTimeout method.

Handling errors

If something goes wrong with obtaining the users location e.g. the user decides not to share their location to your web app. We have the error callback so we can handle the situations that might occur and present useful actions or information back to the user.

The PositionError interface has 4 possible scenarios:

  • UNKNOWN_ERROR (code 0)
  • PERMISSION_DENIED (code 1)
  • POSITION_UNAVAILABLE (code 2)
  • TIMEOUT (code 3)

We have 2 attributes on the error callback available which are code & message these will return either the code number 0-3 or the message.

navigator.geolocation.getCurrentPosition(success, fail);
// fail callback, gets passed error object
fail(error) // 'error' can be named anything
{
	switch(error.code) // Returns 0-3
	{
		case 0:
			// Unknown error alert error message
			alert(error.message);
			break;

		case 1:
			// Permission denied alert error message
			alert(error.message);
			break;
		... etc
	}
}

Just the beginning

The iPhone 3.0 release isn’t the only browser to support Geolocation API, currently Firefox 3.5, Opera 10 beta and Opera Mobile 9.7 beta though this is speculation. I’m sure the other browser vendors will follow in their new releases.

Post filed under: javascript.

Skip to comment form.

  1. Nick says:

    I’m glad you’re enthusiastic about web development for mobile safari. We’re also really excited about the potential for safari and other mobile browsers. CloudMade’s Web Maps Lite library has some basic support for iPhone safari – we’re going to expand support in the near future. Please drop me an email if you’d like more info, or sign up to our developer list at lists.cloudmade.com

  2. Thanks for the sample code. We are planning on using this on one of our sites (ataxi.ro to show more relevant directory information to our customers.

    -Daniel

  3. katrina says:

    Thanks for the code! I’m using it now to develop a web app and it worked on the first go.

    After adding some other code to it, though, something went wrong and now when I try to access geolocation I get the code 1 error (User disallowed GeoLocation). Since then, I fixed my code and it works on other iphone’s and on my ipod touch…but still errors on my own iphone.

    I’ve reset everything on my iphone, did a complete restore, etc. and it still blocks me. Looks like it just blacklisted the domain my web app is on or something like that.

    Any suggestions how to fix this? Not finding much about it online.

    Thanks!

    • You’re welcome.

      If you go into settings > general > reset there will be an option in there to “Reset Location Warnings”. I haven’t yet tried it myself but from what people have said that fixes the problem you are having.

  4. Andrew Carter says:

    Thanks, this helps alot! Im having one issue though!
    I deliver pizzas for dominos, and wrote an app that let you record tips for the iphone. i now have it so it records the lat and lon when you add the tip, and at the end of the day it exports the data to google maps for a tip map sorta deal. every time you add a tip, it calls

    navigator.geolocation.getCurrentPosition(
    	success, 
    	fail,
    	{maximumAge: 3000, timeout:0,enableHighAccuracy:true}
    );
    

    The app adds the data to the database very quickly, and seems to be only using the cell tower location, and not be waiting for the actual gps results. What can i do to force it to wait for more accurate results?

  5. Andrew Carter says:

    oh, the actual call I’m using is:

    if (navigator.geolocation) {  
    	navigator.geolocation.getCurrentPosition(
    	function(position){
    		lat=position.coords.latitude;
    		lon= position.coords.longitude
    	}, 
    	function() {
    		alert('error');
    	}, 
    	{
    		enableHighAccuracy:true,
    		maximumAge:0, 
    		timeout:30000
    	}
    	);
    } else {
    	lat=0;
    	lon=0;
    }
    
    mydb.transaction(
        function (transaction) {
            transaction.executeSql(
    	"INSERT INTO tips (tip,milage,lat,lon) VALUES (?,?,?,?);",
    	[tip,mile,lat,lon]);
    	transaction.executeSql("UPDATE sync SET stops=?",[stops]);
        }
    );
    
    • The Css Ninja says:

      Great idea. As for getting the most accurate results, I would check the accuracy value in the coords attribute that will return how accurate it is in metres you could also check the timestamp attribute to see how old the position is in unix time. Although your example is looking for a position that is no older than 30 seconds so the timestamp should be in between that.

      if(position.coords.accuracy > 10) {
      	// If position is greater than 10m try again...
      	navigator.geolocation.getCurrentPosition();
      }
      

      Hope that helps. Let me know how you go.

  6. Doug R. says:

    Great stuff. One question, how do you force the iPhone/pod to update the location info? Every time I launch my app I get my last location, not the current one. The only way I found to refresh the data is to load the Google Maps (or Google Earth) app and have it get my location, then the location updates. In my code I have maximumage set to zero, I would think that would force a location update, it doesn’t. I have tried my app on two different iPhones and a Touch, same results. It seems to always return the cached position info. What am I missing??

    • I’m not entirely sure without seeing the JavaScript you’re doing, if you set the timeout option to 0 and in your error callback see what error message is getting displayed that should be able to help you. If you attach a watchPosition it should only fire on getting a fresh position, just add an alert in there so you know if your GPS is working or not.

      Also if you load up the demo and go for a walk or drive the watchPosition will update the map marker when the GPS gets fresh coordinates.

  7. yvan says:

    hey! Thanks for this page

    I have a weird problem tho:
    I tried to deny the access to my iphone’s GPS for my own website… well, now I cant get it back!

    I don’t have this problem with your live demo. If I deny it once, I just have to reload the page, and it works.

    Actually, I tried your code on my server… and it doesn’t work neither! Looks like my safari banned my IP for ever

    I reset my phone settings, etc… nothing works

    help me! ^_^’

    • Have you reset your location warnings as mentioned above? I tested that on my own demo. Denied the location request and then reset my location warnings. When I reloaded the page it asked me again to allow my location but it kept failing and falling back to the error handler (showing Apple HQ on the map). For some reason resetting my location took quite a while for it to flow back to safari and start working again. But it does work.

  8. yvan says:

    I’ve reset everything, again and again… I also did a complete restore..

    I tried all kind of voodoo stuff but nothing works. Seems that Safari put my server on a GPS black list for ever

    • Hmm that’s kind of odd, so it only happens on your server? If you visit my demo and deny access then reset your location warnings it starts working again?

  9. yvan says:

    Yes, for some reason, safari blacklisted my server only…

    I could eventually “solve” this problem : i had to restore the phone without using a saved configuration ( I lost all my contacts, pictures, and so on).

    So, be careful when you deny access to a website!

  10. katrina says:

    I posted a comment here back in July reporting the same problem with my iPhone blocking my server/domain after I denied it geolocation. Even after resetting location warnings, it wouldn’t work.

    The way I eventually got it to work was by restoring my phone back to a time before I initially denied location access for my site. This way I didn’t have to lose all my contacts, etc. After it was restored, it still blocked me. But I went in and reset location warnings again and it worked.

    I have no clue why I’d have to reset location warnings after doing a restore. Seems strange to me. But that worked.

    Hope this helps others so they don’t risk doing a complete restore and losing all their data!

  11. Olivier says:

    The licensing agreement from Google does not preclude the use of GPS, no? It just mentions the use of such technology in a turn-by-turn scenario.
    Thoughts?

    • It mentions turn by turn as an example but from their restrictions section:

      …including but not limited to turn-by-turn route guidance

      It’s not limited to turn by turn. I think it is better to be aware that these restrictions are in place before you were to use Google maps in such a way that it would violate their terms & conditions.

  12. Brian says:

    This works great. I was curious if you knew if there was a way to return the zip code closest to the GPS location?

    This would help me greatly hwoever, I have yet to figure out how to do it.

    • It’s currently not available in the geolocation API although Mozilla has added the address attribute to the position object in FF3.7 (minefield) for friendly name results from lat/lng.

      Cloudmade still haven’t released their reverse geocoding webservice so until then you could do a call to Google’s reverse geocoder that’ll return the closest address to the lat/lng provided and from there you could extract the zip/postal code from the address object.

  13. Brian says:

    Thanks for the info. Very helpful. I am now hitting an issue where I am trying to return only the zip code but it seems to keep pulling the full address up in a Google Map. I’m trying to figure out what I might be missing. Is there a special way to pass the lat & lon to get a Zip code returned?

    • You’re welcome. Yeah the address object will always return the full address so you’ll have to extract out the zip/postal code with a regexp, something like this should work:

      var address = "24 place st CA 95014",
      	zipcode = address.match(/d{5}/);
      

      Basically it will match any number that is 5 digits long. Hope that helps.

  14. Flemming says:

    I have also used the geolocation api on the iphone with success. One thing I was wondering though.

    I use the watchPosition and have that callback to a function that inserts the location in a database. Later when I call clearWatch() I want to show the route on GMaps. This works just fine. But if I am tracking my route and the phone automatically locks my screen (which I have set it to do after 3 minutes), the GPS stops making the callbacks until I unlock the screen on the iPhone again.

    Is there a way in the Iphone Geolocation API to force it to continue monitoring the GPS even while the screen is locked? If that is not possible is it then possible to prevent the iphone from locking the screen through javascript when my app is running?

    • @Flemming – Not that I am aware of, at least not with JavaScript. The Phone has a timer that will send the phone to sleep mode if it doesn’t detect any touches after a certain amount of time. I do have a crazy theory that hasn’t been tested nor do I guarantee it will work at all but it’s worth a try.

      If you setup a setInterval timer to set focus to a hidden checkbox every 10 seconds that could fool it into thinking it is being “touched”, it’s worth a try. Let me know how you go.

  15. bernhard says:

    The geolocation api works fine for me, but there is a big problem.

    The API does NOT use GPS to get my position. The accuracy is never below 50m. There also is no altitude available. This accuracy can be calculated using WLAN Stations or Cell Phone Transceivers.

    If I start the “build in map” an locate my position, GPS is working. The accuracy is < 20m.

    If I switch to my webapp very quickly after using the built in map the accuracy is ok and I also get the altitude. But after 10 seconds I have the bad accuracy again.

    At my iPhone the enableHighaccuracy option is definitly ignored.

    No GPS from javascript!!!

    • I have tested the demo while on the move and it updates my location pretty accurately although I am not ouputing the accuracy attribute so I don’t know the exact accuracy figure.

      I did create a bookmarklet that will alert you current lat/lng/accuracy. Find my location.

      The geolocation spec is not purely about using a gps to get your location it uses the best available information it has to work with, whether that be gps, cell towers or ip address.

  16. Flemming says:

    I use the geolocation API on my iphone (3G). If I’m inside a building I won’t be getting locations more accurate than about 2-300m – and most times even much worse that – usually when I test my app indoors I get accuracy of about 1800m :-/

    However, as soon as I’m outside and have clear line of sight to the sky I don’t have problems getting accuracy of about 14m and sometimes as low as 7m.

    I too have set the highAccuracy option to true, but I’m not sure it does much more than poll more often. What is important though is setting the maximumAge property to a very low value – otherwise the phones api may return cached coordinates rather than actually polling the gps in the phone. This will probably also increase battery consumption.

  17. Jeff says:

    Seems to work pretty well. This is a great intro to the geolocation API, thanks Ninja! :)

    I’m working with a 3GS, and I’m getting values for heading and speed, but only while actually moving. Anyone know what the units are for those? While traveling on the freeway around 65mph, speed returned 29.220444444444446 and heading returned 358 (I’m assuming that’s degrees, so I was heading almost due north).

    I’ve linked to a screenshot.

    • @Jeff – Thanks for your comment Jeff.

      Interesting all my testing I did I always got null for speed and heading must only register those values once you are at a certain speed. Do you get heading values when you’re stationary?

  18. Jeff says:

    Oh! I’ve answered my own question. Speed returns meters per second.

  19. Jeff says:

    No I haven’t gotten heading values while stationary, but I have gotten 0 for speed while sitting in the office.

    Altitude also seems to like movement. I’m close to sea level, and while the actual altitude value comes back at what I’m assuming is pretty close, I don’t think I’ve seen altitudeAccuracy get below 70 meters. That’s a big range.

    …and @Flemming: you can set your iPhone to never auto lock in Settings>General>Auto Lock, however, if you are synching with an Exchange server your sysadmin can disable the never option. If you turn off your Exchange account, you’ll see the option for never appear.

    • @Jeff – When I wrote this article I was using the 3.0 beta firmware perhaps they have since updated it to return values for speed and heading? I would imagine you would need the 3GS for heading to work because of the internal compass. Will have to try speed and heading next time I’m in a car.

  20. Jeff says:

    Quite possible, I’m running 3.1 (the current firmware).

  21. Jeff says:

    A buddy of mine just tested out my code for me on his 3G and it was returning the heading, so it’s NOT 3GS specific. He said that it wouldn’t really give him values unless he was over about 30mph (48kph). He was also using the latest firmware (3.1).

  22. @Jeff – Just did some testing, a quick data dump with the coords attribute. Ran it while I was walking down the street and was getting speed and heading results with the speed reading as low as 2km/h (meters * 3.6 to get a rough km/h). So looks like it’s getting pretty good results even at low speeds all it needs is a clear view of the sky to get these results.

  23. Rvhoss says:

    This is incredible.

    I have a list of Zip codes.

    Can I display these zip codes on the map if they are within x miles (within view)?

    Do you know a way to:
    – converting the zips to longitude and latitude
    – displaying them on the map
    – plotting my location

    Thoughts?

  24. Rvhoss says:

    Thanks for the quick response. I looked and wanted to get your thoughts on if I am approaching it right.

    I have a data base of addresses
    I should
    1) plot the user first and then plot nearby locations or
    2) plot my database of locations and then show the user where they are

    any advice you can give would be great.

    • If you’re only interested in plotting nearby locations from your db of address’ then option 1 would be the better approach. You’ll need the users location initially anyway to work out which of the address’ are nearby.

  25. Jonathan says:

    did you notice that very large marker images are not displayed centered, but with the center being the lower left corner.

  26. GaelicWA says:

    I am using the PhoneGap API system with my iPhone web app but am running into a problem. At the moment, I have the iPhone getting the GPS co-ordinates which I am then using to open Google Maps and plot the location on the screen.

    What I seem to be encountering is that the GPS seems to need a good 30 seconds to get a good lock on. I believe the API can not only ‘navigator.geolocation.getCurrentPosition’ but use a function similar to Google Maps when it can follow the user. This would obviously solve my problem as it keeps refreshing the location, hence me being able to get a better GPS location lock.

    Can anyone advise on how to edit my code (see below) to get this running. You help is appreciated.

    function mapLocation(event)
    {
        navigator.geolocation.getCurrentPosition(
            success, 
            fail,
            {
                enableHighAccuracy: true, 
                maximumAge: 1, 
                timeout:10000
            }
        );
        function success(position) {
            var lat = position.coords.latitude;
            var long = position.coords.longitude;
            javascript:location.href = 
            "http://maps.google.com/maps?geocode=&q="+lat+","+long;
        }
         
        function fail() {
            alert('Could not find location');
        }
    }
    
    • I’m pretty sure the PhoneGap API emulates that of the Geolocation API so the syntax and methods available should match. If you want to be constantly updated with new lat/lng points you can use the watchPosition method which will fire everytime the location changes. Position acquiring can take some time if you’re not standing somewhere with a clear line of sight to any of the satellites also.

  27. Eric says:

    Hi!Excuse me …I have a question

    My iPhone 3G is 3.0(7A341),but why it couldn’t display the location information?

    thank you!

  28. Paris says:

    Do you know if Google Maps Premiere allows the use of this method?

  29. FRANCK says:

    Bonjour,
    I have one question.
    i am sure that i am at coord 48.61304,002.4573 multiple test with other gps and googlemap.
    but safari tel me that i am at 48.6144,002.5052 when i try to print on googlemap i have 500 meters error ?
    Anyone have an idea?

  30. Elegantchaos says:

    I like answering my own questions as well when asking them.
    This is a great article and this is awesome work. I hope to test this soon.
    I knew this should be possible so thanks for answering my delayed question. I saw the layers added perfectly as I read. Great stuff
    I started wondering about ip location over 3G and if it was GPS enhanced or many variants of the ips location. But why bother when you add layers and cut the chase and made the cake
    Cheers and much apperciation for the work

  31. koyetsu says:

    Ok, so pulling the gps location isn’t hard…what i can’t seem to find, anywhere is example code of how in the heck you turn it into a city/state location. i don’t wanna map all i need is a fricken plain text “New York City, NY” dropped into a text box. and i can’t seem to find anything like that anywhere. if someone can help me out i would appreciate it. i’m sure it has to do with reverse geocoding but about half the sites i found on that don’t work and the rest don’t work either! hehe.
    Let me know if you can point me at a resource or have sample code to share.

    koyetsu AT yahoo DOT com

  32. Idiot says:

    I do not have an iPhone, so I am going on faith here. I assume that the latitude and longitude are returned in decimal format?

    As you know, there are three different GPS formats: decimal (45.758759), degrees-minutes (N 19° 38.416), and degrees-minutes-seconds (N 19° 38′ 13”).

    If the return values of the coordinates are not in decimal format, please let us know. Thanks!

    • @Idiot –

      Any browser that says they support the geolocation API will abide by the specification which states:

      The latitude and longitude attributes are geographic coordinates specified in decimal degrees.

      So it should always supply the coordinates in decimal degrees. Trying to work with any other format would be a nightmare in javascript.

  33. cam says:

    Would it be possible to write a small app that gets gps periodically. Lets say every 5 minutes and then writes a file to the iphone with the coordinates. Could this easily be done in javascript or jquery?

    • @cam – You could call the getCurrentPosition using the setInterval method and set it to fire every 5mins(300000ms) and then save the position using localStorage e.g.

      navigator.geolocation.getCurrentPosition(success, fail);
      
      function success(pos) {
          // Do something with position
          
          // Store position in localStrorage
          window.localStorage.setItem("coords", 
          [pos.coords.latitude,pos.coords.longitude]);
      
          var getPositionInterval = window.setInterval(
              "navigator.geolocation.getCurrentPosition(success, fail)",
               300000);
      }
      
  34. bill patton says:

    thanks to this (and some other) great tutorials i’ve got my web app running – however i’m curious about how to control the ‘time out’ value of the browser. Once the iPhone goes to sleep it stops sending position and location. Can this be controlled?

    -bill

    • @Bill P – If you’re wanting the watchPosition function to keep updating the users location even when the phone is asleep I think you’re out of luck. Not only would that be a serious privacy issue but also a serious battery drain.

  35. Flemming says:

    @Bill P – I agree with CSS Ninja – unfortunately this cannot be done through the Javascript API. The only way to keep getting position updates in Safari via the JS API is to manually disable the sleep setting in the iphone.

    If you are writing a native app, you can however work around this “problem” by doing something like this:

    – (void)applicationDidFinishLaunching:(UIApplication *)application {

    application.idleTimerDisabled = YES;
    [window addSubview:[rootViewController view]];
    [window makeKeyAndVisible];
    }

    But this API is not exposed via Javascript, so that can only be done in native apps. I wrote a hybdid app that almost had no native code other than the code above to disable the sleep timer – the rest of my application was written using the javascript API.

    As CSS Ninja says when you disable the idleTimer it will lead to serious battery drain, because not only will the GPS keep updating, the screen will also be on maximum brightness, the accelerometer will keep updating etc. etc. It would be nice if I could just turn on GPS updates and let the rest of the hardware go into sleep as usual.

  36. Billp says:

    Thanks for the reply on timeout. I’m resigned to requiring my users to set auto lock to never and to reduce screen brightness.
    I’ve got a live demo that stores path info running at logsitall.com/geo/geo-second.asp – feedback would be welcome.

  37. Oh wise Ninja Sir

    I’m working on this iphone webapp to help educate our fire departments who set up Night time landing zones for us when we need to land we have to have them at night to land. So we wanted to create a nifty tool for them and to help us get out education easier. Anyway I’m by no means a JS savy person even though I’m learning. All I want to do in this app is show the coordinates of their current position and I”m having trouble making it work. Any chance you can post just simple script to call the location and then to how to document write them into a div.

    Thanks ahead of time

  38. Is there an easy way to call the coords as deg min sec or do we have to do the math. I’ve been looking at examples but any changes i make to the current script causes it to fail (not sure why).. example if i add the enableHighAccuracy: it stops working… but my main issue is I must have them as deg min and sec.

    navigator.geolocation.watchPosition(
        function (position) {
            var lat=position.coords.latitude;
            var long=position.coords.longitude;
            var accur=position.coords.accuracy;
            document.getElementById('location').innerHTML=
                'Your current location is:' + '' + 'Lat: ' +lat + '' + 
                'Long: ' +long + '' + 'Accuracy: ' +accur + 
                ' meters' + '';
        },
        function(error) {
            alert('Sorry, could not find you... error code: '+error.code);
        });
    

    thanks again “Wise Ninja”

  39. krycek says:

    You don’t have to have the newest mobile phone to use GPS and Geolocation API. Almost every mobile browser (without proxy server) can be used to read position from buidin GPS. If You have Java and GPS in Your phone – You can use mobile-gps-web-gate – see at http://code.google.com/p/mobile-gps-web-gate/

  40. Hey All and especially Ninja,

    navigator.geolocation.getCurrentPosition(success, fail);

    This call is very slow and may sometimes fail on Safari. Works pretty well on Chrome, Firefox and Opera.

    Do you know anything about this?

    Lakeside

    • There can be many factors why it could be slow. Set a timeout value so say after 3 seconds it will trigger the error callback and in the callback you can trigger the getPosition call again e.g.

      navigator.geolocation.getCurrentPosition(success, fail,
          {timeout: 3000});
      
      function fail(e) {
          // Try again
          if(e.TIMEOUT) {
             navigator.geolocation.getCurrentPosition(success, fail,
                {timeout: 3000});
          } else {
              // Failed for some other reason
          }
      }
      
  41. Emmanuel Garcia says:

    When I use the “View a live demo” button from my iPhone 3Gs, I get the Apple Inc.’s headquarters shown, not my current location. Any suggestions?

    • @Emmanuel G
      Does the demo prompt you for GPS access? If not you may either have location services turned off for Safari. Settings > General > Location Services, make sure that toggle switch is on. Another reason why it might not be working is if you have denied access to the request before. You’ll possibly need to reset location warnings to get prompted again, Settings > General > Reset.

  42. Victor says:

    Hi!

    I am facing a problem with the geolocation API which I hope you might be able to help me with.

    Some of people here commented that when denying the access to the position on the prompt, the geolocation got “blocked” and it became necessary to reset the location warnings on the iphone in order to make it to work again.

    Well, in my case the thing is that even if I restart the location warning, when I call the getCurrentLocation I always get the error 1 (User denied location) even though I haven´t said anything… Has anyone faced the same problem and still continued after restarted the location warnings?

    Thanks so much for your help in advance.

    Cheers, Victor

    • Ryan Seddon says:

      @Victor

      If you navigate to settings > general > reset and tap Reset Location Warnings that should fix your problem. Make sure to kill safari too just to make sure it boots up a new instance.

  43. @RB says:

    Same problem here as Victor. Choosing Deny on the “…would like to use your location…” popup pretty much permanently disables geoLocation. Even if I use Settings -> General -> Reset Location Warnings, yes the popup asking if I want to allow Safari to use my location does in fact popup, but afterwards, the getCurrentPostion call ALWAYS fails with code: 1 message “User denied GeoLocation”, even if I select Allow. This has most certainly got to be a bug in the geo location service of the phone. The same app and code based pushed to a staging site works perfectly fine on chrome and safari browsers, as well as the iPhone Emulator from XCode. These all allow you to simply clear the cache and reload the site and have the geoLocation work fine.

  44. andy leontovich says:

    Hi. Is there a way to suppress the dialog that asks if my page would like to use your current location? I’m using jQueryMobile and would like to show my own dialog.

    Thanks!

  45. Daniel says:

    Hey,

    I’m having the same problem as some of you guys. Even though I approve the popup asking if my website is allowed to use my position date I always get a “User denied Geolocation” error. I tried resetting location warnings, cache, cookies etc. but nothing helps.

    Has anybody found a solution for this without having to reset the whole phone?

    // Daniel

  46. Deepwinter says:

    Awesome, very useful article and one of the few places that draws attention to the advanced options for the geolocation API.

  47. Mik Muller says:

    Awesome. Looking for help getting the GPS info into two hidden form fields so the x y info will be posted with the form. JS function should continually update every few seconds to get the most accurate info. Easy?

  48. Mik Muller says:

    Got that part to work, however the GPS locations are literally all over the map. I just tried mapping a river and five out of seven location captures put me outside the river, with a couple of those being a mile away! Ugh. Any way to get more accurate GPS info?