NativeScript / nativescript-geolocation

Geolocation plugin to use for getting current location, monitor movement, etc
Apache License 2.0
139 stars 76 forks source link

Sample Background Service for the Angular version #263

Open csimpi opened 4 years ago

csimpi commented 4 years ago

Make sure to check the demo app(s) for sample usage

I've checked, also all of the issues, but couldn't figure out how to create a background service in the NS Angular verions.

Make sure to check the existing issues in this repository

Done, found a couple of similar issues, with no final solution or didn't help

If the demo apps cannot help and there is no issue for your problem, tell us about it

Please, ensure your title is less than 63 characters long and starts with a capital letter.

Which platform(s) does your issue occur on?

Android, Emulator, and Device both

Please, provide the following version numbers that your issue occurs with:

Please, tell us how to recreate the issue in as much detail as possible.

Describe the steps to reproduce it.

Is there any code involved?

Tried to use this sample but doesn't work: https://github.com/NativeScript/nativescript-geolocation/tree/master/demo/app

So it would be great a workable sample for an NS-Angular too.

My StackOverflow question: https://stackoverflow.com/questions/62162963/how-to-implement-android-background-service-in-a-nativescript-angular-project

justinmespel commented 4 years ago

Hey, I'm struggling with this as well but will share my code once I figure it out. I've tried the following solutions but each one has an error.

1. Angular Singleton service with RXJS timer.

This works the best by far but has the hardest error. I have tested this solution on phisical Galaxy A8, A11, S8, J3. I use an RXJS loop and geolocation.getCurrentLocation to fetch the location. The location fetches fine and the angular service runs in the background, but the issue is that I always get the exact same location returned. p

2. Implement geolocation example background-service.

If I use the default background-serivce.ts example in the demo, I can connect this to an angular service to turn it on. This works all fine using geolocation.watchLocation, I get locations and can see the location icon in the top bar. As soon as you go to the background, the watch stops (not manually), and you never get a location until you go back to the app.

3. Angular Singleton service with geolocation.watchLocation.

This does not work, I can never seem to get thegeolocation.watchLocation to ever run in the background. It will always pause if the app is minimized.

4. Implement geolocation example background-service combined with RXJS timer.

I did a hybrid implementation of the above method, where I use the manual geolocation.getCurrentLocation inside an RXJS loop that is inside the background service. This gives me the same error where I just receive the exact same location until I go into the app. I can see while the app is in the background, the location icon is never trigged in the top bar.

What's Next?

I'm determined to find a solution for this so I will keep investigating. I think the major issue here is location services are never triggering. I've seen some StackOverflow issues about this saying it's only related to Samsung devices but I cannot test this. One way I can get it to work with solution #1 is run navigation of maps in the background. I can see this triggers the location service always on, and my app will usually get a new location every 40 seconds when geolocation.getCurrentLocation triggers every 10 seconds.

I'm going to attempt to fork the nativescript-geolocation plug and add in @Overrides to kick start the location service before requestion a new location so it doesn't use google maps cache.

earnestware commented 3 years ago

nothing?

justinmespel commented 3 years ago

I forgot to come back to this after posting sorry!

I managed to get the outcome I needed using this plugin. I ran the plugin on its own Android FOREGROUND service with a notification and it works in the background, app minimized/background (not closed), screen off. Looks like the following:

Imports, Consts, Vars StartPluginPollingFunction, StopPollingFunction

@NativeClass() @JavaProxy("com.yourapp.ForegroundService") class ForegroundService extends android.app.Service

Basic Java foreground service with separate SDK version triggers, build up the service

I store the last known location on the foreground service. Then I can fetch it whenever I want from an Angular service.

To start/trigger from an Angular service I do the following:

const context = Application.android.context; const intent = new android.content.Intent(context, locationForegroundService.class); intent.setClassName(context, "com.yourapp.LocationService"); if (Device.sdkVersion >= "26") { context.startForegroundService(intent); } else { context.startService(intent); }

Then at the bottom:

export function getLastLocation() { return lastKnownLocation; }

export const locationForegroundService = ForegroundService;

Then I just fetch the location with an interval from my Angular service for whatever I need it for.

        // This fetches the last known location 
        this.locationInterval
            .pipe(
                takeUntil(this._stop),
                repeatWhen(() => this._start)
            )
            .subscribe(async () => {

                // Pause interval while location is fetched
                this._stop.next();

                const lastLocation = getLastLocation();

                if (lastLocation) {
                    this.locationUpdate$.next(lastLocation);
                }

                this._start.next();

            });

This is a short summarised version. If you are having trouble trying to implement a solution with a Foreground Service feel free to drop a question and I'll do my best to help out :)

liamcharmer commented 2 years ago

@justinmespel

How were you able to get the location when the app is minimised in the foreground/background service? I try to use the plugin however the gps location doesn't change even though the gps is following a route.