Behaviour reproducible in the KitchenSink [geolocation.js](
https://github.com/appcelerator/KitchenSink/blob/master/Resources/examples/geolocation.js) example on Titanium 1.5 to 1.6+.
{quote}
Sometimes the listener fails to return any location even after a few minutes. However, if I open a Ti.Map.MapView with the userLocation attribute set to true, my current location is pointed out on the map within 20 seconds. Other location-based apps installed on the Android phone also manage to successfully geolocate me.
{quote}
(From Q&A post at
http://developer.appcelerator.com/question/118712/tigeolocation-on-android-seems-flaky)
Key points from our conversation with Kevin Whinnery about this issue:
* Accuracy level has been set to *Ti.Geolocation.ACCURACY_BEST*. Our code is more or less the same as the KS example code.
* Reports of geolocation failure from a *wide range of devices*. We have seen nearly 60% of users dropping out because the app didn't geolocate them. Even our existing users keep asking us to improve geolocation - esp. because they see that the map within our app shows the current location, but our geolocation code fails to work.
* The important thing is that this *doesn't happen all the time*. Single-shot GPS readings do come back at a reasonable rate when the geolocation is working. But when it isn't working, we have to wait for minutes together with no guarantee of success.
* Opening & locating ourselves in Gowalla or *other location-based apps* ensures that the Kitchen Sink demo always works the next time we open it.
We *don't* run the geolocation call within the app.js context. We open a heavyweight window using a URL from app.js. From this heavyweight window, we open another window using a URL. It is in this window's context that the geolocation call occurs.
I have this EXACT same problem. It has something to do with [TiLocationHelper.java](https://github.com/appcelerator/titanium_mobile/blob/master/android/titanium/src/java/org/appcelerator/titanium/util/TiLocationHelper.java). Essentially, the accuracy constants map to one of two different options (different behavior than iOS, where all 6 constants do something different), and your choices are either "don't turn on the GPS ever" or "require a great satellite lock and ignore that there's a network location device in this phone", even though Android technically supports a lot more choices than that. It's less than ideal, but I edited the TiLocationHelper.java file to subscribe to updates from both the GPS and network providers, so that my app at least gets a fix in a reasonable amount of time (instead of never), though it doesn't follow the Android model of "get crappy location and keep improving until app is satisfied". If you make this modification (I did it in registerListener and not updateProvider because I'd like to get something immediately and improve it), what fetchProvider does isn't really relevant. I'm working on distilling a patch to do what *I* want, but I'm sure it isn't going to do what you want. I'll post it here once my QA team beats it to death.
Here is a patch that I wrote to halfway hack around this issue:
This works for us because now we get a more-or-less instant response to a location event handler (as in iOS), and then the location will eventually refine to something better (GPS). Theoretically; my custom SDK hasn't been tested by our QA team yet. I don't think this patch is worthy of anything other than to be a usecase-specific hack that may also work for the OP. My personal preference, given that geolocation works differently on iOS and on Android, is either to:
Implement the complete [W3C Geolocation](http://dev.w3.org/geo/api/spec-source.html) standard consistently on both platforms, or
Create an Android geolocation module and an iOS geolocation module, so that the handling specific to both mine and the OP's usecase can be implemented as if it were native.
Also sorry I couldn't actually attach this patch as a .patch. I guess as I'm not the reporter that I can't.Hi Keith, Thanks for the comment and the patch - we'll leave it up here in case anyone would like to attempt to apply it. This is definitely a parity issue, where the behaviors for Geolocation tracking are not the same across platforms. We're probably not going to accept the patch as-is because we need to revisit this API and make sure it's uniformly implemented across all platforms, with unit tests that match the desired behavior. Also, to accept any code at all for Titanium Mobile under any circumstances, we require a contributor agreement to be on file for the patch submitter. To register a CLA, you can visit http://developer.appcelerator.com/cla. Thanks, and we'll get this scheduled ASAP.
As I mentioned via Twitter... my patch is nothing more than a hack to support more quickly giving my app an instant location. While I think that the behavior somewhat matches ACCURACY_BEST on iOS, it doesn't do it exactly. Definitely the more appropriate behavior would be to subscribe to updates from both GPS and network and once a reliable GPS signal is picked up, ignore updates from the network (until GPS is lost, then go back to network). Right now, it picks one or the other, but that's not consistent with iOS. Honestly, it'll probably be easier to implement iOS geolocation and Android geolocation, because the APIs are very different. (Or, like I said, the W3C Geolocation API, which matches neither API.) Because, for example, my desired behavior is good for something where we need to get the best fix possible as soon as possible (like navigation), but I would sure hate to make that behavior apply to everyone. I will go ahead and register a CLA, but please don't take my patch as-is :).
I will have to get my employer to OK filling out a CLA due to the patent licensing thing, which is well above my pay grade :)
Sorry, I can't sign the CLA... But my patch is a hack anyways.
I agree with Keith's goals: 1. Improve the current "require a great satellite lock and ignore that there's a network location device in this phone" method. If I "prefer" the GPS provider, but can't get a GPS lock, then network location is ok. preferredProvider should be just that...the preferred provider of locations. It may be usefull to offer a new minimumProvider property so that apps that need GPS-only locations can lock out network-based locations. 2. Ability to get an instant location response as soon as the listener is activated, with continued 'location' event firings as the GPS comes on line and the location becomes more and more precise. As far as parity goes, this process should behave the same way on Android and iOS, when all is said and done.
Closing bug. Verified fix using code from TIMOB-7565 on: SDK build: 2.0.0.v20120319003254 Runtime: v8, rhino Titanium Studio, build: 2.0.0.201203182248 Device: LG Slate (3.1)