MJ2410
MJ2410

Reputation: 518

setInterval/setTimer not running after 5 mins of background time - Ionic

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 (https://github.com/katzer/cordova-plugin-background-mode), 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?

*** Update ****

Tried to invoke the function every 4 mins in the background to keep running which didn't work for me:

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

     this.backgroundMode.on('activate').subscribe(() => {
        setInterval(function () {
          this.startTimerCounter();
        }, 240000);
      })
      }
    }

Upvotes: 0

Views: 1553

Answers (2)

tf z
tf z

Reputation: 61

Just for Android:

if you don't want use this plugin : cordova-plugin-background and you have power change your android app code. Here is a method, and the end i tell you why cordova-plugin-background don't work (this is my guess, and must read it,if you use this answer).

this is android code.

// first you need create android `jsbridge`
  webView.addJavascriptInterface(InJavaScriptLocalObj(), "android")
      @Suppress("unused")
  inner class InJavaScriptLocalObj {
/**
* @ script you want to run function in js code
  @ interval time unit is millisecond
*/
 @JavascriptInterface
 fun setInterval(script: String, interval: Long): Int {
            // TODO check need to cancel
            if (hashMap.size > 0) {
                hashMap.forEach { it.value.cancel() }
                hashMap.clear()
            }
            val jobSeek = scopeMain.launch {
                while (isActive) {
                    [email protected] {
                       //Run the script in here.
                        webView.evaluateJavascript(script),
                            object : ValueCallback<String?> {
                                override fun onReceiveValue(value: String?) {
                                    if (!value.isNullOrEmpty()){
                                
                                    }
                                }
                            })
                    }
                    delay(interval)
                }
            }
            val id = hashMap.size + 1

            hashMap[id] = jobSeek
            return id
        }

        @JavascriptInterface
        fun clearInterval(id: Int) {
            hashMap[id]?.cancel()
            hashMap.remove(id)
        }
  }

this is JS code


android.setInterval(`interval()`)

function interval(){}

// if you use vue or other frame work,you need do this

window.interval=interval()

// My function in pineapple,so i do this
window.interval=useCounterStore().interval()

But you need to pay attention:

In background,android webview can't update view, can't request network, just can run that function by native called.


why cordova-plugin-background don't work?

you need to tell the user set app IgnoringBatteryOptimizations.

Here is a method https://stackoverflow.com/a/62088633/6631835

Upvotes: 0

Younes Zaidi
Younes Zaidi

Reputation: 1190

use this plugin : cordova-plugin-background

document.addEventListener('deviceready', function () {

            cordova.plugins.backgroundMode.enable();

             cordova.plugins.backgroundMode.onactivate = function () {

               setInterval(function () {

                  YourFunctionHere();

                }, 300000);
             }
           }, false);

your app it' well refrech in backround every 5 Min

300000 millisecond = 5 min

Upvotes: 0

Related Questions