Cordova应用程序每分钟将我的位置上传到后端服务器,即使屏幕关闭或应用程序处于后台

时间:2019-06-02 11:42:45

标签: cordova networking gps

我正在努力为Android编写Cordova应用程序,该应用程序在屏幕关闭后仍将继续运行。我正在尝试后台服务和前台服务(有时一起使用)以保持简单的循环运行:获取我的位置,并将JSON通过TCP发送到后端服务器。有没有人有办法解决吗?我正在运行Android 8.1 Oreo,并且尝试将前景,后台和后台运行的计时器npm程序包都放入我的应用中。无论我如何尝试,在关闭手机屏幕约5分钟后,该应用程序都将停止与后端服务器的通信。我已经禁用了节电措施,而且我真的被困在这里。谢谢。

3 个答案:

答案 0 :(得分:1)

使用更新版本的android,Google越来越多地实现了在后台终止应用程序的功能。在宏伟的计划中,这是一件好事,这是为了节省电池寿命,但是,这对于开发人员而言不是好消息。具体来说,请查看其文档:doze and adaptive battery

在撰写本文时,尚无Cordova插件来说明较新的android版本的这些功能(doze最初是在android 6.0中引入的,后来的版本使其更加苛刻)。

简短编写自己的插件,这里没有好的答案。在后台运行您的应用程序是一项功能,该功能确实(并且将需要)在发布新版本的android时进行持续维护,也就是说,通常,cordova并不擅长于此。

Cordova作为开发工具并不意味着具有深厚的本机功能。如果您需要主要产品的快速随附应用程序,请使用cordova作为平台。

答案 1 :(得分:1)

使用这些插件(与cordova 9.0.0一起使用):

cordova-background-timer 0.0.4 "BackgroundTimer"
cordova-plugin-background-mode 0.7.2 "BackgroundMode"
cordova-plugin-device 2.0.2 "Device"
cordova-plugin-foreground-service 1.1.1 "Cordova Foreground Service"
cordova-plugin-mauron85-background-geolocation 3.0.1 "CDVBackgroundGeolocation"
cordova-plugin-whitelist 1.3.3 "Whitelist"

此JavaScript代码:

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

    cordova.plugins.foregroundService.start('GPS Running', 'Background Service');

    cordova.plugins.backgroundMode.on('activate', function () {
        console.log("Disabled webview optimizations");
        cordova.plugins.backgroundMode.disableWebViewOptimizations();
    });
    cordova.plugins.backgroundMode.enable();

    var socket = io.connect('http://server.com:3000');
    socket.on('request', function (empty) {
        BackgroundGeolocation.getCurrentLocation(function (location) {
            socket.emit('location', JSON.stringify(location));
        });
    });

    BackgroundGeolocation.configure({
        locationProvider: BackgroundGeolocation.ACTIVITY_PROVIDER,
        desiredAccuracy: BackgroundGeolocation.HIGH_ACCURACY,
        notificationTitle: 'Justin is cool',
        notificationText: 'enabled',
        debug: false,
        interval: 30 * 1000,
        fastestInterval: 30 * 1000,
        activitiesInterval: 30 * 1000
    });

    BackgroundGeolocation.on('location', function (location) {
        // handle your locations here
        // to perform long running operation on iOS
        // you need to create background task
        //console.log("regular location:");
        //console.log(location);
        BackgroundGeolocation.startTask(function (taskKey) {
            // execute long running task
            // eg. ajax post location
            // IMPORTANT: task has to be ended by endTask
            BackgroundGeolocation.endTask(taskKey);
        });
    });

    BackgroundGeolocation.on('stationary', function (stationaryLocation) {
        // handle stationary locations here
        //console.log("Stationary object");
        //console.log(stationaryLocation);
    });

    BackgroundGeolocation.on('error', function (error) {
        console.log('[ERROR] BackgroundGeolocation error:', error.code, error.message);
    });

    BackgroundGeolocation.on('start', function () {
        console.log('[INFO] BackgroundGeolocation service has been started');
    });

    BackgroundGeolocation.on('stop', function () {
        console.log('[INFO] BackgroundGeolocation service has been stopped');
    });

    BackgroundGeolocation.on('authorization', function (status) {
        console.log('[INFO] BackgroundGeolocation authorization status: ' + status);
        if (status !== BackgroundGeolocation.AUTHORIZED) {
            // we need to set delay or otherwise alert may not be shown
            setTimeout(function () {
                var showSettings = confirm('App requires location tracking permission. Would you like to open app settings?');
                if (showSetting) {
                    return BackgroundGeolocation.showAppSettings();
                }
            }, 1000);
        }
    });

    BackgroundGeolocation.on('background', function () {
        console.log('[INFO] App is in background');
        // you can also reconfigure service (changes will be applied immediately)
        BackgroundGeolocation.configure({
            debug: false
        });
    });

    BackgroundGeolocation.on('foreground', function () {
        console.log('[INFO] App is in foreground');
        BackgroundGeolocation.configure({
            debug: false
        });
    });

    BackgroundGeolocation.on('abort_requested', function () {
        console.log('[INFO] Server responded with 285 Updates Not Required');

        // Here we can decide whether we want stop the updates or not.
        // If you've configured the server to return 285, then it means the server does not require further update.
        // So the normal thing to do here would be to `BackgroundGeolocation.stop()`.
        // But you might be counting on it to receive location updates in the UI, so you could just reconfigure and set `url` to null.
    });

    BackgroundGeolocation.on('http_authorization', () => {
        console.log('[INFO] App needs to authorize the http requests');
    });

    BackgroundGeolocation.checkStatus(function (status) {
        console.log('[INFO] BackgroundGeolocation service is running', status.isRunning);
        console.log('[INFO] BackgroundGeolocation services enabled', status.locationServicesEnabled);
        console.log('[INFO] BackgroundGeolocation auth status: ' + status.authorization);

        // you don't need to check status before start (this is just the example)
        if (!status.isRunning) {
            BackgroundGeolocation.start(); //triggers start on start event
        }
    });

},

并且禁用此应用程序的节能功能,我成功​​了。

为确保此功能正常运行,我让后端服务器每60秒向我发送一个websocket数据包。

这很讨厌,但是有效。在某个时候,我将开始研究每个依赖项,以了解所需的最低限度,但这是可行的!

答案 2 :(得分:0)

是的,请求以某种方式兑现并设置在应用履历表上-嗯...

尝试一下:

如果可以,请使用“ @ mauron85 / cordova-plugin-background-geolocation”帖子模板,也可以使用“ cordova-plugin-advanced-http”回调方法在onLocation()中删除url和syncUrl并发送自己的http请求,从本地发送请求。

(现在可以在android 7上为我工作数周-三星Galaxy)