Firefox 3.5 and later support the Geolocation API; this allows the user to provide their location to web applications if they so desire. For privacy reasons, the user is asked to confirm permission to report location information.
Firefox 3.5 includes support for locating you based on your WiFi information using Google Location Services. In the transaction between Firefox 3.5 and Google, data is exchanged including WiFi Access Point data, an access token (similar to a 2 week cookie), and the user's IP address. For more information, please check out Mozilla's Privacy Policy and Google's Privacy Policy covering how this data can be used. Also see the source code if you're curious how this service is implemented.
nsIGeolocationProvider
. You may also find the WiFi access point monitoring service interesting.Firefox 3.6 (Gecko 1.9.2) added support for using the GPSD (GPS daemon) service for geolocation on Linux.
The geolocation object
The geolocation API is published through a geolocation
child object within the navigator
object. If the object exists, geolocation services are available. You can test for the presence of geolocation thusly:
if ("geolocation" in navigator) { /* geolocation is available */ } else { alert("I'm sorry, but geolocation services are not supported by your browser."); }
Starting in Gecko 1.9.2 (Firefox 3.6), add-ons can obtain the geolocation object by obtaining a reference to the geolocation service like this:
var geolocation = Components.classes["@mozilla.org/geolocation;1"] .getService(Components.interfaces.nsISupports);
Getting the current position
To obtain the user's current location, you can call the getCurrentPosition()
method. This initiates an asynchronous request to detect the user's position, and queries the positioning hardware to get up-to-date information. When the position is determined, a specified callback routine is executed. You can optionally provide a second callback to be executed if an error occurs. A third, optional, parameter is an options interface where you can set the maximum age of the position returned and the time to wait for a request.
Use getCurrentPosition()
if you want a single position fix ASAP, regardless of the accuracy. Devices with a GPS, for example, can take a minute or more to get a GPS fix, so less accurate data (IP location or wifi) may be returned to getCurrentPosition()
to start.
navigator.geolocation.getCurrentPosition(function(position) { do_something(position.coords.latitude, position.coords.longitude); });
The above example will cause the do_something()
function to execute when the location is obtained.
Watching the current position
If the position data changes (either by device movement or if more accurate geo information arrives) , you can set up a callback that is called with that updated position information. This is done using the watchPosition()
function, which has the same input parameters as getCurrentPosition()
. Its callback is called multiple times, allowing the browser to either update your location as you move, or provide a more accurate location as different techniques are used to geolocate you. The error callback, which is optional just as it is for getCurrentPosition()
, is called only once, if there will never be valid results returned.
You can use watchPosition()
without an initial getCurrentPosition()
call.
var watchID = navigator.geolocation.watchPosition(function(position) { do_something(position.coords.latitude, position.coords.longitude); } );
The watchPosition()
method returns an ID number that can be used to uniquely identify the requested position watcher; you use this value in tandem with the clearWatch()
method to stop watching the user's location.
navigator.geolocation.clearWatch(watchID);
watchPosition()
accepts a success callback and error callback (like getCurrentPosition
) and an optional positionObjects
object, which can have three properties:
enableHighAccuracy
– A boolean which indicates to the device that you wish to obtain it’s most accurate readings (this parameter may or may not make a difference, depending on your hardware)maximumAge
– The maximum age (in milliseconds) of the reading (this is appropriate as the device may cache readings to save power and/or bandwidth)timeout
– The maximum time (in milliseconds) for which you are prepared to allow the device to try to obtain a Geo location
A call to watchPosition could look like:
var wpid = navigator.geolocation.watchPosition(geo_success, geo_error, {enableHighAccuracy:true, maximumAge:30000, timeout:27000});
A demo of watchPosition in use: https://www.thedotproduct.org/experiments/geo/
Describing a position
The user's location is described using a Position object, which has the following fields:
- timestamp
-
The time at which the reading was taken, as a
DOMTimeStamp
. - coords
-
An
nsIDOMGeoPositionCoords
object indicating the location. - address Obsolete since Gecko 14.0
-
An
nsIDOMGeoPositionAddress
object specifying the corresponding address, if available.
Handling errors
The error callback, if provided when calling getCurrentPosition()
or watchPosition()
, has the following signature:
function errorCallback(PositionError error);
The PositionError
structure has the following fields:
- code
- A numeric error code which much be one of the following:
-
UNKNOWN_ERROR
(numeric value 0) - The location acquisition process failed due to an error not covered by the definition of any other error code in this interface.
-
PERMISSION_DENIED
(numeric value 1) - The location acquisition process failed because the application origin does not have permission to use the Geolocation API.
-
POSITION_UNAVAILABLE
(numeric value 2) - The position of the device could not be determined. One or more of the location providers used in the location acquisition process reported an internal error that caused the process to fail entirely.
-
TIMEOUT
(numeric value 3) - The specified maximum length of time has elapsed before the implementation could successfully acquire a new Position object.
- message
- A human readable error message, suitable for use in logs and debugging -- but not for display to the user.
Browser compatibility
Browser | Basic support | Geolocation Level 2 |
---|---|---|
Internet Explorer | IE9 RC | --- |
Firefox (Gecko) | 3.5 (1.9.1) | --- |
Opera | 10.60 | --- |
Safari | Chrome | WebKit | 5 | 5 | 533 | --- |
Prompting for permission
Any add-on hosted on addons.mozilla.org which makes use of geolocation data must explicitly request permission before doing so. The following function will request permission in a manner similar to the automatic prompt displayed for web pages. The user's response will be saved in the preference specified by the pref
parameter, if applicable. The function provided in the callback
parameter will be called with a boolean value indicating the user's response. If true
, the add-on may access geolocation data.
function prompt(window, pref, message, callback) { let branch = Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefBranch); if (branch.getPrefType(pref) === branch.PREF_STRING) { switch (branch.getCharPref(pref)) { case "always": return callback(true); case "never": return callback(false); } } let done = false; function remember(value, result) { return function() { done = true; branch.setCharPref(pref, value); callback(result); } } let self = window.PopupNotifications.show( window.gBrowser.selectedBrowser, "geolocation", message, "geo-notification-icon", { label: "Share Location", accessKey: "S", callback: function(notification) { done = true; callback(true); } }, [ { label: "Always Share", accessKey: "A", callback: remember("always", true) }, { label: "Never Share", accessKey: "N", callback: remember("never", false) } ], { eventCallback: function(event) { if (event === "dismissed") { if (!done) callback(false); done = true; window.PopupNotifications.remove(self); } }, persistWhileVisible: true }); } prompt(window, "extensions.foo-addon.allowGeolocation", "Foo Add-on wants to know your location.", function callback(allowed) { alert(allowed); });