17

I would like to know when a user arrives or leaves certain location. I was trying to do this using the wireless network (check for mobile devices), but I couldn't for several reasons.

1) I needed real time updates or every 1 - 5 min of the information about which devices are connected and which devices have just disconnected.

2) I had very high ping from my PC to my iPhone on the same network (still don't know why).

Now I want to do it using geolocation from a Phonegap application (running in the background) suspended on iOS or running in the background in Android.

Any help would be appreciated.

amarruffo
  • 418
  • 2
  • 5
  • 15

1 Answers1

26

Update 25 May 2019

My original answer below is 6 years old and out-of-date with respect to current mobile OS versions. For example partial wakelocks no longer work on modern Android versions.

Today my recommendation would be (if you have a serious commercial app and not a hobby project) to use the paid-for version of the cordova-background-geolocation plugin by Transistorsoft. The free version works for iOS but for Android a license is required which costs in the order of several hundred US dollars. However I think the price is worth it: in my 10+ years of experience in creating location-aware mobile apps, this has been the most sophisiticated and reliable solution I've encountered. For the cost of your license, you get access to the private repo which is continually updated and maintained to be compatible with new versions of Android & iOS.

If you're looking for a free/open-source solution, I would go with cordova-plugin-background-geolocation which is an open-source fork of the original plugin by Transistorsoft. However my experience with this plugin has been of mixed success; due to being free/open-source, it's not updated as frequently as the paid-for Transistorsoft plugin. I encountered problems due to new more stringent restrictions on background location in recent versions of Android which took a significant time to be resolved or have not been fixed at all (see the plugin's issue list).

Original answer (11 Jun 2013)

The first thing to say is that creating a Phonegap app that receives location updates while running in the background is entirely possible, but not trivial. I've done it myself and released apps on both the Android and iOS platforms.

If you need accurate and regular position updates, I'd suggest using the GPS receiver on the target devices. In Phonegap, you can do this setting the "highAccuracy" flag when requesting position updates. The watchPosition() function will deliver new position information as and when the device receives updates from the GPS receiver, so you use it something like this:

navigator.geolocation.watchPosition(successCallback, errorCallback, {
  enableHighAccuracy: true,
  timeout: 10000,
  maximumAge: 0
});

See the Phonegap geolocation API documentation for more details (note the permissions that are required to make this work on Android and iOS).

To keep your app running in the background on either Android or iOS you will need to setup their respective native development environments: Eclipse for Android, XCode for iOS. You will not be able to use Phonegap Build because custom settings are needed in both cases to make it work. See the Phonegap platform guides for how to do this.

To keep your app running in the background on Android, you either need to write a custom Android service, or you could do what I did and use a Phonegap plugin to acquire a "partial wakelock" (see here) to keep your app running in the background and receive position updates while the screen is off. Note that the original version of this plugin is out-of-date and doesn't work with more recent versions of Phonegap, and also doesn't support partial wakelocks. However, I've updated and extended it for my own use: you can find the source code for it in my answer to this question.

To keep your app running in the background on iOS, you need to do things slightly differently; you don't need a plugin, just a project setting.

You can either manually edit the project .plist and add the key “UIBackgroundModes” key with a value of “location” or, with your project open in XCode, add the "Required Background Modes" key with a value of "App registers for location updates". This will cause iOS to trigger the JS callback function you have registered with watchPosition() each time a location update is received. See here for more about iOS project keys and background modes.

Hope this helps!

DaveAlden
  • 30,083
  • 11
  • 93
  • 155
  • thank you for your answer, I'm gonna need the device to update the location every 5 minutes, I can control that, right? It should work as long as the device has internet connection. – amarruffo Jul 11 '13 at 16:16
  • 1
    If you want to update the position on a fixed interval you can use a timeout to call getCurrentPosition(), e.g. `setTimeout(function(){navigator.geolocation.getCurrentPosition(successCallback,errorCallback,{enableHighAccuracy:true})}, 5*60*1000)` If the device has GPS receiver, you don't need an internet connection to receive position updates. – DaveAlden Jul 11 '13 at 18:30
  • 2
    what happens I need the location to be inserted on a database via a web service, is that going to work from background? I readed somewhere that the web service is not gonna get called, any ideas about this?. Thanks for your help. – amarruffo Jul 11 '13 at 18:59
  • iOS will execute the successCallback function when the position is received. If you make this function push the data to a remote web service, I don't see why it shouldn't work. One thing though; I'm not sure that setTimeout will continue to get executed in the background, so watchPosition() is probably a better choice when running in the background. – DaveAlden Jul 11 '13 at 20:19
  • @Dpa99c I've just test the GPS location in Android without any plugin or background service and it's working after leaving the app... PhoneGap 3.0.0 and Android 4.2.2 – Jonathan Naguin Aug 09 '13 at 14:25
  • @Jonathan Naguin All my apps so far are developed with Phonegap 2.x, so maybe 3.0 has different functionality, but I doubt it. When you say "leaving the app" I assume you mean pressing the Home button and returning to the home screen? How long did you test it for? My apps run in the background for hours while processing geolocations. Try pressing the power button to turn the screen off and see if it still works... – DaveAlden Aug 09 '13 at 16:03
  • @Dpa99c I mean press the home button. I left the app running for one hour or so and I also tried with turn off the screen: it keep working. See my question [here](http://stackoverflow.com/questions/18149414/getting-user-location-in-background/18150844) – Jonathan Naguin Aug 09 '13 at 16:07
  • Well if it works in Phonegap 3.0 without needing plugins, then that's good - much simpler. Like I said, my apps are currently all Phonegap 2.x-based and they definitely need a plugin to keep them in the background. I plan to upgrade them to Phonegap 3.0 shortly so I guess I will find out myself :-) – DaveAlden Aug 09 '13 at 16:12
  • @Dpa99c I guess that the app was open and just minimized, and it wasn't closed at all. – amarruffo Aug 20 '13 at 17:03
  • Extremely comprehensive answer! Thanks! – kizzx2 Nov 07 '13 at 17:12
  • This is a very thorough answer. Thanks! I am using PhongeGap 3 and I am using watchPosition. I have modified the .plist file. I have never been able to get this to work. Once I open my app, it watches my position as expected. But when I press the home button I get nothing. The little GPS icon in the status bar also goes away. Can anyone offer any more insight? – mattnull Nov 08 '13 at 16:04
  • 1
    If you're using PhoneGap Build you can set the UIBackgroundModes key using this undocumented xml in the config.xml. ` location ` – Nico Westerdale Jun 15 '15 at 13:39
  • @daveAlden ..could you please tell me that can we get location updates when app is terminated. If yes then, how it is achieved using iOS plugin or phoneGap plugin? – Kirti Nov 08 '16 at 11:56
  • can we add websockets to this pkacge.as it hit api which may down the server?I have used in ios but want to do with socket io . help me – Zeeshan Feb 19 '23 at 11:10