Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cordova geolocation accuracy gets capped at 10 meters

Update: it is a Google Play Service issue, reported internally here and it will be fixed from version 13.4.0

We use the cordova gelocation plugin and the method navigator.geolocation.watchPosition() with the option enableHighAccuracy: true to track the user location and get the most accurate results.

Our app has been around for more than 1 year and we used to have no problems with any device getting a very good location accuracy, 4/6 meters when outside and the sky is clear.

Lately, many of our users are reporting not being able to get anything less than 10m accuracy no matter what they do.

We decided to test it ourselves and we found to have the same issue. Initially, we thought we introduced some bug in our latest release, we triple checked everything but we made no changes to code/dependencies involving geolocation.

We tested older versions of our app as well, where we are sure it was possible to get like 4m accuracy, but surprisingly they do not work either, accuracy is capped at 10m.

We tried different version of Android and we can reproduce the issue on any platform from 5 (Lollipop) to 8 (Oreo). We also have the same problem on iOS 10/11. Again, we have not updated the app in months.

There is a recent question about the same issue here:

Someone else is having the same problem using Android native code here

Does anyone know what is going on? Is it a permission issue? Location Services are set to High Accuracy as well.

For the sake of completeness, we are able to get 3/4 meters accuracy using the old version (2.x) of this plugin

Is it the only way to go?

We would rather not introduce an extra dependency for something that was working so well out of the box.

Many thanks

like image 290
Mirko Avatar asked Mar 18 '18 13:03

Mirko


1 Answers

Looking at source code:

Old plugin (2.x) Source:

  watchPosition: function(success, error, args) {
    var win = function() {
        var geo = cordova.require('cordova/modulemapper').getOriginalSymbol(window, 'navigator.geolocation');
        geo.watchPosition(success, error, {
            enableHighAccuracy: args[1]
        });
    };
    exec(win, error, "Geolocation", "getPermission", []);
},

New Plugin (master) Source:

watchPosition: function(success, error, args) {
    var pluginWatchId = utils.createUUID();

    var win = function() {
        var geo = cordova.require('cordova/modulemapper').getOriginalSymbol(window, 'navigator.geolocation');
        pluginToNativeWatchMap[pluginWatchId] = geo.watchPosition(success, error, args);
    };

    var fail = function() {
        if (error) {
            error(new PositionError(PositionError.PERMISSION_DENIED, 'Illegal Access'));
        }
    };
    exec(win, fail, "Geolocation", "getPermission", []);

    return pluginWatchId;
},

In OLD plugin code enableHighAccuracy is a boolean set by (arg1 of array).

With NEW version of plugin you need to pass arg as JSON with that flag set: {enableHighAccuracy: true} to reproduce same call to geo.watchPosition function with high accuracy.

Old Way:

navigator.geolocation.watchPosition(geolocationSuccess,
                                                  geolocationError,
                                                  [false,true]);

New Way:

navigator.geolocation.watchPosition(geolocationSuccess,
                                                  geolocationError,
                                                  { enableHighAccuracy: true });
like image 85
Frix33 Avatar answered Oct 02 '22 20:10

Frix33