Closed mlahdouri closed 1 year ago
See api docs Config.stopTimeout
Also read wiki “Philosophy of Operation”
thanks, i have used this option as you can see in my script : stopTimeout : 120, ( is set it to 10 , but still the tracking stopes at 5 min ) also i use disableStopDetection: true, wish should keep the the service from turning OFF
also , i'm aware of the “Philosophy of Operation” my use case is : 1- The user start the tracking, 2 - Tracking should run for like 2 hours ( even when screen is off or in still position ), 3 - The user stops the tracking.
hope you can help with that :)
See wiki Debugging and learn to fetch and observe your logs.
partof-log.txt here is a log for the 5 minutes time the service was working, when screen was off
Screen is off all the time of the test starting from : 11-24 00:57:48.167 end at : 11-24 01:02:22.135 screen on at : 11-24 01:13:46.304
so at the 11-24 01:02:22.135 mark, the tracking stopes, and dosn't resume untill i turn on the screen again at 11-24 01:13:46.304
Show me every bit of code from your app where you are interacting with BackgroundGeolocation.
here is the content of the js file on the start tracking page :
the function startTrack() have the BackgroundGeolocation.ready
then it calls the function getMapLocation() where i do BackgroundGeolocation.setConfig ( just to be sure )
then do a BackgroundGeolocation.getCurrentPosition
getMapLocation() is executed every X seconds by the function pushLocation()
var ctRefresh = 0;
var urlParams;
var accountDataStatus = false;
var idxCustomer;
var groups = new Array();
var user = new Array();
var configurations = new Array();
var getGroupsStatus = false;
var getUserStatus = false;
var getConfigurationStatus = false;
var page_id;
var privilege;
var db;
var prvlg_user = 0;
var ctColdStorageBasket = 0;
var track_id_app;
var continueTracking = false;
var runningBackround = false;
var trackingCount = 0;
var pages = "";
var refreshRate = 6000;
var netStatus = false;
var deviceLat;
var deviceLong;
var devAccuracy;
(window.onpopstate = function () {
var match,
pl = /\+/g, // Regex for replacing addition symbol with a space
search = /([^&=]+)=?([^&]*)/g,
decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
query = window.location.search.substring(1);
urlParams = {};
while (match = search.exec(query))
urlParams[decode(match[1])] = decode(match[2]);
})();
function includeHTML() {
var z, i, elmnt, file, xhttp;
/*loop through a collection of all HTML elements:*/
z = document.getElementsByTagName("*");
for (i = 0; i < z.length; i++) {
elmnt = z[i];
/*search for elements with a certain atrribute:*/
file = elmnt.getAttribute("w3-include-html");
if (file) {
/*make an HTTP request using the attribute value as the file name:*/
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200) {elmnt.innerHTML = this.responseText;}
if (this.status == 404) {elmnt.innerHTML = "Page not found.";}
/*remove the attribute, and call this function once more:*/
elmnt.removeAttribute("w3-include-html");
includeHTML();
}
}
xhttp.open("GET", file, true);
xhttp.send();
/*exit the function:*/
return;
}
}
}
var imageOptions = {
share: true, // default is false
closeButton: false, // default is true
copyToReference: true, // default is false
headers: '', // If this is not provided, an exception will be triggered
piccasoOptions: { } // If this is not provided, an exception will be triggered
};
function getRefreshRate()
{//alert("getRegfresh")
db.transaction(function(tx)
{
tx.executeSql('SELECT * FROM Tracks_Configurations', [], function(tx, rs)
{
for ( i = 0; i < rs.rows.length; i++ )
{
configurations.push(rs.rows.item(i));
}
refreshRate = configurations[0].refresh_rate;
}, function(tx, error)
{
//alert('SELECT Users error: ' + error.message);
});
});
}
function checkRunTracking(listing, totalTrack)
{
if ((listing[listing.length-1].end_time == "" ))
{
continueTracking = true;
trackingCount = totalTrack;
track_id_app = listing[listing.length-1].track_id_app;
runningBackround = true;
getMapLocation();
backModeOn();
}
}
function backModeOn()
{
cordova.plugins.backgroundMode.setDefaults({ text:'Status : Active '});
// Enable background mode
cordova.plugins.backgroundMode.enable();
// Called when background mode has been activated
cordova.plugins.backgroundMode.onactivate = function ()
{
cordova.plugins.backgroundMode.disableWebViewOptimizations();
cordova.plugins.backgroundMode.disableBatteryOptimizations();
//getMapLocation();
}
}
function getMapLocation()
{
BackgroundGeolocation.setConfig({
isMoving: true,
distanceFilter: 100,
pausesLocationUpdatesAutomatically: false,
stopTimeout : 10,
disableStopDetection : true,
stopOnTerminate: false,
logLevel: BackgroundGeolocation.LOG_LEVEL_VERBOSE,
debug: true,
disableMotionActivityUpdates: true,
allowIdenticalLocations : true,
autoSync : false
}, (state) => {
console.log("- BackgroundGeolocation is ready, set config ok: ", state);
});
alert("getMapLocation")
if ( runningBackround == true )
{
BackgroundGeolocation.getCurrentPosition({
samples: 3,
persist: true
}).then((location) => {
//document.getElementById("locDiv").innerHTML = "Counter " + ct + " = \n" + location.coords.latitude + " " + JSON.stringify(location);
trackingCount++;
deviceLat = location.coords.latitude;
deviceLong = location.coords.longitude;
devAccuracy = location.coords.accuracy;
//alert(pages + " " + JSON.stringify(listing[listing.length-1]))
if ( pages == "tracking")
{
document.getElementById("gpsLat").innerHTML = deviceLat;
document.getElementById("gpsLong").innerHTML = deviceLong;
document.getElementById("trackingCount").innerHTML = stringTrackingCount + "(" + trackingCount + ")";
}
pushLocation();
}, function(error) {
//BackgroundGeolocation.changePace(true);
getMapLocation();
bgGeo.on('heartbeat', function(params) {
console.log('- heartbeat event received');
});
});
}
}
function onMapError(error)
{
//alert('code: ' + error.code + '\n' +
//'message: ' + error.message + '\n');
getMapLocation();
}
var onMapSuccess = function (position)
{
//alert("onMapSuccess")
trackingCount++;
deviceLat = position.coords.latitude;
deviceLong = position.coords.longitude;
pushLocation();
}
function pushLocation()
{
//alert("pushLocation")
var dateTime = new Date();
//alert(dateTime);
dateTime = dateTime.toLocaleString('en-US', {hour12: false});
//alert(dateTime);
if ( continueTracking == false )
{
//track_id_app = uid + "" + new Date().valueOf()
}
//alert(continueTracking + " " + track_id_app)
db.transaction(function(tx)
{
tx.executeSql('INSERT INTO Tracking VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13)',
[uid + "" + new Date().valueOf(), track_id_app, dateTime, deviceLat, deviceLong, devAccuracy, "", "", "", refreshRate, user[0].user_id, uid, 0 ]);
}, function(error) {
console.log('Transaction ERROR: ' + error.message);
}, function() {
setTimeout(getMapLocation, refreshRate);
});
}
function startTrack()
{
BackgroundGeolocation.ready({
distanceFilter: 20,
stopTimeout : 10,
pausesLocationUpdatesAutomatically: false,
disableStopDetection : true,
stopOnTerminate: false,
logLevel: BackgroundGeolocation.LOG_LEVEL_VERBOSE,
debug: true
}, (state) => {
console.log("- BackgroundGeolocation is ready: ", state);
});
BackgroundGeolocation.start().then((state) => {
console.log("[start] success - ", state);
});
document.getElementById("actionButton").innerHTML = "<a href=\"#\" onclick=\"stopTrack();\">" +
"<p>STOP</p>" +
"</a>";
listing.length = 0;
details.length = 0;
//trackingCount = 0;
var dateTime = new Date();
dateTime = dateTime.toLocaleString('en-US', {hour12: false});
listingId = uid + "" + new Date().valueOf();
track_id_app = listingId;
runningBackround = true;
listing.length = 0;
db.transaction(function(tx)
{
tx.executeSql('SELECT * FROM Listing', [], function(tx, rs)
{
for ( i = 0; i < rs.rows.length; i++ )
{
listing.push(rs.rows.item(i));
}
setTimeout(getMapLocation,700);
window.open("tracking.html","_blank");
}, function(tx, error)
{
alert('SELECT Listing error: ' + error.message);
});
});
}
function stopTrack()
{
var text = "want to Stop?";
if (confirm(text) == true)
{
continueTracking = false;
//cordova.plugins.backgroundMode.disable();
runningBackround = false;
var dateTime = new Date();
dateTime = dateTime.toLocaleString('en-US', {hour12: false});
//alert(dateTime + " " + track_id_app)
db.transaction(function(tx) {
var query = "update Listing set end_time = ? where track_id_app = ?";
tx.executeSql(query, [dateTime, listing[listing.length-1].track_id_app], function(tx, res) {
console.log("insertId: " + res.insertId);
},
function(tx, error) {
alert('UPDATE error: ' + error.message);
});
}, function(error) {
//console.log('Transaction ERROR: ' + error.message);
alert('Download Product Transaction ERROR: ' + error.message);
}, function() {
listing.length = 0;
document.getElementById("actionButton").innerHTML = startTrackButton;
window.open("index.html","_blank");
//showTrack();
});
}
BackgroundGeolocation.logger.emailLog('myemail@mailprovider.com').then((success) => {
console.log('[emailLog] SUCCESS');
}).catch((error) => {
console.log('[emailLog] ERROR: ', error);
});
}
where i do BackgroundGeolocation.setConfig ( just to be sure )
Sure of what??
This is incorrect usage, as warned in the README.
BackgroundGeolocation.ready({
distanceFilter: 20,
stopTimeout : 10,
pausesLocationUpdatesAutomatically: false,
disableStopDetection : true,
stopOnTerminate: false,
logLevel: BackgroundGeolocation.LOG_LEVEL_VERBOSE,
debug: true
}, (state) => {
console.log("- BackgroundGeolocation is ready: ", state);
});
// NO! You CANNOT call .start() before callback to .ready has fired!!!!!!!!!!!!
BackgroundGeolocation.start().then((state) => {
console.log("[start] success - ", state);
});
BackgroundGeolocation.ready(config, function(state) {
// Background Geolocation is now ready to use.
if (!state.enabled) {
// YES! OK to call .start() here.
BackgroundGeolocation.start();
}
});
// NO!!!!!!!!!!!!! .ready() callback has not fired!
BackgroundGeolocation.start();
This is some ancient-looking code. Are you a developer who has taken over an old project?
You know you have a potential memory leak, adding an onHeartbeat
listener each time your error callback to getCurrentPosition
fires?
bgGeo.on('heartbeat', function(params) {
console.log('- heartbeat event received');
});
Seriously?? You're going to run that function every 700ms?? Your app is probably running out of memory and the device overheating.
setTimeout(getMapLocation,700);
setTimeout(getMapLocation,700);
Oh, sorry...that's not setInterval
. Still weird.
yes i'm trying to help to figure this out with my devlopper
Your app is stuck in some sort of loop calling .ready()
and/or .start()
over and over again.
You likely have some code in the app pause
/ resume
event interacting with the plugin.
It's important to be aware that the PLUGIN ITSELF causes pause
/resume
events to occur on Android (see Config.disableLocationAuthorizationAlert
.
Your logs are full of this, over and over and over
11-24 00:58:17.162 DEBUG [LifecycleManager onPause] ☯️ onPause
11-24 00:58:17.162 DEBUG [LifecycleManager onStop] ☯️ onStop
.
.
.
🔵 Acquired motionchange position, isMoving: true
.
.
.
11-24 00:58:23.395 DEBUG [LifecycleManager onStart] ☯️ onStart
11-24 00:58:23.398 DEBUG [LifecycleManager onResume] ☯️ onResume
...
whatever your problem is, it's your own code responsible.
It's like you're calling .start()
every 6-8
seconds.
11-24 00:57:48.991 INFO [TSLocationManager onSingleLocationResult]
🔵 Acquired motionchange position, isMoving: true
11-24 00:57:55.984 INFO [TSLocationManager onSingleLocationResult]
🔵 Acquired motionchange position, isMoving: true
11-24 00:58:02.998 INFO [TSLocationManager onSingleLocationResult]
🔵 Acquired motionchange position, isMoving: true
11-24 00:58:10.044 INFO [TSLocationManager onSingleLocationResult]
🔵 Acquired motionchange position, isMoving: true
11-24 00:58:16.995 INFO [TSLocationManager onSingleLocationResult]
🔵 Acquired motionchange position, isMoving: true
11-24 00:58:23.989 INFO [TSLocationManager onSingleLocationResult]
🔵 Acquired motionchange position, isMoving: true
it's BackgroundGeolocation.getCurrentPosition that is executed every 6 seconds, we need this to get the current position and save it on the DB
What's the point calling .start()
and .setConfig
every 6 seconds?!?
Get rid of that.
If you want the location every 6 seconds just call .getCurrentPosition()
here i have moved the bgGeo.ready to the onDeviceReady :
function onDeviceReady() {
db = window.sqlitePlugin.openDatabase({
name: 'my.db',
location: 'default',
});
uid = device.uuid;
pages = "tracking";
// 1. Listen to events
var bgGeo = window.BackgroundGeolocation;
bgGeo.onLocation(function(location) {
console.log('[location] -', location);
});
bgGeo.onMotionChange(function(event) {
console.log('[motionchange] -', event.isMoving, event.location);
});
bgGeo.onProviderChange(function(event) {
console.log('[providerchange] -', event.status, event.enabled, event.gps, event.network);
});
// 2. Execute #ready method:
bgGeo.ready({
debug: true,
logLevel: bgGeo.LOG_LEVEL_VERBOSE,
desiredAccuracy: bgGeo.DESIRED_ACCURACY_HIGH,
stopTimeout: 14,
pausesLocationUpdatesAutomatically: false,
disableStopDetection: true,
stopOnTerminate: false,
startOnBoot: true,
isMoving: true,
distanceFilter: 100,
disableMotionActivityUpdates: true,
allowIdenticalLocations : true,
autoSync : false
}, function(state) { // <-- Current state provided to #configure callback
// 3. Start tracking
console.log('BackgroundGeolocation is configured and ready to use');
if (!state.enabled) {
bgGeo.start().then(function() {
console.log('- BackgroundGeolocation tracking started');
});
}
});
}
then only call .getCurrentPosition() inside function getMapLocation()
function getMapLocation()
{
if ( runningBackround == true )
{
BackgroundGeolocation.getCurrentPosition({
samples: 3,
persist: true
}).then((location) => {
trackingCount++;
deviceLat = location.coords.latitude;
deviceLong = location.coords.longitude;
devAccuracy = location.coords.accuracy;
pushLocation();
}, function(error) {
getMapLocation();
});
}
}
do you know that the plugin has its own http service and SQLite database?
see api docs Config.url
yes, but we use our own function for that, as we have other type of inserts
also we give the user the choice to sync or not
Then do you know that each time you call getCurrentPosition with persist: true, the plugin inserts a new record into its database, that you’re never going to use?
I suggest you call .getCount()
and see how many records you’ve got inserted in the plugin db.
also see api docs Config.maxRecordsToPersist, Config.maxDaysToPersist
autoSync : false
This option is ignored if you don’t provide the plugin an url
stopOnTerminate: false,
Do you know that your app is not uploading or storing anything in your SQLite db when the app is running terminated, even though the plugin continues to track?
i see what you mean, we can use the http service , but the problem now is that the tracking still stops after 5 min, after the edit i sent you
I suggest go test my SampleApp on your device.
It’s available on the Play Store and linked in the readme.
I also suggest you build yourself a simple HelloWorld app and test that.
Your Environment
cordova -v
): 11.0.0cordova platform ls
): android 11.0.0, browser 6.0.0#ready
:Expected Behavior
the tracking should not stop even in still mode after the screen is off
Actual Behavior
the tracking stop after 5 min when screen is off
Steps to Reproduce
i have a function that i execute every X seconds
}