katzer / cordova-plugin-background-mode

Keep app running in background
Apache License 2.0
1.38k stars 1.02k forks source link

SetInterval/SetTimeout stops working after 5 mins #518

Open meghajayakumar opened 4 years ago

meghajayakumar commented 4 years ago

I have a requirement of a timer, that should send out notification (I am used onesignal API notification) after a particular user set value is reached.

For example if a user sets a value of 7 mins, the timer should send notification after 7 mins. The time a user can set varies from 1-59 mins. But even with using the background mode plugin, I cannot get the setInterval/setTimeout functions to work after 5 mins.

Tried using recursive setTimeout method:


function startTimerCounter() {
this.timerCounter = 0;
const objThis  = this; //store this.

if(this.timerCounter >= this.setTime) {
this.backgroundMode.disable();
this.goalTimerReached = true;
}
else {
this.backgroundMode.enable();
this.timer= setTimeout(function request() {
        if (objThis.timerCounter=== objThis.setTime) {
          //onesignal notification
          clearTimeout(objThis.timer);
        } else {
          ++objThis.timerCounter;
          objThis.timer= setTimeout(request, 1000);
        }
      }, 1000);
}

Tried using the setInterval method:

function startTimerCounter() {
this.timerCounter = 0;
const objThis  = this; //store this.

if(this.timerCounter >= this.setTime) {
this.backgroundMode.disable();
this.goalTimerReached = true;
}
else {
this.backgroundMode.enable();
this.timerCounter = 0;
const objThis  = this; //store this.
this.timer= setInterval(() => {
        if (objThis.timerCounter=== objThis.setTime) {
          //onesignal notification
          clearInterval(objThis.timer);
        } else {
          ++objThis.timerCounter;
        }
      }, 1000);
}

The background activation notification at the top and I can see that the background mode is active. But the timer doesn't seem to be running after 5 mins.

any idea how this could be solved?

danielehrhardt commented 4 years ago

Could you try: https://bitbucket.org/TheBosZ/cordova-plugin-run-in-background/src/master/

rcasunshare commented 4 years ago

Could you try: https://bitbucket.org/TheBosZ/cordova-plugin-run-in-background/src/master/

Does this help me to prevent notifications from freezing after 10 minutes?

My application shows the name of the song with the cover but when it is in the background the information in the notification bar stops updating after 10 minutes and freezes and does not refresh until the application is opened.

Gabri1495 commented 3 years ago

The background activation notification at the top and I can see that the background mode is active. But the timer doesn't seem to be running after 5 mins.

I have made exactly the same test with a setInterval and I have the same problem. Do you have solved it?

peitschie commented 2 years ago

I needed to call disableWebViewOptimizations() in Cordova's pause event. The 5min limit there is from the WebView itself throttling things down after a certain amount of time not being visible.

x842013824 commented 1 year ago

I needed to call disableWebViewOptimizations() in Cordova's pause event. The 5min limit there is from the WebView itself throttling things down after a certain amount of time not being visible.

I tried it, it works, disableWebViewOptimizations call webview’s onShow method, so it must be called in pause event

riccardocostantini commented 11 months ago

@katzer

riccardocostantini commented 11 months ago

function manageEvents() { document.addEventListener("deviceready", onDeviceReady, false); }

function onDeviceReady() { document.addEventListener("pause", onPause, false); cordova.plugins.backgroundMode.setEnabled(true); var func = ajaxRequest; setInterval(func, time); }

function onPause() { cordova.plugins.backgroundMode.disableWebViewOptimizations(); var func = ajaxRequest; setInterval(func, time); }

Doesn’t even work by inserting disableWebViewOptimizations() in Cordova's pause event.

peitschie commented 11 months ago

@riccardocostantini I've been using this version instead: https://bitbucket.org/TheBosZ/cordova-plugin-run-in-background/src/master/

The exact code that works for me is:

function onDeviceReady() {
  cordova.plugins.backgroundMode.enable();
  cordova.plugins.backgroundMode.on("activate", () => {
    cordova.plugins.backgroundMode.disableWebViewOptimizations();
  });
  cordova.plugins.backgroundMode.disableWebViewOptimizations();
}

Note, there's still an Android power optimization (doze mode) that kicks in after 40mins-1hr which will throttle this even then. Additionally, if your app uses too much CPU, you might be throttled by Android.

Are you seeing the exact issue here where the interval stops after 5mins?

riccardocostantini commented 11 months ago

@peitschie I've been using this version: https://bitbucket.org/TheBosZ/cordova-plugin-run-in-background/src/master/ and i reproduced your code but after 5 minutes set interval stops working. The process is active but the js no longer works. This is my version of android: android 10.1.1 First Ajax-Request in background: Date: Mon, 13 Nov 2023 10:30:18 GMT Last Ajax-Request in background: Date: Mon, 13 Nov 2023 10:34:53 GMT @peitschie

riccardocostantini commented 11 months ago

@peitschie any news?

peitschie commented 11 months ago

I have no obvious answers sorry @riccardocostantini

Not sure if there's something different about your environment to my own test setup to cause this, but this kind of power thing is very difficult to guess.

riccardocostantini commented 11 months ago

What version of java are you using? @peitschie

bonanhel commented 11 months ago

Can you try this version?

https://github.com/Mforcen/cordova-plugin-background-mode

riccardocostantini commented 11 months ago

No, i try this https://bitbucket.org/TheBosZ/cordova-plugin-run-in-background/src/master/ or this https://github.com/katzer/cordova-plugin-background-mode. Have you tried this version (https://github.com/Mforcen/cordova-plugin-background-mode)? @bonanhel

bonanhel commented 11 months ago

@riccardocostantini No, but my app is working fine..

did you declare the service type on xml?

https://developer.android.com/about/versions/14/changes/fgs-types-required

riccardocostantini commented 11 months ago

@bonanhel You mean that in Android XML? "android.permission.FOREGROUND_SERVICE" Does your setinterval(JS) work even after the 5 minutes the app is in the background? Because after 5 minutes the app is in the background the setinterval(JS) stops working.

bonanhel commented 11 months ago

@riccardocostantini Yes, on Android 10+ you must declare the foreground service type. For example GPS, Media etc..

Yes, all my timers are working fine on background (Using foreground service)

riccardocostantini commented 11 months ago

Thanks for the answer @bonanhel. I add this in manifest xml: android:name="android.permission.ACCESS_BACKGROUND_SERVICE" android:name="android.permission.FOREGROUND_SERVICE" android:name="android.permission.WAKE_LOCK" This is my index js:

document.addEventListener("deviceready", onDeviceReady, false);

function onDeviceReady() { cordova.plugins.backgroundMode.setEnabled(true); setInterval(function () { console.log("OK"); }, 1000); }

But after 5 minutes setInterval stop working in background. Do you have any suggestions?

bonanhel commented 11 months ago

You need to declare the foreground service for the plugin within the element. You'll find a line like this:

<service android:name="de.appplant.cordova.plugin.background.ForegroundService" />

However, you must declare it like this:

<service android:foregroundServiceType="specialUse" android:name="de.appplant.cordova.plugin.background.ForegroundService" /> The foregroundServiceType must be one of the following:

camera connectedDevice dataSync health location mediaPlayback mediaProjection microphone phoneCall remoteMessaging shortService specialUse systemExempted

On js

      cordova.plugins.backgroundMode.setDefaults({
              title: 'Your App',
              text: 'Description'
          });

    cordova.plugins.backgroundMode.requestForegroundPermission();
    cordova.plugins.backgroundMode.setEnabled(true);
    cordova.plugins.backgroundMode.overrideBackButton();

    cordova.plugins.backgroundMode.on('activate', function() {
        cordova.plugins.backgroundMode.disableWebViewOptimizations();
        setInterval(function () {
            console.log('OK');
            }, 1000);
    });

    cordova.plugins.backgroundMode.on('deactivate', function() {
    });

    cordova.plugins.backgroundMode.disableBatteryOptimizations();
riccardocostantini commented 11 months ago

@bonanhel thanks for the response. But I not view in your comment this line: You'll find a line like this:

bonanhel commented 11 months ago

@riccardocostantini Sorry for the confusion earlier, it seems there was an issue with the code formatting in the GitHub editor. Could you please take another look?

riccardocostantini commented 11 months ago

@bonanhel Thanks for the answer. Now I see everything. Which version did you use?

riccardocostantini commented 11 months ago

@bonanhel When i add

<service android:foregroundServiceType="specialUse" android:name="de.appplant.cordova.plugin.background.ForegroundService" />

this error occurred:

Error: Element service#de.appplant.cordova.plugin.background.ForegroundService at AndroidManifest.xml:13:9-91 duplicated with element declared at AndroidManifest.xml:12:9-134

bonanhel commented 11 months ago

@riccardocostantini Yes, plugin also added this line .

make a code search on plugins directory for this line and update it there. Then don’t add it on xml and let plugin to append it

riccardocostantini commented 11 months ago

@bonanhel My androidmanifest: <service android:foregroundServiceType="dataSync|location" android:name="de.appplant.cordova.plugin.background.ForegroundService" />

my js:


document.addEventListener("deviceready", onDeviceReady, false);

function onDeviceReady() {
  cordova.plugins.backgroundMode.setDefaults({
    title: "Your App",
    text: "Description",
  });
  cordova.plugins.backgroundMode.setEnabled(true);
  cordova.plugins.backgroundMode.overrideBackButton();
  cordova.plugins.backgroundMode.on("activate", function () {
    cordova.plugins.backgroundMode.disableWebViewOptimizations();
    setInterval(function () {
      console.log("OK");
    }, 1000);
  });
  cordova.plugins.backgroundMode.on("deactivate", function () {});

  cordova.plugins.backgroundMode.disableBatteryOptimizations();
}

First console.log on chrome inspect device: 12:39:41.407 OK Last console.log on chrome inspect device: 12:44:41.065 OK

riccardocostantini commented 11 months ago

@bonanhel any news? Why is it not working?

bonanhel commented 11 months ago

@riccardocostantini Sorry, can’t help. It works here. I guess you need to check further your Android app configuration.

riccardocostantini commented 11 months ago

@bonanhel thanks for response. What kind of configuration are you talking about?

riccardocostantini commented 11 months ago

@bonanhel with your directives, the problem arises when I go to kill the app, because when I normally close the app from the home button, it works properly.

peitschie commented 11 months ago

@riccardocostantini killing the app is something done by Android. There's no protection or recovery guaranteed from this action by the user. See for models and details: https://dontkillmyapp.com/

riccardocostantini commented 11 months ago

@peitschie the method onDestroy() cause the process ended.