Приложение Cordova, которое каждую минуту загружает мое местоположение на внутренний сервер, даже если экран выключен или приложение находится в фоновом режиме - PullRequest
1 голос
/ 02 июня 2019

Я изо всех сил пытаюсь написать приложение Cordova для Android, которое будет продолжать работать после выключения экрана. Я пытаюсь использовать фоновые и передние службы (иногда вместе), чтобы поддерживать простой цикл: определите мое местоположение и отправьте JSON через TCP на внутренний сервер. у кого-нибудь есть решение? Я использую Android 8.1 Oreo, и я попытался добавить в приложение пакеты npm, работающие как на переднем, так и на заднем плане, и фоновые. Независимо от того, что я пытаюсь сделать, через ~ 5 минут после выключения экрана телефона приложение перестает взаимодействовать с внутренним сервером. Я отключил меры по энергосбережению, и я действительно застрял здесь. Спасибо.

Ответы [ 2 ]

1 голос
/ 04 июня 2019

Используя эти плагины (с 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 секунд по беспроводной сети.

Это неприятно, но работает.В какой-то момент я начну разбираться с каждой зависимостью, чтобы увидеть необходимый минимум, но это работает!

1 голос
/ 03 июня 2019

С новыми версиями Android, Google все больше и больше реализует функции, которые убивают приложение в фоновом режиме. В общей схеме это хорошо, это для того, чтобы сэкономить заряд батареи, однако, это не очень хорошая новость для разработчика. В частности, посмотрите на их документацию: доза и адаптивный аккумулятор .

На момент написания этой статьи не было никаких плагинов Cordova, которые бы учитывали эти функции для более новых версий Android (сначала была введена доза для Android 6.0, более поздние версии сделали ее более жесткой).

Если не писать свой собственный плагин, здесь нет хорошего ответа. Поддержание работы вашего приложения в фоновом режиме - это функция, которая требует (и будет) требовать постоянного обслуживания по мере выпуска новых версий Android, и это, в общем-то, не то, что у Cordova отлично получается.

Cordova как инструмент разработки не предназначен для глубоких нативных функций. Используйте cordova в качестве платформы, если вам требуется приложение для вашего основного продукта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...