ionic-team / capacitor-background-runner Goto Github PK
View Code? Open in Web Editor NEWLicense: Other
License: Other
I am developing a specialized alarm clock for a specific task. I ran into a problem: a task in the background can be executed once every 15 minutes, this is an extremely long period.
I know that the classic android application has an AlarmManager class, can I use this in my capacitor-application?
FAILURE: Build completed with 9 failures.
Could not resolve all dependencies for configuration ':app:debugRuntimeClasspath'.
The project declares repositories, effectively ignoring the repositories you have declared in the settings.
You can figure out how project repositories are declared by configuring your build to fail on project repositories.
See https://docs.gradle.org/7.5/userguide/declaring_repositories.html#sub:fail_build_on_project_repositories for details.
Could not find :android-js-engine-release:.
Required by:
project :app > project :capacitor-background-runner
Run with --info or --debug option to get more log output.
Run with --scan to get full insights.
Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:checkDebugAarMetadata'.
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:38)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:69)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:327)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:314)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:307)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:293)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:417)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:339)
at org.gradle.execution.plan.DefaultPlanExecutor.process(DefaultPlanExecutor.java:96)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph.executeWithServices(DefaultTaskExecutionGraph.java:140)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph.execute(DefaultTaskExecutionGraph.java:125)
at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:39)
at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:51)
at org.gradle.execution.BuildOperationFiringBuildWorkerExecutor$ExecuteTasks.call(BuildOperationFiringBuildWorkerExecutor.java:54)
at org.gradle.execution.BuildOperationFiringBuildWorkerExecutor$ExecuteTasks.call(BuildOperationFiringBuildWorkerExecutor.java:43)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
at org.gradle.execution.BuildOperationFiringBuildWorkerExecutor.execute(BuildOperationFiringBuildWorkerExecutor.java:40)
at org.gradle.internal.build.DefaultBuildLifecycleController.lambda$executeTasks$7(DefaultBuildLifecycleController.java:161)
at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:247)
at org.gradle.internal.model.StateTransitionController.lambda$tryTransition$7(StateTransitionController.java:174)
at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:44)
at org.gradle.internal.model.StateTransitionController.tryTransition(StateTransitionController.java:174)
at org.gradle.internal.build.DefaultBuildLifecycleController.executeTasks(DefaultBuildLifecycleController.java:161)
at org.gradle.internal.build.DefaultBuildWorkGraphController$DefaultBuildWorkGraph.runWork(DefaultBuildWorkGraphController.java:156)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:249)
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:109)
at org.gradle.composite.internal.DefaultBuildController.doRun(DefaultBuildController.java:164)
at org.gradle.composite.internal.DefaultBuildController.access$000(DefaultBuildController.java:45)
at org.gradle.composite.internal.DefaultBuildController$BuildOpRunnable.run(DefaultBuildController.java:183)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
Caused by: org.gradle.api.internal.artifacts.configurations.ResolveExceptionWithHints: Could not resolve all dependencies for configuration ':app:debugRuntimeClasspath'.
The project declares repositories, effectively ignoring the repositories you have declared in the settings.
You can figure out how project repositories are declared by configuring your build to fail on project repositories.
See https://docs.gradle.org/7.5/userguide/declaring_repositories.html#sub:fail_build_on_project_repositories for details.
at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.failuresWithHint(DefaultConfiguration.java:764)
at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.rethrowFailure(DefaultConfiguration.java:1518)
at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.access$3700(DefaultConfiguration.java:159)
at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$DefaultResolutionHost.rethrowFailure(DefaultConfiguration.java:2174)
at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$ConfigurationFileCollection.visitContents(DefaultConfiguration.java:1496)
at org.gradle.api.internal.file.AbstractFileCollection.visitStructure(AbstractFileCollection.java:375)
at org.gradle.api.internal.file.CompositeFileCollection.lambda$visitContents$0(CompositeFileCollection.java:119)
at org.gradle.api.internal.file.collections.UnpackingVisitor.add(UnpackingVisitor.java:64)
at org.gradle.api.internal.file.collections.UnpackingVisitor.add(UnpackingVisitor.java:89)
at org.gradle.api.internal.file.DefaultFileCollectionFactory$ResolvingFileCollection.visitChildren(DefaultFileCollectionFactory.java:333)
at org.gradle.api.internal.file.CompositeFileCollection.visitContents(CompositeFileCollection.java:119)
at org.gradle.api.internal.file.AbstractFileCollection.visitStructure(AbstractFileCollection.java:375)
at org.gradle.api.internal.file.CompositeFileCollection.lambda$visitContents$0(CompositeFileCollection.java:119)
at org.gradle.api.internal.tasks.PropertyFileCollection.visitChildren(PropertyFileCollection.java:48)
at org.gradle.api.internal.file.CompositeFileCollection.visitContents(CompositeFileCollection.java:119)
at org.gradle.api.internal.file.AbstractFileCollection.visitStructure(AbstractFileCollection.java:375)
at org.gradle.internal.fingerprint.impl.DefaultFileCollectionSnapshotter.snapshot(DefaultFileCollectionSnapshotter.java:51)
at org.gradle.internal.execution.fingerprint.impl.DefaultInputFingerprinter$InputCollectingVisitor.visitInputFileProperty(DefaultInputFingerprinter.java:131)
at org.gradle.api.internal.tasks.execution.TaskExecution.visitRegularInputs(TaskExecution.java:322)
at org.gradle.internal.execution.fingerprint.impl.DefaultInputFingerprinter.fingerprintInputProperties(DefaultInputFingerprinter.java:61)
at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.captureExecutionStateWithOutputs(CaptureStateBeforeExecutionStep.java:193)
at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.lambda$captureExecutionState$1(CaptureStateBeforeExecutionStep.java:141)
at org.gradle.internal.execution.steps.BuildOperationStep$1.call(BuildOperationStep.java:37)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
at org.gradle.internal.execution.steps.BuildOperationStep.operation(BuildOperationStep.java:34)
at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.captureExecutionState(CaptureStateBeforeExecutionStep.java:130)
at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.lambda$execute$0(CaptureStateBeforeExecutionStep.java:75)
at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:75)
at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:50)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.executeWithNoEmptySources(SkipEmptyWorkStep.java:254)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:91)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:56)
at org.gradle.internal.execution.steps.RemoveUntrackedExecutionStateStep.execute(RemoveUntrackedExecutionStateStep.java:32)
at org.gradle.internal.execution.steps.RemoveUntrackedExecutionStateStep.execute(RemoveUntrackedExecutionStateStep.java:21)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)
at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:43)
at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:31)
at org.gradle.internal.execution.steps.AssignWorkspaceStep.lambda$execute$0(AssignWorkspaceStep.java:40)
at org.gradle.api.internal.tasks.execution.TaskExecution$4.withWorkspace(TaskExecution.java:281)
at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:40)
at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:30)
at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:37)
at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:27)
at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:44)
at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:33)
at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:76)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:139)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:128)
at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:77)
at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
Caused by: org.gradle.api.internal.artifacts.configurations.ResolveExceptionWithHints: Could not resolve all dependencies for configuration ':app:debugRuntimeClasspath'.
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:69)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:327)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:314)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:307)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:293)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:417)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:339)
at org.gradle.execution.plan.DefaultPlanExecutor.process(DefaultPlanExecutor.java:96)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph.executeWithServices(DefaultTaskExecutionGraph.java:140)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph.execute(DefaultTaskExecutionGraph.java:125)
at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:39)
at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:51)
at org.gradle.execution.BuildOperationFiringBuildWorkerExecutor$ExecuteTasks.call(BuildOperationFiringBuildWorkerExecutor.java:54)
at org.gradle.execution.BuildOperationFiringBuildWorkerExecutor$ExecuteTasks.call(BuildOperationFiringBuildWorkerExecutor.java:43)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
at org.gradle.execution.BuildOperationFiringBuildWorkerExecutor.execute(BuildOperationFiringBuildWorkerExecutor.java:40)
at org.gradle.internal.build.DefaultBuildLifecycleController.lambda$executeTasks$7(DefaultBuildLifecycleController.java:161)
at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:247)
at org.gradle.internal.model.StateTransitionController.lambda$tryTransition$7(StateTransitionController.java:174)
at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:44)
at org.gradle.internal.model.StateTransitionController.tryTransition(StateTransitionController.java:174)
at org.gradle.internal.build.DefaultBuildLifecycleController.executeTasks(DefaultBuildLifecycleController.java:161)
at org.gradle.internal.build.DefaultBuildWorkGraphController$DefaultBuildWorkGraph.runWork(DefaultBuildWorkGraphController.java:156)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:249)
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:109)
at org.gradle.composite.internal.DefaultBuildController.doRun(DefaultBuildController.java:164)
at org.gradle.composite.internal.DefaultBuildController.access$000(DefaultBuildController.java:45)
at org.gradle.composite.internal.DefaultBuildController$BuildOpRunnable.run(DefaultBuildController.java:183)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
Caused by: org.gradle.internal.resolve.ModuleVersionNotFoundException: Could not find :android-js-engine-release:.
Required by:
project :app > project :capacitor-background-runner
==============================================================================
Only on Android, the device receives the notification but does not open the application when tapping on the notification.
On ios the behavior is as expected
scheduleDate.setSeconds(scheduleDate.getSeconds() + 20);
CapacitorNotifications.schedule([
{
id: 100,
title: "Enterprise Background Runner",
body: "Received silent push notification",
scheduleAt: scheduleDate,
},
]);
resolve();
Nowhere in the documentation does it explain what interval is (milliseconds or minutes) and does not define the default value if interval is not set. Documentation also does not specify what other parameters can use used to set into capacitor.config.ts for Background.runner.
"@capacitor/background-runner": "^1.0.5",
@capacitor/cli: 5.0.5
@capacitor/core: 5.0.5
@capacitor/android: 5.0.5
@capacitor/ios: 5.0.5
Android, ios
I'm using capacitor in a ionic+ stencil application
I'm not able to start correctly BackgroundRunner plugin
This is my runner.js location
this is my capacitor.config.ts
{
"appId": "com.myapp.app",
"appName": "MyApp",
"webDir": "www",
"server": {
"androidScheme": "https"
},
"ios": {
"handleApplicationNotifications": false
},
"plugins":{
"BackgroundRunner": {
"label": "com.myapp.app.check",
"src": "runner.js",
"event": "checkIn",
"repeat": true,
"interval": 2,
"autoStart": false
}
}
}
And I have this error
Is a problem cause by a wrong path for the runner.js file or something else?
I'm not able to make it work!
Plugin runs correctly
In my background.js
file i have 1 event listener defined:
addEventListener("myEvent", (details) => {
console.log("do something to update the system here:", details);
details.completed();
});
In my capacitor.config.ts
i have Background Runner configured as follows:
BackgroundRunner: {
label: "com.myappname.background.task",
src: "background.js",
event: "myEvent",
repeat: false,
interval: 2,
autoStart: false,
}
In my React App i am using the @capacitor/app
plugin to monitor appStateChange
and am triggering myEvent
based on the isActive
status as follows:
App.addListener('appStateChange', async ({ isActive }) => {
if(!isActive) {
await BackgroundRunner.dispatchEvent({
label: "com.myappname.background.task",
event: "myEvent",
details: {foo: 'bar'},
});
}
});
Results in the following errors when running the app on an actual iOS device running iOS v16.5.1(c) after putting the app into the background:
starting runner and loading contexts...
2023-07-29 18:39:07.567069-0400 App[39138:2062252] *** Assertion failure in -[CLLocationManager setAllowsBackgroundLocationUpdates:], CLLocationManager.m:1033
2023-07-29 18:39:07.567933-0400 App[39138:2062252] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: !stayUp || CLClientIsBackgroundable(internal->fClient) || _CFMZEnabled()'
*** First throw call stack:
(0x1c0b98cb4 0x1b9c343d0 0x1bb32a56c 0x1cc5b1f28 0x10135d0d8 0x10135ce1c 0x101359274 0x10134e8a0 0x10134b400 0x10134c814 0x101352820 0x10134a600 0x101b7c520 0x101b7e038 0x101b92670 0x101b92e34 0x220918da0 0x220918b7c)
libc++abi: terminating due to uncaught exception of type NSException
What am i missing?
We've created a scheduled runner:
BackgroundRunner: {
label: '<not relevant>',
src: 'runners/runner.js',
event: 'handleNotifications',
repeat: true,
interval: 1,
autoStart: true,
}
inside the event handler we try to use fetch as follows:
fetch("https://jsonplaceholder.typicode.com/todos/1").then((data) => {
console.log("fetch ok");
resolve();
}).catch((err) => {
console.log("fetch failed");
console.log(err);
reject();
});
Only the catch block gets executed, but the err parameter is always empty.
This was tested with 2 different devices, both with Android 13 and with proper internet connection.
Could you please provide any advice on how to solve or further diagnose this issue?
My android app is constantly crashing when I call dispatchEvent
. It doesn't crash every time. It's about 70% fail. I can't speak for iOS since the company where I work isn't developing an iOS version of our app. I also had to move the android-js-engine-release.aar
file in node_modules
and move it into ./android/app/libs/android-js-engine-release.aar
in order to build the app with background-runner. It seems that the issue is coming from there based on logs in LogCat.
Using: Ionic React
Background runner version: 1.0.5
Android emulator device: Pixel 5
Android emulator OS: Android 11 / API 30
Compile version: 33
Target version: 30
Stack Trace from Android Studio (edited to remove app name):
Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x30 in tid 11397 (DefaultDispatch), pid 11281 (---)
pid-11405
pid: 11281, tid: 11397, name: DefaultDispatch >>> --- <<<
#00 pc 0000000000095268 /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/lib/arm64/libandroid_js_engine.so (BuildId: 23642ddb9d662eef5ccc60ef02e70cf602a60b91)
#01 pc 000000000007334c /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/lib/arm64/libandroid_js_engine.so (BuildId: 23642ddb9d662eef5ccc60ef02e70cf602a60b91)
#02 pc 0000000000072f88 /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/lib/arm64/libandroid_js_engine.so (BuildId: 23642ddb9d662eef5ccc60ef02e70cf602a60b91)
#03 pc 000000000007217c /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/lib/arm64/libandroid_js_engine.so (JS_DefineProperty+1276) (BuildId: 23642ddb9d662eef5ccc60ef02e70cf602a60b91)
#04 pc 0000000000066224 /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/lib/arm64/libandroid_js_engine.so (JS_NewContextRaw+920) (BuildId: 23642ddb9d662eef5ccc60ef02e70cf602a60b91)
#05 pc 00000000000663d4 /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/lib/arm64/libandroid_js_engine.so (JS_NewContext+20) (BuildId: 23642ddb9d662eef5ccc60ef02e70cf602a60b91)
#06 pc 0000000000058a7c /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/lib/arm64/libandroid_js_engine.so (Context::Context(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&, JSRuntime*, _JNIEnv*, _jobject*)+152) (BuildId: 23642ddb9d662eef5ccc60ef02e70cf602a60b91)
#07 pc 000000000005d6d8 /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/lib/arm64/libandroid_js_engine.so (Java_io_ionic_android_1js_1engine_Context_initContext+324) (BuildId: 23642ddb9d662eef5ccc60ef02e70cf602a60b91)
#15 pc 0000000000230ca8 [anon:dalvik-classes.dex extracted in memory from /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/base.apk] (io.ionic.android_js_engine.Context.<init>+52)
#18 pc 000000000023168e [anon:dalvik-classes.dex extracted in memory from /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/base.apk] (io.ionic.android_js_engine.Runner.createContext+30)
#21 pc 00000000000265d2 [anon:dalvik-classes2.dex extracted in memory from /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/base.apk!classes2.dex] (io.ionic.backgroundrunner.plugin.BackgroundRunner.initContext+182)
#24 pc 0000000000026c9c [anon:dalvik-classes2.dex extracted in memory from /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/base.apk!classes2.dex] (io.ionic.backgroundrunner.plugin.BackgroundRunner.start+36)
#27 pc 00000000000268aa [anon:dalvik-classes2.dex extracted in memory from /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/base.apk!classes2.dex] (io.ionic.backgroundrunner.plugin.BackgroundRunner.execute+134)
#30 pc 000000000002611a [anon:dalvik-classes2.dex extracted in memory from /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/base.apk!classes2.dex] (io.ionic.backgroundrunner.plugin.BackgroundRunnerPlugin$dispatchEvent$1.invokeSuspend+122)
#33 pc 000000000029d1fa [anon:dalvik-classes.dex extracted in memory from /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/base.apk] (kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith+42)
#36 pc 00000000002e3558 [anon:dalvik-classes.dex extracted in memory from /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/base.apk] (kotlinx.coroutines.DispatchedTask.run+444)
#39 pc 000000000031f902 [anon:dalvik-classes.dex extracted in memory from /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/base.apk] (kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely+2)
#42 pc 000000000031e5e6 [anon:dalvik-classes.dex extracted in memory from /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/base.apk] (kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask+34)
#45 pc 000000000031e714 [anon:dalvik-classes.dex extracted in memory from /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/base.apk] (kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker+56)
#48 pc 000000000031e6c4 [anon:dalvik-classes.dex extracted in memory from /data/app/~~3YKbJCkYNizHvKvWmPFnow==/---6rPajoauhEUqOtrJbLn0YA==/base.apk] (kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run)
channel '80bf992 --/--.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
We're also seeing lots of messages for Memory leak: 32 bytes lost in 1 block
from android-js-engine-qjs
Following the documentation it is not clear where to place the .js file. Even with several tests you always get the following error (in an Ionic+Angular project).
`โก๏ธ To Native -> BackgroundRunner dispatchEvent 83467667
starting runner and loading contexts...
error executing task: runnerError(reason: "source file not found")
ERROR MESSAGE: {"errorMessage":"runnerError(reason: "source file not found")","message":"runnerError(reason: "source file not found")"}
โก๏ธ [error] - {"errorMessage":"runnerError(reason: "source file not found")","message":"runnerError(reason: "source file not found")"}
โก๏ธ [log] - Errore in sync, processo terminato. {"errorMessage":"runnerError(reason: "source file not found")"}
To Native Cordova -> BackgroundMode disable BackgroundMode1323252294 ["options": []]`
The API description (https://capacitorjs.com/docs/next/apis/background-runner#geolocation-1) states:
CapacitorGeolocation.getCurrentLocation()
whereas in the code is:
const location = await CapacitorGeolocation.getCurrentPosition();
what is correct? In my case neither works. First gives the error: no a function (in the log) second a full stack of errors and then then app stops.
After installing @capacitor/[email protected]
and setting up, any appStateChange
listeners no longer get executed on android
Ionic:
Ionic CLI : 7.1.1 (~/.nvm/versions/node/v20.5.0/lib/node_modules/@ionic/cli)
Capacitor:
Capacitor CLI : 5.7.4
@capacitor/android : 5.7.4
@capacitor/core : 5.7.4
@capacitor/ios : 5.7.4
Utility:
cordova-res : not installed globally
native-run : 2.0.1
System:
NodeJS : v20.5.0 (~/.nvm/versions/node/v20.5.0/bin/node)
npm : 10.2.4
OS : macOS Unknown
Example code
// capacitor.config.ts
plugins: {
BackgroundRunner: {
src: 'runners/background.js',
autoStart: true,
},
},
// background.js
// empty
// App.tsx
useEffect(() => {
App.addListener('appStateChange', ({ isActive }) => {
console.log('IS ACTIVE', isActive);
});
}, []);
After loading app, sending app to background then being to foreground, no events are triggered, no console log has need output
If I then uninstall background runner the exact some code executes as expected
Expected behaviour
appStateChange
is triggered as expected on app state change
There's no documentation about or what actionTypeId
is, does, and how to make it work
Hi there, I have following setup:
Info.plist:
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>de.domain.app.background.task</string>
</array>
AppDelegate:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
BackgroundRunnerPlugin.registerBackgroundTask()
BackgroundRunnerPlugin.handleApplicationDidFinishLaunching(launchOptions: launchOptions)
return true
}
capacitor.config.ts
plugins: {
CapacitorCookies: {
enabled: true,
},
BackgroundRunner: {
label: 'de.domain.app.background.task',
src: 'capacitor/background-task.js',
event: 'myCustomEvent',
repeat: true,
interval: 5,
autoStart: false,
},
PushNotifications: {
"presentationOptions": ["badge", "sound", "alert"]
}
}
capacitor/background-task.js
addEventListener('myCustomEvent', (resolve, reject, args) => {
console.warn('do something to update the system here');
resolve();
});
addEventListener('myCustomEventWithReturnData', (resolve, reject, args) => {
try {
console.log('accepted this data: ' + JSON.stringify(args));
} catch (err) {
reject(err);
}
});
addEventListener('remoteNotification', (resolve, reject, args) => {
try {
console.warn('received silent push notification');
CapacitorNotifications.schedule([
{
id: 100,
title: 'Enterprise Background Runner',
body: 'Received silent push notification',
},
]);
resolve();
} catch (err) {
reject();
}
});
I adjusted webpack to copy capacitor/background-task.js
into dist folder.
After running cap-sync
and compiling application on device I get following ( correct ) log:
Scheduling de.domain.app.background.task
Unfortunately I do not see any other log in Xcode output. Is there any way to log if the background-task related javascript file could have been loaded from capacitor or if there is any errors on that?
It would be helpful to see, if the reference to the javascript file is broken after compiling for "dist" or if there is any other Issuesโฆ
Is there any advice you can share with me?
I am currently working on a project where I need to synchronize the local SQLite database of my app with the server. To achieve this, I am considering using a background runner plugin to fecth data from db and make POST requests. But not finding any way to acess sqlite db inside background task and make post requests.
I got the following error on iOS simulator:
CapacitorBackgroundRunner/BackgroundRunner.swift:160: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
The problematic code is this:
returnObj.toDictionary().forEach { key, value in. // Line 160
dict[String(describing: key)] = value
}
My code in the runner.js file:
addEventListener("fetchTest", async (resolve, reject, args) => {
try {
const res = await fetch("https://randomuser.me/api/");
console.log("res???", res);
resolve('plain text');
} catch (err) {
console.error(err);
reject(err);
}
});
C:\Windows\system32\cmd.exe /d /s /c mkdir -p $INIT_CWD/android/app/libs/ && cp -f android/src/main/libs/android-js-engine-release.aar $INIT_CWD/android/app/libs/
npm ERR! The syntax of the command is incorrect.
Hi,
i am trying to make this work for 3 days now, i am sure that is something small but i can't figure it out.
So here we go:
I am using it on iOS, i made my configurations as in the documentation
plugins: {
BackgroundRunner: {
label: 'ro.patrimonium.opla.task',
src: 'runners/runner.js',
event: 'checkIn',
repeat: true,
interval: 1,
autoStart: true,
},
...
}
import UIKit
import Capacitor
import CapacitorBackgroundRunner
import WonderPush
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
BackgroundRunnerPlugin.registerBackgroundTask()
BackgroundRunnerPlugin.handleApplicationDidFinishLaunching(launchOptions: launchOptions)
return true
}
addEventListener('checkIn', async (resolve, reject, args) => {
try {
if (args && typeof args.identifier !== 'undefined') {
await CapacitorKV.set('radius', args.radius)
await CapacitorKV.set('language', args.language)
await CapacitorKV.set('identifier', args.identifier)
}
const push = await CapacitorKV.get('identifier').value;
const radius = await CapacitorKV.get('radius').value
const language = await CapacitorKV.get('language').value
const location = await CapacitorGeolocation.getCurrentPosition();
// const location = {
// latitude: 45.565656,
// longitude: 45.5656565,
// };
console.log('this is my location ' + JSON.stringify(location))
const lat = location.latitude
const lng = location.longitude
const body = `identifier=${push}&radius=${radius}&language=${language}&lat=${lat}&lng=${lng}`;
console.log("location lat: " + lat);
console.log("location lng: " + lng);
console.log("language: " + language);
console.log("radius: " + radius);
const response = await fetch('https://my.endpoint', {
method: 'POST',
headers: {
Accept: 'application/json',
Authorization: `Bearer token`,
},
body: body
})
const message = await response.json()
console.log(JSON.stringify(message))
if (response.ok) {
console.log('Fetch is working!')
} else {
console.log('There is an error with the fetch function')
}
resolve(message)
} catch (err) {
console.error(err);
reject(err);
}
});
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>ro.patrimonium.opla.task</string>
</array>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We need to track your location while your device is locked in order to notify you when you are close to a monument.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>$(PRODUCT_NAME) uses location services to track your location in order to notify you when you are close to a monument</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>$(PRODUCT_NAME) uses location services to track your location in order to notify you when you are close to a monument</string>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>location</string>
<string>processing</string>
<string>remote-notification</string>
</array>
And now comes the interesting part, if i dispatch the event from the app when it's state is active all is working ok, i am getting the location and it is sent to the dashboard, but when a send the app in background i have 2 strange problems:
Did you have this problem ? Could somebody help me out please. I am using Ionic 7 with vuejs and capacitor 5
Thank you.
Hi there,
first of all, thanks for this awesome work !
Just give a try to this plugin (and app test) and i found some issues. On background.js there's missing try statement on line 156 and 168, and there's missing permissions for location in the manifest file.
I was able to test the app (on Android device) after this corrections and everything works except the geolocation. Seems that Android needs FINE location permission instead of COARSE as you can see below :
Made the correction to allow FINE location permission in order to run this geolocation event but then I experienced app crash... Tested on Huawei P20 lite / Android 9 and Samsung A41 / Android 12 brings me the same result. Running the app mulitple times make eventually the app showing the location result (1 time over a least 15 tests), but not sure why in this case everything works fine ...
You can see below the crash log from android studio when the event fails :
Thanks for your help !
I'm making an app that needs to update the user location to a server each 15 minutes I would like to know if it is viable to do with this plugin
I am trying to dispatch an event on receiving a notification while the app is closed.
On iOS this is demonstrated by adding BackgroundRunnerPlugin.dispatchEvent(event: "remoteNotification", eventArgs: userInfo)
to the AppDelegate
on didReceiveRemoteNotification
How is this achieved on android?
First of all thanks for the useful plugin!
I tried several hours with the existing documentation but ended up with the following situation:
Device: iPhone 11 Pro / iOS 16.6
capacitor.config.js
const config = { plugins: {}, ... }
...
config.plugins.BackgroundRunner = {
label: 'de.domain.appname.background',
src: 'background.js',
event: 'myCustomEvent',
repeat: true,
interval: 1,
autoStart: true
}
...
module.exports = config
background.js
addEventListener('myCustomEvent', (resolve, reject) => {
console.log('myCustomEvent called')
try {
let scheduleDate = new Date();
scheduleDate.setSeconds(scheduleDate.getSeconds() + 5);
CapacitorNotifications.schedule([
{
id: 100,
title: "Enterprise Background Runner",
body: "A test message from the Enterprise Background Runner",
scheduleAt: scheduleDate,
},
]);
resolve();
} catch (err) {
console.error(err);
reject(err);
}
});
App.vue (manuel dispatch)
BackgroundRunner.dispatchEvent({ label: 'de.domain.appname.background', event: 'myCustomEvent', details: {} })
What can I do as a next step for troubleshooting?
Hello there !
I know that the module is very recent, but I've been waiting for it for a while, I couldn't resist using it haha
Btw... I can't install it.
Here are the logs:
npm ERR! code 1
npm ERR! path C:\...\node_modules\@capacitor\background-runner
npm ERR! command failed
npm ERR! command C:\WINDOWS\system32\cmd.exe /d /s /c C:\Users\ADMINI~1\AppData\Local\Temp\postinstall-438df915.cmd
npm ERR! The command syntax is incorrect.
My config :
Win 11
npm 8.15.1
node 16.16.0
capacitor 5
I tried deleting the node_module to get a clean install, or install it using --force, but nothing.
Any ideas?
Thanks again for this plugin though!
Can't wait to use it
EDIT:
after npm update (9.8.0), new error:
npm ERR! code 1
npm ERR! path C:\...\node_modules\@capacitor\background-runner
npm ERR! command failed
npm ERR! command C:\WINDOWS\system32\cmd.exe /d /s /c mkdir -p $INIT_CWD/android/app/libs/ && cp -f android/src/main/libs/android-js-engine-release.aar $INIT_CWD/android/app/libs/
npm ERR! The command syntax is incorrect.
EDIT 2:
successful installation using WSL !
so there must be a problem in a variable that only works under Unix (I won't go any further)
I am using the Cordova-Bluetooth-plugin, I tried to connect a device using the background runner but couldn't use the window object in my runner.js file facing an error like the window is not defined. Is there any solution?
Hello, I have tried fetch API from background JS script. but not working.
addEventListener("fetchTest", async (resolve, reject, args) =>{
try {
console.log('fetch start');
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
if(response.ok){
console.log('fetch success');
}else{
console.log('fetch failed');
}
resolve();
} catch (error){
console.log('error caught');
console.error(error);
reject();
}
});
BackgroundRunner.dispatchEvent({
label: 'com.example.background.task',
event: 'fetchTest',
details: {},
});
I have tried this on Android Studio emulator (Android ver 13) but only the messages 'fetch start' and 'error caught' appears on logcat.
Thanks!
I am trying to schedule a local notification on android using a background runner from the docs. However nothing appears in the status bar after the allotted time. The background runner is working as i tested it for setting KV and retrieving it.
within background.js
addEventListener("notiTestEvent", async (resolve, reject, args) => {
try {
let scheduleDate = new Date();
scheduleDate.setSeconds(scheduleDate.getSeconds() + 5);
CapacitorNotifications.schedule([
{
id: 312,
title: "Enterprise Background Runner",
body: "A test message from the Enterprise Background Runner",
scheduleAt: scheduleDate,
},
]);
resolve();
} catch (err) {
console.log("err", err);
reject(err);
}
});
function calling event
const ontestbasic = async () => {
try {
await BackgroundRunner.dispatchEvent({
label: 'com.reacttest.app.task',
event: 'notiTestEvent',
details: {}
});
setValue('notification scheduled');
} catch (err) {
console.log('err', err);
}
};
Heres the repo if it helps
https://github.com/RaafatAburashed1/test-react-noti
The Response object returned by the fetch api is missing properties from MDN docs, mainly headers and the data methods (blob, text, etc).
I had some issues while following the docs and propose to add these relevant details:
The Info.plist in Xcode requires not only the background modes but also the labels as identifiers as information:
In the AppDelegate.swift file, an import statement must be added:
If relevant, location usage descriptions must be added to the Info.plist:
If the event handler return anything with resolve()
it must be a proper JS object:
Wondering why
"src": "background.js"
tries to find the file as public/background.js, as shown in observed logs.
It's an Ionic Angular Capacitor project, and I have no such folder in it at all.
In my background.js I have one simple event listener:
addEventListener("myCustomEvent", (details) => {
console.log("launched listener");
let scheduleDate = new Date();
CapacitorNotifications.schedule([
{
id: 1,
title: "Enterprise Background Runner",
body: "Received silent push notification",
scheduleAt: scheduleDate,
},
]);
console.log(scheduleDate);
details.completed();
});
and have my capacitor.config.ts defined as follows:
"BackgroundRunner": {
"label": "com.williegg.togetherminds.task",
"src": "background.js",
"event": "myCustomEvent",
"repeat": true,
"interval": 16,
"autoStart": true
}
When I open my app, and then navigate back to my phone home screen (with the app still being open in the background), the background worker always finishes succesfully, and the event listener I have defined is fired/executed correctly.
However, when I completely close my app (so my app itself is not running in the background), my background worker always fails. The worker does fire at the interval I have set, however it never actually executes my eventlistener (since the console.log I put at the beginning of the function never gets executed), and instead the android studio console says that the worker failed.
Is there something I am missing or is this a bug with the plugin?
The following is not clear:
For both iOS and Android, in what directory exactly is the background.js
file supposed to live for each platform respectively?
In capacitor.config.ts
is it possible to define multiple events in event: 'myCustomEvent'
?
Or is it that we can only define one event to execute automatically?
If we can indeed define more than one event, how do we configure autoStart
, interval
and repeat
for each?
Does interval: 2
mean 2 minutes? or 2 seconds?
When and where is it appropriate to execute an event that is defined in our runner?
Is it OK to do this inside the @capacitor/app
plugin's appStateChange
listener event?
For example:
App.addListener('appStateChange', async ({isActive}) => {
if (!isActive) {
// call the background runner here
await BackgroundRunner.dispatchEvent({
label: "com.myapp.background.task",
event: "myCustomEvent",
details: {foo: 'bar'},
});
}
});
Hello, when trying to use the background runner to print a message to the console, I see the following...
2023-07-25 12:53:11.682098-0400 App[1435:66319] [connection] nw_read_request_report [C1] Receive failed with error "Software caused connection abort"
2023-07-25 12:53:11.676307-0400 App[1435:66319] [connection] nw_read_request_report [C6] Receive failed with error "Socket is not connected"
2023-07-25 12:53:11.677610-0400 App[1435:66319] [connection] nw_read_request_report [C2] Receive failed with error "Socket is not connected"
2023-07-25 12:53:11.677770-0400 App[1435:66319] [connection] nw_read_request_report [C2] Receive failed with error "Socket is not connected"
2023-07-25 12:53:11.691876-0400 App[1435:66319] [quic] quic_conn_send_frames_for_key_state_block_invoke [C4.1.1.1:2] [-f824dbb0b13609a5] unable to request outbound data
2023-07-25 12:53:11.696412-0400 App[1435:66319] [quic] quic_conn_send_frames_for_key_state_block_invoke [C8.1.1.1:2] [-f7b53de6ad2c4401] unable to request outbound data
2023-07-25 12:53:11.696524-0400 App[1435:66319] [quic] quic_conn_send_frames_for_key_state_block_invoke [C8.1.1.1:2] [-f7b53de6ad2c4401] unable to request outbound data
2023-07-25 12:53:11.703410-0400 App[1435:66319] [] nw_endpoint_flow_fillout_data_transfer_snapshot copy_info() returned NULL
I am using the following packages...
"@capacitor/app": "^5.0.0",
"@capacitor/background-runner": "^1.0.0-rc.1"
I have setup my AppDelegate.swift, and background.js using the example app in this repo as inspiration, creating a simple listener called "heyo" that prints a message to the console, and returns data using details.completed({message: "heyo"});
My capacitor config is the following...
label: "..." src: "background.js", event: "heyo", repeat: true, interval: 3, autoStart: false,
With my label included in the info.plist BGTaskSchedulerPermittedIdentifiers.
I am running the app on a physical device running ios 16.4.
Any help to resolve this issue would be greatly appreciated! Thanks so much.
Following the step-by-step setup instructions, after I add the lines
BackgroundRunnerPlugin.registerBackgroundTask()
BackgroundRunnerPlugin.handleApplicationDidFinishLaunching(launchOptions: launchOptions)
to my AppDelegate.swift file, my IOS build in Xcode quickly fails with the error "Cannot find 'BackgroundRunnerPlugin' in scope".
The only way I have found to successfully build the project is to remove those two lines from my AppDelegate.swift file, which prevents the plugin from running.
What am I missing?
Hi,
I have a few apps that have a need to perform Bluetooth and File operations (e.g., read data from Bluetooth and write to a file) from a background task.
Do you have any roadmap or future plans to allow further extensibility to the APIs available within the background context here?
I'm watching this with great interest as my current approach when faced with a similar problem in the past on Android was to run a headless WebView within the WorkManager (this was on a cordova base). This looks like a great approach if it can be made more extensible.
I installed this plugin into a previously working Ionic / Capacitor project on MacOS, and it appeared to install fine.
However, after install, when I try to build the project for Android, I get the following error:
Task :capacitor-background-runner:compileDebugKotlin FAILED
Execution failed for task ':capacitor-background-runner:compileDebugKotlin'.
'compileDebugJavaWithJavac' task (current target is 11) and 'compileDebugKotlin' task (current target is 17) jvm target compatibility should be set to the same Java version.
This Pull Request appears to address the same issue: #14
Im trying to build an android app with Android extension in VScode. Now im experiencing this error
I have already made a file in android/app/libs/android-js-engine-release.aar also in background-runner folder, all set up in grandle-build modules. I did delete the grandle cache, cleaning build etc..
any thoughs please?
I'm not able to build android after adding this plugin.
I get repeated errors saying:
Caused by: org.gradle.api.internal.artifacts.ivyservice.DefaultLenientConfiguration$ArtifactResolveException: Could not resolve all files for configuration ':app:orDebugRuntimeClasspath'.
Caused by: org.gradle.internal.resolve.ModuleVersionNotFoundException: Could not find :android-js-engine-release:.
Environment:
"@capacitor/android": "^5.2.3"
Android Studio Giraffe | 2022.3.1
classpath 'com.android.tools.build:gradle:8.1.0'
Thanks for the help! Looking forward to using this plugin!
Hi,
I want to know how is it possible from runner.js. Call something in Angular/Capacitor application. e.g. if this background task wants to trigger a function in Angular/Capacitor to synchronize data, how can you do that? I tested using fetch to call a URL from the Capacitor app, but it doesn't work! and there is no other connection from runner.js to Capacitor app.
Best regards
Hello I'm testing on android actualli and i got this error:
This is my runner :
Here I got the location
The function calling the runner:
This function call the runner in background each x seconds and with the obtained loc it sends it to a server (this is actually only for testing)
In foreground it works correctly
Tested on realme gt neo 2
Hello,
I spent about two days on version 1.0.5 to fix the call to the fetch function in the event listener that was getting an error and the error was empty.
Hopefully the not LTS version 1.0.6-devxxxxx6000.0 works. I would like to raise the issue and ask: When will the LTS version for that fix come?
and the android-jw-engine-release.aar should be manually copied to android/libs/...
Greetings and thank you for this useful plugin ;)
Steps to reproduce the problem using an Android device:
After a while, event B will be triggered again instead of A.
Using the Capacitor Badge plugin is working fine from the application code. But it would be more useful to update the badge from the background runner. Is there any way to modify the badge?
Import / Require the module failed and resulted several Xcode errors.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.