Search code examples
javascriptcordovaionic-frameworkionic2cordova-plugins

Geolocation running very slow on Android


I'm building an app using Ionic/Angular/Firebase.

The app requires a user's geolocation.. I'm using Ionic native's geolocation plugin and I'm stumbling on some issues with speed for Android.

  • On PC it takes less than 500 milliseconds to get the current geolocation.

  • On iOS it takes about 1 second.

  • On Android it takes 6+ seconds, and sometimes it even fails entirely.

Is this an issue with Ionic Native? Is there a special plugin for Android?

Here is my code:

this.geolocation.getCurrentPosition({enableHighAccuracy: false, timeout: 3000, maximumAge: 100000}).then((resp) => {
   this.userLocation.lat = resp.coords.latitude;
   this.userLocation.lng = resp.coords.longitude;
   this.getLocation();
}).catch((error) => {
  this.geolocation.getCurrentPosition({enableHighAccuracy: true, timeout: 3000, maximumAge: 100000}).then((resp) => {
     this.userLocation.lat = resp.coords.latitude;
     this.userLocation.lng = resp.coords.longitude;
     this.getLocation();
  }).catch((error) => {
    this.userLocation.lat = this.userData.location.lat || 0;
    this.userLocation.lng = this.userData.location.lng || 0;
    //if fails, get users last known location.
    this.getLocation();
    console.log('Error getting location', error);
  });
  console.log('Error getting location', error);
});

I can't imagine this code is wrong.. As I said, it works wonderfully on PC and iOS.. Is there something I should do if the user is on android? Is there a different plugin I could use? Any help would be amazing!


Solution

  • The code you are using is working.

    What @Maheshvirus is talking about is the 'cordova-plugin-request-location-accuracy' plugin which actually allows you to prompt the user to turn on high location accuracy (and to check and see if it is on first) for GPS, which will 'Use GPS, WiFi, Bluetooth, or cellular networks to determine location'. I use the same plugin in my apps, it works well.

    From doing some quick Googling it seems that IOS does not have a high accuracy mode, because by default IOS uses gps, wifi, bluetooth etc to get your location...you cant turn it on and off like Android, which explains why IOS is always so quick to know where you are. So on Android devices you need to prompt the user to turn it on, with the plugin mentioned by @Maheshvirus. Which it then should always stay on unless the user changes their mode to a battery-saving or device-only location mode.

    PC should have way faster internet and shouldn't have data caps or severe throttling (unless net neutrality is now completely gone or you're in some other terrible place) so your browser should be able to locate you pretty easily and quickly through the modem/router you're connected to - see this post answer for more details.

    The Solution

    I'm too tired right now to get you the working code example you need, but utilizing Geolocation.watchPosition() rather than getCurrentPosition() will allow you to get the location much faster in my experience using it - and this user seems to have tested it. The watchPosition 'is used to register a handler function that will be called automatically each time the position of the device changes'. The watchPosition function is also utilized almost exactly the same as getCurrentPosition, except when it is called you have to assign it an ID and use Geolocation.clearwatch(idname) when done. Here is the docs for watchPosition(). So the cool thing is if the user moves or the phones location service thinks they've moved, it won't have to spin up another call to the device GPS (which is what is making it take so long) since the GPS is already listening.

    Sorry I didn't offer an actual code fix, but I hope these details help. This was an issue I also ran into when I was utilizing getCurrentPosition on the different devices. You should have no problem implementing watchPosition(), and should see android location latency improvements immediately - especially if you get the user to turn on High Accuracy Location mode with that plugin 'cordova-plugin-request-location-accuracy'