setInterval/setTimer 在后台时间 5 分钟后未运行 - Ionic

问题描述 投票:0回答:2

我需要一个计时器,它应该在达到特定的用户设置值后发出通知(我使用的是onesignal API通知)。

例如,如果用户设置值 7 分钟,则计时器应在 7 分钟后发送通知。用户可以设置的时间范围为 1-59 分钟。但即使使用后台模式插件(https://github.com/katzer/cordova-plugin-background-mode),我也无法让 setInterval/setTimeout 函数在 5 分钟后工作。

尝试使用递归setTimeout方法:

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

尝试使用setInterval方法:

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

顶部的后台激活通知,我可以看到后台模式已激活。但计时器似乎在 5 分钟后就不再运行了。

知道如何解决这个问题吗?

*** 更新****

尝试在后台每 4 分钟调用一次该函数以继续运行,但这对我来说不起作用:

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);
      })
      }
    }
javascript android cordova timer ionic4
2个回答
0
投票

使用这个插件:

cordova-plugin-background

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

            cordova.plugins.backgroundMode.enable();

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

               setInterval(function () {

                  YourFunctionHere();

                }, 300000);
             }
           }, false);

你的应用程序每 5 分钟就会在后台刷新一次

300000 毫秒 = 5 分钟


0
投票

仅适用于安卓:

如果您不想使用此插件:cordova-plugin-background 并且您有权更改您的 Android 应用程序代码。这是一个方法,最后我告诉你为什么

cordova-plugin-background
不起作用(这是我的猜测,如果你使用这个答案,必须阅读它)。

这是Android代码。

// 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)
        }
  }

这是JS代码


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

但是你需要注意:

在后台,android webview 无法更新视图,无法请求网络,只能通过本机调用来运行该功能。


为什么

cordova-plugin-background
不起作用?

你需要告诉用户设置应用程序

IgnoringBatteryOptimizations

这是一个方法https://stackoverflow.com/a/62088633/6631835

© www.soinside.com 2019 - 2024. All rights reserved.