transistorsoft / cordova-background-geolocation-lt

The most sophisticated background location-tracking & geofencing module with battery-conscious motion-detection intelligence for iOS and Android.
http://www.transistorsoft.com/shop/products/cordova-background-geolocation
Other
658 stars 276 forks source link

Registry location problem #1141

Closed hernanjls closed 4 years ago

hernanjls commented 4 years ago

Hello, I was testing your plugin with my phone to record the location on my server, and it actually works, the data is sent to the server when I activate the app location "start button", but when I put the phone in my pocket and go out for a few laps (about 500 meters) around my house to see if the locations are being sent to the server, back I see that nothing has been registered, I have also verified that I have an internet connection while I am walking and I think it is not a connection problem. I have used the cordova example code that I show below, what could be the problem?

Your Environment

/**

var URL_SERVICE_BASE = 'https://mobileservices.domunet.com/'; var URL_SERVICE = URL_SERVICE_BASE + 'rest/';

var app = { // For posting locations to Transistor Software test-server. host: 'tracker.transistorsoft.com',

// Application state
state: {
    enabled: false,
    isMoving: false
},

// Application Constructor
initialize: function() {
    document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
},

// deviceready Event Handler
onDeviceReady: function() {
    this.receivedEvent('deviceready');

    ////
    // We request a unique identifier so you can post locations to tracker.transistorsoft.com.
    // - You can view your tracking at: http://tracker.transistorsoft.com/{username}
    // - You can completely delete your recorded locations at the web application.
    //
    this.getUsername(function (username) {

        initialize_Map();
        this.configureBackgroundGeolocation(username);

    }.bind(this));
},

// Update DOM on a Received Event
receivedEvent: function(id) {
    console.log('Received Event: ' + id);
},

// Configure Background Geolocation
configureBackgroundGeolocation: function(username) {
    username = username || 'cordova-basic';

    var bgGeo = window.BackgroundGeolocation;
    app.bgGeo = bgGeo;

    ////
    // Step 1:  Listen to events.  It's always best to listen to events first, before #configure
    //

    // location event: Fires whenever a location is recorded.
    bgGeo.onLocation(function(location) {
        console.log('[event] location: ', location);
        app.setLocation(location);

        var uname = "--";
        var lat = location.coords.latitude;
        var lon = location.coords.longitude;
        if (window.localStorage.getItem('username')) {
            uname = window.localStorage.getItem('username');
        }
        else{
            uname = location.uuid;
        }

        insertarLocation(uname, lat, lon);

    }, function(error) {
        console.warn('[event] location error: ', error);
    });

    // motionchange event:  Fires when plugin changes state from Stationary->Moving and vice-versa.
    bgGeo.onMotionChange(function(location) {
        console.log('[event] motionchange', location);
        app.setState({
            enabled: true,
            isMoving: location.isMoving
        });
    });

    // providerchange event:  Fires when user changes location authorization)
    bgGeo.onProviderChange(function(provider) {
        console.log('[event] providerchange: ', provider);
        app.setProvider(provider);
    });

    // heartbeat event:  Fires every heartbeatInterval while plugin is in stationary state.  iOS requires preventSuspend: true)
    bgGeo.onHeartbeat(function(event) {
        console.log('[event] heartbeat: ', event);
    });

    ////
    // Step 2:  Configure the plugin ONCE when your app boots.
    //

    bgGeo.ready({
        reset: true,
        desiredAccuracy: bgGeo.DESIRED_ACCURACY_HIGH,     // Highest possible accuracy: GPS + Wifi + Cellular
        distanceFilter: 10,     // Record a location every 10 meters.
        stopTimeout: 1,         // Change state to stationary after 1 min with device "still"
        stopOnTerminate: false, // Don't stop tracking when app is terminated.
        foregroundService: true,// Prevent Android from terminating service due to memory pressure from other apps.
        heartbeatInterval: 60,  // <-- heartbeat event every 60s
        url: 'http://' + app.host + '/locations/' + username,
        params: bgGeo.transistorTrackerParams(window.device),
        debug: false,            // Debug sounds & notifications
        autoSync: true,         // Auto sync each recorded location to #url immediately.
        logLevel: bgGeo.LOG_LEVEL_VERBOSE
    }, function(state) {
        app.setState(state);
        console.log('- BackgroundGeolocation is configured and ready to use');
    });

    // Wire-up UI
    var btnEnable = document.getElementById('btn-enable');
    var btnChangePace = document.getElementById('btn-changePace');
    var btnGetCurrentPosition = document.getElementById('btn-getCurrentPosition');
    var label = document.getElementById('label-view-tracker');

    btnEnable.addEventListener('click', this.onToggleEnabled.bind(this));
    btnChangePace.addEventListener('click', this.onClickChangePace.bind(this));
    btnGetCurrentPosition.addEventListener('click', this.onClickGetCurrentPosition.bind(this));

    // Write label message of where to view tracking history
    //label.innerHTML = 'View your tracking at http://' + app.host + '/' + username;
},

onToggleEnabled: function() {
    if (app.state.enabled) {
        app.bgGeo.stop(function(state) {
            console.log('- stop success');
            app.setState(state);
            app.setLabel('Stopped', 'grey');
        });
    } else {
        app.bgGeo.start(function(state) {
            console.log('- start success');
            app.setState(state);
            app.setLabel('Acquiring motionchange position...', 'red');
        });
    }
},

onClickChangePace: function() {
    if (!app.state.enabled) {
        console.warn('- Cannot changePace while disabled.  You must #start the plugin first');
        return;
    }
    var isMoving = !app.state.isMoving;
    app.setLabel('Acquiring motionchange position...', (isMoving) ? 'green' : 'red');
    app.updateChangePaceButton(isMoving);
    app.bgGeo.changePace(isMoving, function() {
        console.log('- changePace success');
    });
},

onClickGetCurrentPosition: function() {
    app.bgGeo.getCurrentPosition({persist: true, samples: 1}).then(function(location) {
        console.log('- getCurrentPosition success: ', location);
    }, function(error) {
        console.warn('- getCurrentPosition error: ', error);
    });
},

setState: function(state) {
    app.state = state;
    var text = '';
    var color = 'grey';

    if (state.enabled) {
        if (state.isMoving) {
            text = 'Tracking mode';
            color = 'green';
        } else {
            text = 'Stationary mode';
            color = 'red';
        }
    } else {
        text = 'Stopped';
        color = 'grey';
    }
    this.setLabel(text, color);
    this.updateChangePaceButton(state.isMoving);
    this.updateToggleButton(state.enabled);
},

setLabel: function(text, color) {
    var trackingState = document.getElementById('tracking-state');
    var classNames = ['event', color];
    trackingState.innerHTML = text;
    trackingState.className = classNames.join(' ');
},

updateToggleButton: function(enabled) {
    var btnEnable = document.getElementById('btn-enable');
    if (enabled) {
        btnEnable.innerHTML = 'Stop';
        btnEnable.className = 'red';
    } else {
        btnEnable.innerHTML = 'Start';
        btnEnable.className = 'green';
    }
},

updateChangePaceButton: function(isMoving) {
    var btn = document.getElementById('btn-changePace');
    btn.className = (isMoving) ? 'red' : 'green';
},

setLocation: function(location) {
    var consoleEl = document.getElementById('location');

    // Print Location JSON
    //var json = JSON.stringify(location, null, 2);
    //consoleEl.innerHTML = json.substring(4, json.length-2);

    var lat = location.coords.latitude;
    var lon = location.coords.longitude;

    consoleEl.innerHTML = "LAT: " + lat + "</br>LON: " + lon ;

    // Highlight animation
    consoleEl.className = "highlight";
    setTimeout(function() {
        consoleEl.className = '';
    }, 200);
},

setProvider: function(provider) {
    var providerEl = document.getElementById('provider');
    providerEl.innerHTML = JSON.stringify(provider);
},

getUsername: function(callback) {

    if (window.localStorage.getItem('username')) {
        // We have a username already, yay!
        callback(window.localStorage.getItem('username'));
        return;
    }
    // Prompt user at first boot for username.
    navigator.notification.prompt('Porfavor ingresa un identificador de Usuario (ej: tu nombre, email o telefono)' , function(response) {

        var uname = "--";
        if (response.buttonIndex === 1 && response.input1.length > 0) {
            uname = response.input1;
        } 

        $.ajax({
            type: "POST",
            url: URL_SERVICE + "retrofitLocation2.aspx/insertUsername",
            data: "{'username':'" + uname + "'}",
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            crossDomain: true,
            cache: false,
            success: function (result) {
                if (result.d != null) {
                    var reg = result.d;

                    var data = jQuery.parseJSON(result.d);
                    window.localStorage.setItem('username', data.userName);
                    // We have a username
                    callback(response.input1);

                }
            },
            error: function (result) {
                callback(null);
                alert("Ocurri� un problema al insertar al usuario");
            }
        });

    }, 'Tu Identificador');
}

};

app.initialize();

function insertarLocation(uname, lat, lon) {

var params = {
    username: uname,
    lat: lat,
    lon: lon
};

$.ajax({
    type: "POST",
    url: URL_SERVICE + "retrofitLocation2.aspx/insertarLocation",
    data: JSON.stringify(params),
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    crossDomain: true,
    success: function (res) {

        var data = jQuery.parseJSON(res.d);

    },
    failure: function (response) {
        alert(response.d);
    },
    error: function (response) {
        alert(response.d);
    }
});

}


## Expected Behavior
<!--- Tell us what should happen -->

## Actual Behavior
<!--- Tell us what happens instead -->

## Steps to Reproduce
<!--- reproduce this issue; include code to reproduce, if relevant -->
1.
2.
3.
4.

## Context
<!--- What were you trying to do? -->

## Debug logs
<!-- include iOS / Android logs
- ios XCode logs,
- use #getLog #emailLog methods (@see docs)
- Android: $ adb logcat
-->
<details>
    <summary>Logs</summary>

```<!-- Syntax highlighting:  DO NOT REMOVE -->
PASTE_YOUR_LOGS_HERE

christocracy commented 4 years ago

Plugin version: Device manufacturer / model:

christocracy commented 4 years ago

Cordova version (cordova -v): Cordova platform version (cordova platform ls):

christocracy commented 4 years ago

The plugin's built-in native HTTP service is far superior for uploading locations to a server than Ajax requests.

I suggest you enable debug: true so you can hear the plugin working. Also see Wiki Debugging to learn how to retrieve logs from the plugin's log database.

hernanjls commented 4 years ago

cordova version is: 9.0.0 (cordova-lib@9.0.1)

platform compiling is: windows 10

phone model is: HUAWEI P8 lite (ale-l23)

I could also use XMLHttpRequest (), but I think the problem is not that I am using ajax, anyway I am going to try it but where does it have an example of how to send data to my server using the option you mentioned in the plugin ?, I will put it in mode debug and try to see also the logs that you mention

christocracy commented 4 years ago

HUAWEI P8 lite (ale-l23)

I purchased a Huawei P20 Lite (ANE-LX3) precisely because Huawei are the worst devices on earth for background-services. See http://dontkillmyapp.com

hernanjls commented 4 years ago

here in my country, the use of huawei and samsung is quite widespread ... I going to install it on a samsung and see what happens

christocracy commented 4 years ago

There is no developer solution for issues regarding any particular device. The only solution is to modify device settings as prescribed at http://dontkillmyapp.com.

hernanjls commented 4 years ago

for my device there an developer solution showed there

Solution for devs EMUI 4

String tag = "com.my_app:LOCK";

if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M && Build.MANUFACTURER.equals("Huawei")) { tag = "LocationManagerService"; }

PowerManager.WakeLock wakeLock = ((PowerManager) getSystemService(Context.POWER_SERVICE)).newWakeLock(1, tag); wakeLock.acquire();

Can you put this fix in your plugin please??

hernanjls commented 4 years ago

I understand that each manufacturer includes default restrictions on applications, especially with the use of batteries, but for example certain applications such as WhatsApp and Facebook Messenger are activated by default as allowed when I install them and I had no need to modify anything in the configuration of the phone, as programmers have surely found some way to include them as allowed using a developer solution, es posible do this in your plugin??

christocracy commented 4 years ago

but for example certain applications such as WhatsApp and Facebook Messenger are activated by default

Correct. Those are "big company" apps and they've made specific deals with particular device manufacturers to have their apps "white-listed" in the OS. Your company is free to contact the device manufacturers and make a case to have your own app white-listed.

hernanjls commented 4 years ago

Only this way is possible to do? no way to do one app is allow how enabed from developer java language? what others android devices occurs this problem?

christocracy commented 4 years ago

I develop against the published Android API docs. What each Android OEM does is beyond the control of a developer. The necessary settings required are detailed at http://dontkillmyapp.com.

hernanjls commented 4 years ago

ok I set the debug in true, and settings is changed in my device for enable the battery condition... When the app is in background, the sound (like frog sound) happen after some seconds while I walking in the street, I suposse that this happen when change locations is detected rigth?, but this code

// location event: Fires whenever a location is recorded. bgGeo.onLocation(function(location) {

        var uname = "--";
        var lat = location.coords.latitude;
        var lon = location.coords.longitude;
        if (window.localStorage.getItem('username')) {
            uname = window.localStorage.getItem('username');
        }
        else{
            uname = location.uuid;
        }

        insertarLocation(uname, lat, lon);

        console.log('[event] location: ', location);
        app.setLocation(location);

    }, function(error) {
        console.warn('[event] location error: ', error);
    });

only happen when the screen of the app is active apparently, because the call to the function insertarLocation(uname, lat, lon); not is called in background, only is called when the screen app is active.

Where I will be put the code for the execution of call function happens?

christocracy commented 4 years ago

The debug sounds are explained in the api docs for Config.debug

hernanjls commented 4 years ago

Ok and sorry but where is the documentation link that you mention before? please write the link, thanks

christocracy commented 4 years ago

The api docs are linked in the readme.