Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SetInterval/SetTimeout stops working after 5 mins #518

Open
meghajayakumar opened this issue Jul 10, 2020 · 31 comments
Open

SetInterval/SetTimeout stops working after 5 mins #518

meghajayakumar opened this issue Jul 10, 2020 · 31 comments

Comments

@meghajayakumar
Copy link

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
Copy link

@rcasunshare
Copy link

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
Copy link

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
Copy link

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
Copy link

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
Copy link

@katzer

@riccardocostantini
Copy link

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
Copy link

peitschie commented Nov 13, 2023

@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
Copy link

riccardocostantini commented Nov 13, 2023

@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
Copy link

@peitschie any news?

@peitschie
Copy link

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
Copy link

What version of java are you using? @peitschie

@bonanhel
Copy link

Can you try this version?

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

@bonanhel
Copy link

@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
Copy link

riccardocostantini commented Nov 15, 2023

@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
Copy link

@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
Copy link

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
Copy link

bonanhel commented Nov 15, 2023

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
Copy link

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

@bonanhel
Copy link

@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
Copy link

riccardocostantini commented Nov 15, 2023

@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
Copy link

@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
Copy link

@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
Copy link

@bonanhel any news?
Why is it not working?

@bonanhel
Copy link

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

@riccardocostantini
Copy link

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

@riccardocostantini
Copy link

@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
Copy link

@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
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants