cordova-plugin-background-mode icon indicating copy to clipboard operation
cordova-plugin-background-mode copied to clipboard

SetInterval/SetTimeout stops working after 5 mins

Open meghajayakumar opened this issue 4 years ago • 31 comments

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?

meghajayakumar avatar Jul 10 '20 14:07 meghajayakumar

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

danielehrhardt avatar Sep 15 '20 14:09 danielehrhardt

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.

rcasunshare avatar Sep 21 '20 23:09 rcasunshare

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?

Gabri1495 avatar Nov 26 '20 13:11 Gabri1495

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.

peitschie avatar Jun 17 '22 04:06 peitschie

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

x842013824 avatar Aug 03 '23 03:08 x842013824

@katzer

riccardocostantini avatar Nov 13 '23 08:11 riccardocostantini

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.

riccardocostantini avatar Nov 13 '23 08:11 riccardocostantini

@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?

peitschie avatar Nov 13 '23 10:11 peitschie

@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 avatar Nov 13 '23 10:11 riccardocostantini

@peitschie any news?

riccardocostantini avatar Nov 14 '23 18:11 riccardocostantini

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.

peitschie avatar Nov 14 '23 22:11 peitschie

What version of java are you using? @peitschie

riccardocostantini avatar Nov 15 '23 06:11 riccardocostantini

Can you try this version?

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

bonanhel avatar Nov 15 '23 07:11 bonanhel

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

riccardocostantini avatar Nov 15 '23 07:11 riccardocostantini

@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

bonanhel avatar Nov 15 '23 07:11 bonanhel

@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.

riccardocostantini avatar Nov 15 '23 07:11 riccardocostantini

@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)

bonanhel avatar Nov 15 '23 07:11 bonanhel

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?

riccardocostantini avatar Nov 15 '23 07:11 riccardocostantini

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();

bonanhel avatar Nov 15 '23 08:11 bonanhel

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

riccardocostantini avatar Nov 15 '23 08:11 riccardocostantini

@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?

bonanhel avatar Nov 15 '23 08:11 bonanhel

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

  • https://bitbucket.org/TheBosZ/cordova-plugin-run-in-background/src/master/ ?
  • https://github.com/katzer/cordova-plugin-background-mode ?
  • https://github.com/Mforcen/cordova-plugin-background-mode ?

riccardocostantini avatar Nov 15 '23 10:11 riccardocostantini

@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

riccardocostantini avatar Nov 15 '23 11:11 riccardocostantini

@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

bonanhel avatar Nov 15 '23 11:11 bonanhel

@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 avatar Nov 15 '23 11:11 riccardocostantini

@bonanhel any news? Why is it not working?

riccardocostantini avatar Nov 16 '23 10:11 riccardocostantini

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

bonanhel avatar Nov 16 '23 14:11 bonanhel

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

riccardocostantini avatar Nov 17 '23 08:11 riccardocostantini

@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.

riccardocostantini avatar Nov 22 '23 08:11 riccardocostantini

@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/

peitschie avatar Nov 22 '23 09:11 peitschie