Mon 21 Jul 22:43:21 CEST 2025
This commit is contained in:
		
							parent
							
								
									5255fc42b1
								
							
						
					
					
						commit
						31eaed8303
					
				|  | @ -0,0 +1,211 @@ | ||||||
|  | /* | ||||||
|  |  * | ||||||
|  |  * Licensed to the Apache Software Foundation (ASF) under one | ||||||
|  |  * or more contributor license agreements.  See the NOTICE file | ||||||
|  |  * distributed with this work for additional information | ||||||
|  |  * regarding copyright ownership.  The ASF licenses this file | ||||||
|  |  * to you under the Apache License, Version 2.0 (the | ||||||
|  |  * "License"); you may not use this file except in compliance | ||||||
|  |  * with the License.  You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  *   http://www.apache.org/licenses/LICENSE-2.0
 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, | ||||||
|  |  * software distributed under the License is distributed on an | ||||||
|  |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||||||
|  |  * KIND, either express or implied.  See the License for the | ||||||
|  |  * specific language governing permissions and limitations | ||||||
|  |  * under the License. | ||||||
|  |  * | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | var argscheck = require('cordova/argscheck'), | ||||||
|  |     utils = require('cordova/utils'), | ||||||
|  |     exec = require('cordova/exec'), | ||||||
|  |     PositionError = require('./PositionError'), | ||||||
|  |     Position = require('./Position'); | ||||||
|  | 
 | ||||||
|  | var timers = {};   // list of timers in use
 | ||||||
|  | 
 | ||||||
|  | // Returns default params, overrides if provided with values
 | ||||||
|  | function parseParameters(options) { | ||||||
|  |     var opt = { | ||||||
|  |         maximumAge: 0, | ||||||
|  |         enableHighAccuracy: false, | ||||||
|  |         timeout: Infinity | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     if (options) { | ||||||
|  |         if (options.maximumAge !== undefined && !isNaN(options.maximumAge) && options.maximumAge > 0) { | ||||||
|  |             opt.maximumAge = options.maximumAge; | ||||||
|  |         } | ||||||
|  |         if (options.enableHighAccuracy !== undefined) { | ||||||
|  |             opt.enableHighAccuracy = options.enableHighAccuracy; | ||||||
|  |         } | ||||||
|  |         if (options.timeout !== undefined && !isNaN(options.timeout)) { | ||||||
|  |             if (options.timeout < 0) { | ||||||
|  |                 opt.timeout = 0; | ||||||
|  |             } else { | ||||||
|  |                 opt.timeout = options.timeout; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return opt; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Returns a timeout failure, closed over a specified timeout value and error callback.
 | ||||||
|  | function createTimeout(errorCallback, timeout) { | ||||||
|  |     var t = setTimeout(function() { | ||||||
|  |         clearTimeout(t); | ||||||
|  |         t = null; | ||||||
|  |         errorCallback({ | ||||||
|  |             code:PositionError.TIMEOUT, | ||||||
|  |             message:"Position retrieval timed out." | ||||||
|  |         }); | ||||||
|  |     }, timeout); | ||||||
|  |     return t; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var geolocation = { | ||||||
|  |     lastPosition:null, // reference to last known (cached) position returned
 | ||||||
|  |     /** | ||||||
|  |    * Asynchronously acquires the current position. | ||||||
|  |    * | ||||||
|  |    * @param {Function} successCallback    The function to call when the position data is available | ||||||
|  |    * @param {Function} errorCallback      The function to call when there is an error getting the heading position. (OPTIONAL) | ||||||
|  |    * @param {PositionOptions} options     The options for getting the position data. (OPTIONAL) | ||||||
|  |    */ | ||||||
|  |     getCurrentPosition:function(successCallback, errorCallback, options) { | ||||||
|  |         argscheck.checkArgs('fFO', 'geolocation.getCurrentPosition', arguments); | ||||||
|  |         options = parseParameters(options); | ||||||
|  | 
 | ||||||
|  |         // Timer var that will fire an error callback if no position is retrieved from native
 | ||||||
|  |         // before the "timeout" param provided expires
 | ||||||
|  |         var timeoutTimer = {timer:null}; | ||||||
|  | 
 | ||||||
|  |         var win = function(p) { | ||||||
|  |             clearTimeout(timeoutTimer.timer); | ||||||
|  |             if (!(timeoutTimer.timer)) { | ||||||
|  |                 // Timeout already happened, or native fired error callback for
 | ||||||
|  |                 // this geo request.
 | ||||||
|  |                 // Don't continue with success callback.
 | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             var pos = new Position( | ||||||
|  |                 { | ||||||
|  |                     latitude:p.latitude, | ||||||
|  |                     longitude:p.longitude, | ||||||
|  |                     altitude:p.altitude, | ||||||
|  |                     accuracy:p.accuracy, | ||||||
|  |                     heading:p.heading, | ||||||
|  |                     velocity:p.velocity, | ||||||
|  |                     altitudeAccuracy:p.altitudeAccuracy | ||||||
|  |                 }, | ||||||
|  |                 (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp))) | ||||||
|  |             ); | ||||||
|  |             geolocation.lastPosition = pos; | ||||||
|  |             successCallback(pos); | ||||||
|  |         }; | ||||||
|  |         var fail = function(e) { | ||||||
|  |             clearTimeout(timeoutTimer.timer); | ||||||
|  |             timeoutTimer.timer = null; | ||||||
|  |             var err = new PositionError(e.code, e.message); | ||||||
|  |             if (errorCallback) { | ||||||
|  |                 errorCallback(err); | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         // Check our cached position, if its timestamp difference with current time is less than the maximumAge, then just
 | ||||||
|  |         // fire the success callback with the cached position.
 | ||||||
|  |         if (geolocation.lastPosition && options.maximumAge && (((new Date()).getTime() - geolocation.lastPosition.timestamp.getTime()) <= options.maximumAge)) { | ||||||
|  |             successCallback(geolocation.lastPosition); | ||||||
|  |         // If the cached position check failed and the timeout was set to 0, error out with a TIMEOUT error object.
 | ||||||
|  |         } else if (options.timeout === 0) { | ||||||
|  |             fail({ | ||||||
|  |                 code:PositionError.TIMEOUT, | ||||||
|  |                 message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceeds provided PositionOptions' maximumAge parameter." | ||||||
|  |             }); | ||||||
|  |         // Otherwise we have to call into native to retrieve a position.
 | ||||||
|  |         } else { | ||||||
|  |             if (options.timeout !== Infinity) { | ||||||
|  |                 // If the timeout value was not set to Infinity (default), then
 | ||||||
|  |                 // set up a timeout function that will fire the error callback
 | ||||||
|  |                 // if no successful position was retrieved before timeout expired.
 | ||||||
|  |                 timeoutTimer.timer = createTimeout(fail, options.timeout); | ||||||
|  |             } else { | ||||||
|  |                 // This is here so the check in the win function doesn't mess stuff up
 | ||||||
|  |                 // may seem weird but this guarantees timeoutTimer is
 | ||||||
|  |                 // always truthy before we call into native
 | ||||||
|  |                 timeoutTimer.timer = true; | ||||||
|  |             } | ||||||
|  |             exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.maximumAge]); | ||||||
|  |         } | ||||||
|  |         return timeoutTimer; | ||||||
|  |     }, | ||||||
|  |     /** | ||||||
|  |      * Asynchronously watches the geolocation for changes to geolocation.  When a change occurs, | ||||||
|  |      * the successCallback is called with the new location. | ||||||
|  |      * | ||||||
|  |      * @param {Function} successCallback    The function to call each time the location data is available | ||||||
|  |      * @param {Function} errorCallback      The function to call when there is an error getting the location data. (OPTIONAL) | ||||||
|  |      * @param {PositionOptions} options     The options for getting the location data such as frequency. (OPTIONAL) | ||||||
|  |      * @return String                       The watch id that must be passed to #clearWatch to stop watching. | ||||||
|  |      */ | ||||||
|  |     watchPosition:function(successCallback, errorCallback, options) { | ||||||
|  |         argscheck.checkArgs('fFO', 'geolocation.getCurrentPosition', arguments); | ||||||
|  |         options = parseParameters(options); | ||||||
|  | 
 | ||||||
|  |         var id = utils.createUUID(); | ||||||
|  | 
 | ||||||
|  |         // Tell device to get a position ASAP, and also retrieve a reference to the timeout timer generated in getCurrentPosition
 | ||||||
|  |         timers[id] = geolocation.getCurrentPosition(successCallback, errorCallback, options); | ||||||
|  | 
 | ||||||
|  |         var fail = function(e) { | ||||||
|  |             clearTimeout(timers[id].timer); | ||||||
|  |             var err = new PositionError(e.code, e.message); | ||||||
|  |             if (errorCallback) { | ||||||
|  |                 errorCallback(err); | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         var win = function(p) { | ||||||
|  |             clearTimeout(timers[id].timer); | ||||||
|  |             if (options.timeout !== Infinity) { | ||||||
|  |                 timers[id].timer = createTimeout(fail, options.timeout); | ||||||
|  |             } | ||||||
|  |             var pos = new Position( | ||||||
|  |                 { | ||||||
|  |                     latitude:p.latitude, | ||||||
|  |                     longitude:p.longitude, | ||||||
|  |                     altitude:p.altitude, | ||||||
|  |                     accuracy:p.accuracy, | ||||||
|  |                     heading:p.heading, | ||||||
|  |                     velocity:p.velocity, | ||||||
|  |                     altitudeAccuracy:p.altitudeAccuracy | ||||||
|  |                 }, | ||||||
|  |                 (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp))) | ||||||
|  |             ); | ||||||
|  |             geolocation.lastPosition = pos; | ||||||
|  |             successCallback(pos); | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         exec(win, fail, "Geolocation", "addWatch", [id, options.enableHighAccuracy]); | ||||||
|  | 
 | ||||||
|  |         return id; | ||||||
|  |     }, | ||||||
|  |     /** | ||||||
|  |      * Clears the specified heading watch. | ||||||
|  |      * | ||||||
|  |      * @param {String} id       The ID of the watch returned from #watchPosition | ||||||
|  |      */ | ||||||
|  |     clearWatch:function(id) { | ||||||
|  |         if (id && timers[id] !== undefined) { | ||||||
|  |             clearTimeout(timers[id].timer); | ||||||
|  |             timers[id].timer = false; | ||||||
|  |             exec(null, null, "Geolocation", "clearWatch", [id]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | module.exports = geolocation; | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user