Cordova-plugin-background-geolocation: Question: `keepRunning` property in background mode

Created on 2 Jun 2016  Â·  17Comments  Â·  Source: mauron85/cordova-plugin-background-geolocation

Warning: You probably have to set your cordova app to keep running by keepRunning property to true (this is the default now).

Please let me know if I am interpreting correctly:

  1. When the app is minimized by the user (background mode) there is no guarantee that geolocation plugin will trigger a callback. To overcome this, the app shouldn't pause in background. This can be achieved through https://github.com/katzer/cordova-plugin-background-mode by calling cordova.plugins.backgroundMode.enable(); alternative to keepRunning mentioned in docs (please consider adding this
    <platform name="android"> ... <preference name="KeepRunning" value="false" /> )
  2. When app is in background I get 2 notifications: a) The app is running in background doing heavy task and b) App is running. Touch for more info. Is there any way I can remove these? Or lower it down to one?
  3. If point 1 is correct would this cause issues during IOS app review, as the app would always keep running in background?
  4. When the user kills/force-stops the app(not background mode), geolocation plugin will continue logging location in local db and callback won't be triggered. These location can then be retrieved by calling backgroundGeoLocation.getLocations(success, fail). [Android Only]
  5. Point 4 function backgroundGeoLocation.getLocations(success, fail) is Android only, what happens in case of IOS?
  6. If point4 is correctly interpreted, how do I know if there are locations stored in local db?
question

Most helpful comment

Of course it sets UIBackgroundMode "location", this is a _background-geolocaiton_ plugin!

However, the only way that iOS will keep your app from being suspend with this mode is if location-services _are engaged_, ie: the GPS radio is ON and sucking power. You could do this but the user's battery will die in a few hours and your users will hate you. The _second_ you turn off location-services, iOS will immediately put your app to sleep.

I originally designed this plugin for a disaster-response application, tracking first-responders into hurricanes & earthquakes, in an environment where the network is likely destroyed. The core philosophy of _my_ work is tracking the device in the most battery-efficient manner possible. That means that location-services must be engaged only when the device is detected to be moving and turned off ASAP when the device is stopped.

The differences between this plugin and my new version are vast. I'm probably about 1500 hours ahead of this fork. I've completely refactored both Android & iOS during the past 17 months-or-so after I put it up for sale. Since that time, I make enough sales that I'm able to devote _every single hour_ of my time to supporting the plugin. I'm supporting hundreds of paying customers now. It's not a side-project for me, it's my full time job.

I've extracted the core native functionality into pure native frameworks for each platform, completely decoupled from Cordova. I sell the same plugin now for React Native and I'm considering porting it to NativeScript by Telerik. Each framework I port-to requires just a small facade in front of the same core native framework.

AirBnb is one of my customers

iOS is free but you have to purchase a license for Android. You can try Android with my SampleApp, which contains a license-key that unlocks the Android plugin only only for the SampleApp app's bundle ID.

All 17 comments

  1. I believe keepRunning only works for android. I'm not iOS expert, but former author found way, how to do callbacks in iOS.
  2. Use notificationTitle, notificationText and notificationIcon config props. But in case of notificationIcon also read my comment.
  3. in iOS when you "kill" an app, I believe there background tracking will be stopped. Also, there is no persistence of locations like in Android. (no getLocations method...)
  4. just call backgroundGeoLocation.getLocations and in success callback filter debug locations (if you used debug: true config options) and count number of elements in array. If count is larger then zero, voila you have some stored locations.
backgroundGeoLocation.getLocations(function(locs) {
    var filtered = [].filter.call(locs, function(location) {
        return location.debug === false;
    });
    if (filtered.length > 0) {
        console.log('You have new locations');
    }
});

Thanks @mauron85 , so as off now IOS will stop getting callback when the app is suspended or killed. I just went through this link and found some interesting information:

https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

There is a UIBackgroundModes key that can be set to location in app’s Info.plist. This ensures that a background app is woken up from suspension in cause of an update. Similarly if an app is killed, it is relaunched by the system to handle location update. More under Tracking the User’s Location section.

great. not sure about what killed means, but apart from that make sense.

This line is verbatim from the link.

If the app starts this service and is then terminated, the system relaunches the app automatically when a new location becomes available.

I guess this may just solve ios callback issue what do you think?

yes, that is it. thanks

Hi, original author here. Unless you're making a music-player app, If you want to have your app rejected by Apple, 100% guaranteed, go ahead and use cordova-plugin-background-mode

If you want to keep your iOS app running 24 hours a day in the background without having battery-draining location-services engaged constantly, use my clever preventSuspend option.

