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