2

I've been searching around stackoverflow for a few hours tonight looking for a solution to this issue which I strongly am thinking is a cordova/phonegap bug with Geolocation.

I'm having the same issue as @Tal here at geoLocation enabling without page-refresh?

Basically the onSuccess from getLocation call never gets called the first time you request location. I've set a timeout to call onError and rest the page but still can't figure out why it doesn't work the first time around and only a full refresh will solve the problem. Putting it into a loop i.e:

function onError(error) {
  if (error.code === PositionError.TIMEOUT){
    navigator.geolocation.getCurrentPosition(onSuccess, onError,
      { maximumAge: 3000, timeout: 1000, enableHighAccuracy: true } );
  }
  // Handle other errors here
}

Never seems to work either. I've tried re arranging my code order and functions and it does not seem to make any difference. The application will only successfully get GPS coordinates after the first time it fails. I really think its a cordova bug. My full javascript code below:

<script type="text/javascript" charset="utf-8">
    // onSuccess Geolocation
    //
    function onSuccess(position) {
        var element = document.getElementById('geolocation');
        //OUTPUT COORDINATES INFORMATION INTO HTML
    element.innerHTML = '<h2>Detailed Gelocation information</h2><table class="geoTable"><tr><td class="noborder"></td><th>Latitude</th><th>Longitude</th><th>Altitude</th><th>Accuracy</th><th>Altitude Accuracy</th><th>Heading</th><th>Speed</th><th>Timestamp</th></tr>' +
            '<tr><td class="head">Data Value</td>' +
            '<td class="centre">' + position.coords.latitude  + '</td>' +
            '<td class="centre">' + position.coords.longitude + '</td>' +
            '<td class="centre">'  + position.coords.altitude + '</td>' +
            '<td class="centre">'  + position.coords.accuracy + '</td>' +
            '<td class="centre">'  + position.coords.altitudeAccuracy + '</td>' +
            '<td class="centre">'  + position.coords.heading + '</td>' +
            '<td class="centre">'  + position.coords.speed   + '</td>' +
            '<td class="centre">' + new Date(position.timestamp) + '</td></tr>'+
            '</table>' +
            '<p align="center"><button data-theme="h" onclick="resetLocation();">Clear GPS Location</button></p>';


                    //GET LOCATION VARIABLES FROM API
                    var lat = position.coords.latitude;
                    var lng = position.coords.longitude;
                    var yourStartLatLng = new google.maps.LatLng(lat, lng);

                    //PUT GMAPS INFORMATION INTO PAGE
                    $('#map_canvas').gmap({'center': yourStartLatLng});
                    $('#map_canvas').gmap('option', 'zoom', 19);
                    $('#map_canvas').gmap('option', 'mapTypeId', google.maps.MapTypeId.SATELLITE);
                    $('#map_canvas').gmap('addMarker', {
                                                        'position': yourStartLatLng, 
                                                        'draggable': false, 
                                                        'bounds': false
                                                        });
    }
    // onError Callback sends user an alert message and refreshes screen to load all scripts again
    //
    function onError(error) {
        alert('The Freshwater application failed to get your location. Please ensure that you have a successful WIFI or 3G/4G internet connection when using the Geolocation feature. ' +
              'The Locator screen will now be refreshed. Please attempt Geolocation again.');

    //navigator.geolocation.getCurrentPosition(onSuccess, onError,
      //{ maximumAge: 3000, timeout: 5000, enableHighAccuracy: false } );
        //PUT A TIMER ON ERROR TO REFRESH PAGE FOR GPS
        setTimeout("window.location+='?refreshed';", .1000); 
    }

//RESET GEOLOCATION PAGE TO TAKE ANOTHER LOCATION READING
    function resetLocation(){
        setTimeout("window.location+='?refreshed';", .1000); 
    }

    //ATTACH FUNCTION TO BUTTON TO CALL GEOLOCATION
  function getLocation() {
        navigator.geolocation.getCurrentPosition(onSuccess ,onError,
      { timeout: 1000, enableHighAccuracy: true } );
    }
</script>
Community
  • 1
  • 1
Ryan Coolwebs
  • 1,611
  • 5
  • 22
  • 44
  • your cordova version? – Kathir Apr 25 '14 at 11:59
  • Sorry, forgot to mention that. I am using the latest version, 3.4 – Ryan Coolwebs Apr 25 '14 at 12:25
  • We've seen some similar issues with geo in the XDK (which provides a similar webview environment) and believe the problem is being caused by the native GPS implementation -- the results tend to vary as a function of the Android version and the Android manufacturer. Wish I could offer a solution... – xmnboy Apr 25 '14 at 17:22
  • Yeah I have heard of that. I'm hoping that my beta testers don't encounter the same problem/error. I am going out on a 'wing' here but I'm wondering if I will get different results with Adobe Phonegap build service? Too bad the app is over 15mb... – Ryan Coolwebs Apr 26 '14 at 00:14

2 Answers2

0

It is the loading time of Javascript that is causing the geolocation function to timeout the first time.

I did some modifications on the script and got rid of a number of Gmap UI Jquery libraries I was not using.

jquery.ui.map.extensions.js
jquery.ui.map.microdata.js
jquery.ui.map.microformat.js
jquery.ui.map.overlays.js
jquery.ui.map.rdfa.js
jquery.ui.map.services.js

This may have had a small effect. When doing some time-based tests using iOS simulator, asking for geolocation as soon as the page loads never fires onSuccess the first time. If I wait about 10s before clicking on the 'get location' button, it works the first time around.

Obviously this is something to do with loading all the (internal and external) scripts properly before requesting geolocation. I have preloaded the external google map script like so:

  function onLoad() {
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = 'https://maps.googleapis.com/maps/api/js?key=AIzaSyDy1bBAiDhmFfuKz6SerLvKyOIUqlFsX7c&sensor=true&' +
  'callback=mapLoaded';
  document.body.appendChild(script);
    }

But if someone requests geolocation too quickly it seems to timeout and run onError the first time around.

UPDATE: I have decided to hide the button that requests geolocation and show it when external script has been loaded (and put a loadbar gif). It still makes an error when location is requested. Most likely because the google api code itself contains a getScript command (so I'm not seeing the true load time).

At the mercy of Google maybe?

Ryan Coolwebs
  • 1,611
  • 5
  • 22
  • 44
0

I think this may be because your device is not 'Ready'. See the below code:

<script>
    function onDeviceReady() {
        // Do your geolocation call here ...
    }
    document.addEventListener("deviceready", onDeviceReady, false);
</script>

If you put your geolocation calls in the device ready event then they will only trigger once your device is considered 'ready'.

akanieski
  • 61
  • 5