我需要一个计时器,它应该在达到特定的用户设置值后发出通知(我使用的是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);
})
}
}
使用这个插件:
cordova-plugin-background
document.addEventListener('deviceready', function () {
cordova.plugins.backgroundMode.enable();
cordova.plugins.backgroundMode.onactivate = function () {
setInterval(function () {
YourFunctionHere();
}, 300000);
}
}, false);
你的应用程序每 5 分钟就会在后台刷新一次
300000 毫秒 = 5 分钟
仅适用于安卓:
如果您不想使用此插件: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
。