bgGeo.configure({
  preventSuspend: true,
  heartbeatInterval: 60
}, function(state) {
  bgGeo.start();
});

// Listen to heartbeat events while plugin is in stationary state.  Works for both iOS & Android.
// While in debug mode, you'll hear the debug sound `"boop"` each time a heartbeat event fires.
bgGeo.onHeartbeat(function(params) {
  bgGeo.getCurrentPosition(function(location) {
    console.log('- location every minute from heartbeat event, 24 hours a day', location);
  });
});

@shyamal890 I used that Apple document "Background Execution" while designing the original cordova-background-geolocation iOS plugin, which @mauron85 has forked here.

Come over and try my super advanced iOS version which now integrates with my old cordova-plugin-background-fetch, assisting in re-awakening a killed app.

And @mauron85 if you ever want to try my Android version, I'll give you some license keys. email me

Thanks @christocracy I stopped using cordova-plugin-background-mode and am sticking with keepRunning flag for android.

Regarding IOS: I haven't really started implementing for IOS as I am on a windows system. Will start debugging once I have a VM setup with OSX. However, when you say

I used that Apple document "Background Execution" while designing the original cordova-background-geolocation iOS plugin, which @mauron85 has forked here.

Do you mean @mauron85 's plugin has already implemented the UIBackgroundModes = location in Info.plist ? And is not a good enough solution?

Moreover, can you please explain what is the difference between original cordova-background-geolocation and super advanced iOS version ?

Of course it sets UIBackgroundMode "location", this is a _background-geolocaiton_ plugin!

However, the only way that iOS will keep your app from being suspend with this mode is if location-services _are engaged_, ie: the GPS radio is ON and sucking power. You could do this but the user's battery will die in a few hours and your users will hate you. The _second_ you turn off location-services, iOS will immediately put your app to sleep.

I originally designed this plugin for a disaster-response application, tracking first-responders into hurricanes & earthquakes, in an environment where the network is likely destroyed. The core philosophy of _my_ work is tracking the device in the most battery-efficient manner possible. That means that location-services must be engaged only when the device is detected to be moving and turned off ASAP when the device is stopped.

The differences between this plugin and my new version are vast. I'm probably about 1500 hours ahead of this fork. I've completely refactored both Android & iOS during the past 17 months-or-so after I put it up for sale. Since that time, I make enough sales that I'm able to devote _every single hour_ of my time to supporting the plugin. I'm supporting hundreds of paying customers now. It's not a side-project for me, it's my full time job.

I've extracted the core native functionality into pure native frameworks for each platform, completely decoupled from Cordova. I sell the same plugin now for React Native and I'm considering porting it to NativeScript by Telerik. Each framework I port-to requires just a small facade in front of the same core native framework.

AirBnb is one of my customers

iOS is free but you have to purchase a license for Android. You can try Android with my SampleApp, which contains a license-key that unlocks the Android plugin only only for the SampleApp app's bundle ID.

Hi @christocracy, just read your description

For an app which uses our Background Geolocation plugin, as soon as the plugin enters stationary mode, iOS will immediately suspend your app. In stationary-mode, the Background Geolocation plugin has created a geofence around the current position and iOS will not interrogate this geofence until a "significant-change" event occurs.

I was always wondering why are you using both geofencing and significant changes, but now I getting into it. If I understand it correctly, significant changes are used as kind of safety catch.

iOS persists listeners which glom onto both geofences and sig.changes APIs after app-termination & device-reboot.

Ok, but why this duality? Isn't geofence or sig changes alone enough? I mean it make sense to me to have them as two separate providers (like I already have in Android), but you're using them at same time. Not sure about the reason but not iOS expert either.

There was an obscure reason for it. I don't exactly recall why.

@christocracy Thank you for the explanation. So it's a workaround. I was scratching my head around this for quite long time (not really) :-). Good job Chris.

@christocracy Maybe I know why. It seems that startMonitoringForRegion sometimes miss to trigger didExitRegion and without significant changes, you can get effectively get stuck with no location updates.

For a terminated iOS app, this service relaunches the app to deliver events. Use of this service requires “Always” authorization from the user.

Edit: There is also the thing about starting terminated apps. But region monitoring also starts terminated service so that was not reason for using sig changes (just sayin).

I believe this can be closed for now.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Ritzlgrmft picture Ritzlgrmft  Â·  6Comments

sasiadstar picture sasiadstar  Â·  4Comments

mahmed-ntd picture mahmed-ntd  Â·  10Comments

vlafranca picture vlafranca  Â·  6Comments

shyamal890 picture shyamal890  Â·  10Comments