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