DEV Community

Discussion on: Background Services in Ionic Capacitor

Collapse
 
mohsinhassan92 profile image
Mohsin Hassan

Hi Jscrambler, this really a nice tutorial, I just want to know, how to run a timer/ timer in angular.

Actually i wanna run this snippet periodically in the background:

      let location = await this.getCurrentPosition(); 
      // The location is fetched using Geolocation service.

      LocalNotifications.schedule({
        notifications: [
          {
            title: "Last Known Location",
            body: "Latitude: "+ location.coords.latitude +"Longitude: "+ location.coords.longitude,
            id: 1,
            schedule: { at: new Date(Date.now() + 1000 * 10) },
            sound: null,
            attachments: null,
            actionTypeId: "",
            extra: null
          }
        ]
      });   
Enter fullscreen mode Exit fullscreen mode

Thanks.

Collapse
 
karandpr profile image
Karan Gandhi • Edited

Ohai.
I wrote the original article for @jscrambler .
I can think of two ways.
You can achieve the functionality on Android using setInterval .

You will need unique id for LocalNotifications so we need to set a variable beforehand. Here is the code snippet for the functionality.

id: number = 0;
       let taskId = BackgroundTask.beforeExit(async () => {
          let notificationInterval = setInterval(async () => {
            let location = await this.getCurrentPosition();            
            LocalNotifications.schedule({
              notifications: [{
                title: "Last Known Location",
                body: "Latitude: " + location.coords.latitude + "Longitude: " + location.coords.longitude,
                id: this.id++,
                schedule: {
                  at: new Date(Date.now() + 1000 * 10)
                },
                sound: null,
                attachments: null,
                actionTypeId: "",
                extra: null
              }]
            });
            if (this.id > 10) {
              console.log("task Finished", this.id)
              clearInterval(notificationInterval);
              BackgroundTask.finish({
                taskId
              });

            } else {
              console.log("task in progress", this.id)
            }

          }, 2000)
        });

Apparently setInterval and setTimeout don't work in background on iOS.
So the other way is more hacky as shown in Ionic Docs. This should work on both Android and iOS.

      let taskId = BackgroundTask.beforeExit(async () => {
        let start = new Date().getTime();
        for (var i = 0; i < 1e18; i++) {
          if (this.id > 10) { 
            break;
          }
          if ((new Date().getTime() - start) % 2000 === 0) {
            let location = await this.getCurrentPosition();
            LocalNotifications.schedule({
              notifications: [{
                title: "Last Known Location",
                body: this.id + " Latitude: " + location.coords.latitude + "Longitude: " + location.coords.longitude,
                id: this.id++,
                schedule: {
                  at: new Date(Date.now() + 1000 * 10)
                },
                sound: null,
                attachments: null,
                actionTypeId: "",
                extra: null
              }]
            });
          }
        }
        BackgroundTask.finish({
          taskId
        });
      });     

I think that should suffice your usecase.
Cheers !

Collapse
 
rbauhn profile image
Robin Bauhn

You just saved me from a bunch of googling, very nice examples! Thank you very much!

Collapse
 
hamzahalvanaa profile image
Lordrauf

how about to call the function every minute, for example, every 5 minutes?

Thread Thread
 
karandpr profile image
Karan Gandhi

You can't. The time limit for iOS is 180 seconds and android implementations vary a lot. Doze mode, battery optimizations, and things like that. You can check this website to check the different vendor implementations.
Depending on the use case you can design custom solutions.
One of the ways to actually force an app in foreground via silent push notifications and native background tasks. Or a combination of silent and full push.
However, this is not possible in Ionic/Cordova/Capacitor. As such you will have to dabble into Native Programming.