[
https://issues.apache.org/jira/browse/CB-95?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13159658#comment-13159658
]
Shazron Abdullah commented on CB-95:
------------------------------------
by: http://github.com/gregavola (2011-10-27T14:03:23Z)
As I have mentioned in all those issues listed above - I am experiencing this
issue. The only way to work around this:
1. The first call to get the location, works if the app has just been started
for the first time. You'll need to cache the location (you can use
LocalStorage), and then store the timeStamp of when that location was pulls.
2. Since every subsequent call to get the location fails, use the cached
location to make the call. You can also use the timeStamp to check the age of
the lat/long. If the timeStamp is very old - you can force and update, but in
your callback make sure you do the following:
function err_callback(err)
{
if (err.code == 3)
{
// its timeout error. use the localstorage elements and tell the user of
the issue.
}
else
{
// its a real error!
}
}
It's the only way to currently work around the frustration of the issue.
Thanks,
Greg
by: http://github.com/sromalewski (2011-10-27T14:07:55Z)
Thanks @gregavola, I'll try your workaround.
Since geo is such a fundamental aspect of mobile (using your phone to determine
your location and then doing interesting/cool things with that location), it
makes me wonder what kind of apps people are writing now with Phonegap, since
geo hasn't worked now for the last two PG versions. I'd expect more of an
outcry from devs about this, unless they're just writing relatively simple
apps, or perhaps games. What do you think?
by: http://github.com/gregavola (2011-10-27T14:15:25Z)
@sromalewski I have no idea why it hasn't been addresses - as it's one of those
features that works perfectly fine WITHOUT an Native App - so I figure it would
be an important feature.
I've been told it has to do with a timeout with the native Objective-C code.
Hopefully a PG dev can fix this soon!
by: http://github.com/paulj (2011-11-01T11:06:05Z)
I've been seeing this in my application, though it varies by device and
location. My device in Australia isn't seeing it, but I've got ones in the UK
that do.
I've managed to fix the problem by inserting a `this.stop()` directly above the
`this.start(params)` in the `Geolocation.prototype.getCurrentPosition`
definition. My figuring on this (after reading the iOS location manager docs)
is that PhoneGap's location is expiring because the location manager hasn't
issue an update during the timeout, and the call to startLocation in the native
code does nothing to provoke a new one being sent. Calling stop beforehand
ensures that the location manager provides a new location update.
This doesn't seem like a permanent fix to me though - I'm wondering why the
location values are expired in getCurrentPosition at all. Whenever the location
services are running, they should be being kept up to date - so in what
scenario would they become stale?
by: http://github.com/sromalewski (2011-11-01T11:20:01Z)
Great suggestion, I'll test this fix and post how well it worked. Btw, do you
have a sense if this will work for watchPosition as well? (I don't have the
code in front of me.) Thanks!
by: http://github.com/paulj (2011-11-01T11:21:08Z)
@sromalewski watchPosition is calling getPosition internally, so I reckon it
should help.
by: http://github.com/sromalewski (2011-11-01T13:46:56Z)
@paulj I tried your suggestion and here's the result. Short answer is I think
it worked. My app now calls watchPosition like it should - in other words,
when I call watchPosition subsequent times after the first one, it does indeed
try to get a position instead of timing out.
My code is below, and the console result is below that.
I have a function "nearMe" that my users can call by tapping on a screen
element (I use the Datazombies fork of jQTouch for my UI). I've added comments
below to annotate the code:
function nearMe(){
lmNS.gotcoordsFlag = false; // I create a namespace 'lmNS' so I can reuse
variables across multiple functions.
console.log('****** STARTING LAT LON ' + lmLat + ', ' + lmLon);
var geoOptions = {
maximumAge: 1000,
enableHighAccuracy: true
};
lmNS.watchID = navigator.geolocation.watchPosition(onGeoUpdateSuccess,
onGeoUpdateError, geoOptions);
console.log('****** WATCH ID ' + lmNS.watchID);
lmNS.timerFlag = false;
lmNS.t = setTimeout(getCoordTimeout,7000);
}
function onGeoUpdateSuccess(position) {
lmLat = position.coords.latitude;
lmLon = position.coords.longitude;
lmNS.lmAccuracy = position.coords.accuracy;
console.log('******Coords are ' + lmLat + ' and ' + lmLon + '; Accuracy ' +
lmNS.lmAccuracy);
// I use gotCoordsFlag to solve problem of watchPosition trying to sneak in
another success callback after we've gotten coords
if (lmNS.gotcoordsFlag === false){
if (lmNS.watchID != null){
if (lmNS.lmAccuracy <= 70) {
console.log('****** LESS THAN 70 ACCURACY');
lmNS.timerFlag = true;
navigator.geolocation.clearWatch(lmNS.watchID);
lmNS.watchID = null;
lmNS.lmAccuracy = null;
lmNS.locSource = 'GPS';
lmNS.mapViewFlag = '';
lmNS.gotcoordsFlag = true;
useNearMeCoords();
}
}
}
}
function getCoordTimeout(){
console.log('******** TIMEOUT Lat is ' + lmLat);
if (lmNS.timerFlag != true && lmLat != 0) {
console.log('****WATCH OFF VIA TIMEOUT**** USING PRIOR OR LOWER QUALITY
COORDS and Accuracy is ' + lmNS.lmAccuracy);
lmNS.lmAccuracy = null;
lmNS.locSource = 'GPS';
lmNS.mapViewFlag = '';
lmNS.gotcoordsFlag = true;
useNearMeCoords();
} else if (lmNS.timerFlag != true && lmLat === 0){
console.log('****We\'re trying again.');
nearMe();
}
}
The first time I call nearMe, watchPosition almost always returns a lat/lon
with accuracy better than 70 meters. (Note that I'm testing this on my iPhone
3GS running iOS 4.3.3.) Before implementing your "this.stop()" fix, when I
would call nearMe subsequent times, the watchPosition success or failure
callbacks would almost never be invoked and I would always have to rely on the
timeout (i.e., the app would be using old coordinates until watchPosition would
eventually fire and get newer, better coordinates).
After I implemented your fix, here's my console output (I tapped the nearMe
screen element the first time, then I moved about 50 feet and tapped again,
then moved to a different spot and tapped again).
Nov 1 09:19:22 unknown GeoLocTest[5525] : Device initialization: DeviceInfo =
{"name":"Sromalewski’s
iPhone","uuid":"xxxxxxxx","platform":"iPhone","gap":"1.1.0","version":"4.3.3","connection":{"type":"wifi"}};
Nov 1 09:19:25 unknown GeoLocTest[5525] : [INFO] ****** STARTING LAT LON 0, 0
Nov 1 09:19:25 unknown GeoLocTest[5525] : [INFO] ****** WATCH ID 13
Nov 1 09:19:25 unknown GeoLocTest[5525] : Received memory warning. Level=1
Nov 1 09:19:25 unknown GeoLocTest[5525] : [INFO] ******Coords are 40.744286
and -73.998093; Accuracy 66.01
Nov 1 09:19:25 unknown GeoLocTest[5525] : [INFO] ****** LESS THAN 70 ACCURACY
Nov 1 09:19:25 unknown GeoLocTest[5525] : [INFO] ***** GOT COORDS
Nov 1 09:19:25 unknown GeoLocTest[5525] : Loading stop
Nov 1 09:19:27 unknown GeoLocTest[5525] : Loading stop
Nov 1 09:19:30 unknown GeoLocTest[5525] : [INFO] ********** Flags: locSource
GPS, mapView , gotCoords true
Nov 1 09:19:32 unknown GeoLocTest[5525] : [INFO] ******** TIMEOUT Lat is
40.744286 //The timeout is reached, but because the timeFlag is true the
timeout if statement isn't invoked.
Nov 1 09:20:07 unknown GeoLocTest[5525] : [INFO] ****** STARTING LAT LON
40.744286, -73.998093 //This is the second activation of nearMe.
Nov 1 09:20:07 unknown GeoLocTest[5525] : [INFO] ****** WATCH ID 16
Nov 1 09:20:14 unknown GeoLocTest[5525] : [INFO] ******** TIMEOUT Lat is
40.744286
Nov 1 09:20:14 unknown GeoLocTest[5525] : [INFO] ****WATCH OFF VIA TIMEOUT****
USING PRIOR OR LOWER QUALITY COORDS and Accuracy is null //The fact that
lmNS.lmAccuracy is null says to me that the watchPosition success callback
wasn't fired, but neither was the failure callback.
Nov 1 09:20:14 unknown GeoLocTest[5525] : [INFO] ***** GOT COORDS
Nov 1 09:20:14 unknown GeoLocTest[5525] : Loading stop
Nov 1 09:20:17 unknown GeoLocTest[5525] : Loading stop
Nov 1 09:20:17 unknown GeoLocTest[5525] : [INFO] ********** Flags: locSource
GPS, mapView , gotCoords true
Nov 1 09:20:27 unknown GeoLocTest[5525] : [INFO] ******Coords are 40.744316
and -73.998142; Accuracy 65 //But this indicates that the watchPosition
success callback was eventually fired. Except that I didn't use the coords
because the gotCoordsFlag had already been set to true. Maybe I need to tweak
the timing of maximumAge?
Nov 1 09:20:36 unknown GeoLocTest[5525] : [INFO] ****** STARTING LAT LON
40.744316, -73.998142 //This is the third activation of nearMe.
Nov 1 09:20:36 unknown GeoLocTest[5525] : [INFO] ****** WATCH ID 19
Nov 1 09:20:37 unknown GeoLocTest[5525] : [INFO] ******Coords are 40.744301
and -73.998089; Accuracy 93.36
Nov 1 09:20:43 unknown GeoLocTest[5525] : [INFO] ******** TIMEOUT Lat is
40.744301
Nov 1 09:20:43 unknown GeoLocTest[5525] : [INFO] ****WATCH OFF VIA TIMEOUT****
USING PRIOR OR LOWER QUALITY COORDS and Accuracy is 93.36
Nov 1 09:20:43 unknown GeoLocTest[5525] : [INFO] ***** GOT COORDS
Nov 1 09:20:43 unknown GeoLocTest[5525] : Loading stop
Nov 1 09:20:46 unknown GeoLocTest[5525] : Loading stop
Nov 1 09:20:46 unknown GeoLocTest[5525] : [INFO] ********** Flags: locSource
GPS, mapView , gotCoords true
Nov 1 09:20:56 unknown GeoLocTest[5525] : [INFO] ******Coords are 40.744327
and -73.998137; Accuracy 65 //Again, these lines are indications that the
watchPosition success callback is being fired multiple times, which (AFAIK) is
how the function is supposed to work now that your I implemented this.stop()
fix. (Actually, it keeps getting fired - I need to tweak how I clear the
watchID to minimize battery impact.)
Nov 1 09:20:57 unknown GeoLocTest[5525] : [INFO] ******Coords are 40.744327
and -73.998137; Accuracy 65
Sorry for the lengthy code and console entries, but hopefully this is helpful.
What do you think? Thanks!
by: http://github.com/sromalewski (2011-11-01T15:11:21Z)
Success! I've been testing my app in the field all morning, and watchPosition
with repeated calls works just great - indoors, outdoors, with wifi, without
wifi. I'll check my console log tonight when I'm back home, but for now I'm
thrilled. Thanks @paulj !
by: http://github.com/sromalewski (2011-11-02T13:36:27Z)
I've done some more testing, and checked my console log entries, and I think
there's still a (or perhaps new) problem. Unless I haven't set up my code
properly, I can't seem to clear the watchID after I've added @paulj 's
"this.stop()" fix. Even though I've cleared the watchID and set it to null,
every time I move my phone (even a few feet) the watchPosition success callback
is called again and again.
I even added a flag that's set to true after I get the coordinates, and
watchPosition is still called:
if (lmNS.gotcoordsFlag === false) {
lmNS.watchID = navigator.geolocation.watchPosition(onGeoUpdateSuccess,
onGeoUpdateError, geoOptions);
}
This doesn't seem to have any effect, watchPosition is called repeatedly even
though lmNS.gotcoordsFlag has been set to true. And in my onGeoUpdateSuccess,
the first line is the following:
console.log('****** WATCH ID ' + lmNS.watchID);
It returns:
Nov 2 09:35:09 unknown GeoLocTest[6139] : [INFO] ****** WATCH ID null
So the watchID is null and gotcoordsFlag is true, but watchPosition is still
being called. I'm mystified.
by: http://github.com/gregavola (2011-11-07T15:06:01Z)
@sromalewski so it seems like there still is a bug with watchPosition? What
about getPosition - does that appear to be fixed with this.stop();?
by: http://github.com/sromalewski (2011-11-24T04:35:37Z)
Not sure about getCurrentPosition. But I've implemented @paulj 's fix and it
seems to work. Not ideal, but it's good enough for Apple :) -- my app update
with the fix was accepted for iTunes and is now in the AppStore (see
http://spatialityapps.com/). It still seems buggy, but for now it's adequate.
Btw, @mschulkind has a similar fix, but it didn't seem to provide anything
different from paulj's fix -- see
https://github.com/phonegap/phonegap-iphone/issues/197#issuecomment-2741229
Odd that it's so problematic but isn't really being addressed head on.
Several people have raised the issue recently on Google Groups: see
http://groups.google.com/group/phonegap/browse_thread/thread/90e7eee2798b8bb2#
and
http://groups.google.com/group/phonegap/browse_thread/thread/1b8bd1e4716b0994#
by: http://github.com/shazron (2011-11-24T20:46:56Z)
Does this fix it? https://github.com/callback/callback-ios/pull/14 (already
pulled into trunk)
by: http://github.com/sromalewski (2011-11-28T05:36:31Z)
Thanks @shazron. I'm reluctant to test this, though, because I'm not ready to
upgrade to PG 1.2. Can I simply run the install with 1.2, add
phonegap-1.2.0.js to my existing www folder, then build my app? I'm worried
I'll run into problems, and then have to start from scratch by creating a new
project and then manually importing all the plugins, etc.
> .watchPosition & .getCurrentPosition still timeouts
> ---------------------------------------------------
>
> Key: CB-95
> URL: https://issues.apache.org/jira/browse/CB-95
> Project: Apache Callback
> Issue Type: Bug
> Components: iOS
> Reporter: Shazron Abdullah
> Assignee: Shazron Abdullah
>
> reported at: https://github.com/callback/callback-ios/issues/1
> by: https://github.com/schmitti12345
> sorry to mention, but
> [#197](https://github.com/phonegap/phonegap-iphone/issues/197),
> [#304](https://github.com/phonegap/phonegap-iphone/issues/304#issuecomment-2460999)
> & [#287](https://github.com/phonegap/phonegap-iphone/issues/283) are still
> there.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators:
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira