I am building a location aware app for Android using sencha 2.3.1 + phonegap 3.3.0, and use geolocation to show a list of destinations ordered by proximity to the user location.
Everything works fine if the setting for network-based location is on. But if I turn it off and leave gps only based location then it never gets detected.
The code is very basic, I tried both the sencha path:
Ext.device.Geolocation.watchPosition({
frequency: 10000,
callback: function(position) {
AppHelper.setCurrentLocation(position);//yeah!!
},
failure: function() {
AppHelper.setLocationModeOff();//oouch!
}
});
and the phonegap path:
var success = function(position) {
AppHelper.setCurrentLocation(position);
};
var fail = function() {
AppHelper.setLocationModeOff();
};
navigator.geolocation.watchPosition(success, fail,{ timeout: 30000 });
Result is the same, I tried waiting for a couple minutes for the geolock to happen but no sign of location service.
The phonegap location plugin is installed, the permissions are correct, and everything works if network location is enabled.
I am testing on a Sony Tablet S.
I am aware of this bug:
How to get user position by GPS in Sencha
But I checked the code and its is definetely fixed in sencha 2.3.1
I wil try on other devices but I was wondering if anybody experienced the same.
TIA.
EDIT:
I made an experiment using standard html5 code on my android device using systems default browser (webkit based).
I would access my settings page and change settings at each run.
Accessing http://html5demos.com/geo I get the following:
I started the device with network geolocation on and gps based location off:
I get a message that asks if I want to share my location I say yes, only this time everything works fine.
Turn off network based geolocation, gps still off:
Location detection fails. (as expected)
Turn on GPS, leave network geolocation off:
Geolocation fails silently, I don't get a request to use my location and subsequent activation of GPS based gelocation.
So my conclusion is: this is similar to what I noticed in phonegap. If network based geolocation is on everything works as expected. But if I have no network connection and gps is on that is pretty useless in my html5 app.
At least this is what happens on my device (sony tablet)
From my understanding of HTML5 geolocation API, that is expected behaviour, you just can't control if under the hood it is using gps or network location.
What's probably happening is that watchPosition(), when it is called, tries first a raw, quick positioning using network, then goes with the gps positioning to give you a better result (assuming you called it with the enableHighAccuracy parameter).
If you are disabling network positioning it probably gets stuck at the first point: as stated in cordova/phonegap's docs the permission to access coarse location is a requirement for geolocation to work.
(in app/AndroidManifest.xml)
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
I am guessing that revoking access to coarse location from the device settings somehow "overrides" the user permission given when installing the app.
Related
I am implementing an APP with Xamarin.
In my APP I have set access fine location permission.
And in runtime I have allow the permission.
But sometimes, the APP still can't get the GPS location infomation.
(This happens in a low possiblity)
But once connect the phone to a network(router).
The GPS works again.
What would be the reason?
Here is code I use
var locator = CrossGeolocator.Current;
var position = await locator.GetPositionAsync(TimeSpan.FromMilliseconds(5000));
We use in Cordova with plugin "cordova-plugin-locationservices"
Sometimes we get location that a few km away from real location.
we call to "getCurrentPosition" with next options:
{
timeout: 60000,
enableHighAccuracy: true,
maximumAge: 0,
}
Someone use in this plugin and use in another options or recommend on another plugin.
At first we use "cordova-plugin-geolocation" with same options but it's also sometimes return not accurate position.
I've written extensively on this topic at https://breautek.com/articles/geolocation-accuracy.html
But to summarise there are a number of reasons why you aren't receiving the accuracy that you're after.
The two main contributors to inaccurate readings are 1) Settings & 2) The environment.
Natively, the GPS service operates in two modes: Fine location and coarse location. Fine location will allow you to get approximately up to 3-5 meter accuracy and is generally used if you require information such as the specific street. Coarse location gives you a very low accuracy reading that can only be useful to determine the location of the user's state or country.
Settings includes both programmatic settings, such as the enableHighAccuracy parameter, and they include User device settings, which is configurable by the user on based on their own location preferences.
The developer obviously has control over programmatic settings, and it looks like you're doing just that. However, the developer doesn't have access to change user preferences of the device. Just because the user has consented permission for your app to use location, doesn't mean they have location services actually enabled, or even configured to provide fine location. The specific settings can vary from device to device or by OS version to OS version. But generally speaking they usually have some sort of "Device/GPS only", and "High Accuracy" (sometimes labelled as "Bluetooth/Wifi/Mobile") setting for geolocation. It's the app's responsibility to handle these situations.
In my apps, I use the mixture of the cordova-plugin-geolocation as well as the third-party diagnostics plugin. With the diagnostics plugin, you can check if permission is granted, including for fine/precise location, as well if location services are indeed enabled.
Lastly, the second issue could be the environment. Even if the device is configured and the app has permission to use fine location, you still may not actually receive accurate readings. This can be caused purely based on the environment. Being located in a concrete office building for example hinders a lot of GPS capabilities.
It's recommended to pay attention to the accuracy field in your GPS callbacks, which will tell how confident the GPS service is that the given GPS point is accurate. The accuracy reading is in meters which tells you that the true location is within X meters radius of the given location. So in otherwords, the lower the number the better.
I'm working on updating an existing product using here-sdk from version 3.7 to 3.8 / 3.9
It has hardware gps on board available via android LocationManager.GPS_PROVIDER, but also receives location information from an external device which is injected via location mock as the network provider:
this.locationManager.addTestProvider(LocationManager.NETWORK_PROVIDER,
false, false, false, false, true, true, true,
Criteria.POWER_LOW, Criteria.ACCURACY_FINE);
this.locationManager.setTestProviderEnabled(LocationManager.NETWORK_PROVIDER, true);
this.locationManager.setTestProviderStatus(LocationManager.NETWORK_PROVIDER,
LocationProvider.AVAILABLE, null, System.currentTimeMillis());
This external data is used primarily whenever gps is not available, eg. during startup.
PositioningManager is started with: PositioningManager.getInstance().start(PositioningManager.LocationMethod.GPS_NETWORK);
Other places in the codebase have locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, ...) -> onLocationChanged(Location location) handlers that fire on each new mocked location, plus other handlers listening to LocationManager.GPS_PROVIDER which work for updates from hardware gps.
There are also PositioningManager onPositionFixChanged() listeners which fire for these same coordinates from both providers.
On HERE SDK 3.7 this all works perfectly.
Once I upgrade HERE SDK to 3.8 however the network provider updates stop working.
The map display no longer updates and the onPositionFixChanged() listeners no longer fires for mock network updates. GPS updates work fine however.
The LocationManager onLocationChanged listeners still work for network, but not the PositioningManager callbacks.
If I change the mock provider to override LocationManager.GPS_PROVIDER instead of network, onPositionFixChanged() and the map updates correctly, but then the real gps coordinates are lost.
SDK 3.9 behaves the same.
Even changing Positioning Manager startup to not use gps, only network does not work, I get no updates from either provider then.
Switching back to 3.7 aar file makes it all work again (with no other code changes)
In case it helps, the device is running Android 5.1.1
Thanks!
I had a closer look into this topic and the root cause is here a change with the following background:
Within the 3.7 SDK we experienced an issue with the Tunnel extrapolation broken by "bad" network positions - In a simple test app a tunnel extrapolation was interrupted by a network position claim to be 24M accurate but likely was not. This is just one example but something which definitely should not happen. Within changes introduced ion 3.8 one we considered that the Android HERE We Go did not have this problem because it only uses LocationMethod.GPS during navigation and LocationMethod.GPS_NETWORK at all other times. The implementation of the same behavior means generally better navigation in tunnels is underway.
So the usage of an external device to get the location will not working starting from 3.8 and for now it is considered as expected behavior.
On the other hand it is not needed any longer as the SDK supports a much better tracking.
I am using Phonegap Build version 3.4.0 with the geolocation plugin version 0.3.7.
My app should display the users location on a map.
This works very well under iOS.
But depending on the location settings in Android I am getting very different results.
If I am trying to get a quick location fix with enableHighAccuracy: false and the user has disabled Wireless Location Access, my error callback gets called with the error code 2. This is what I expected.
But if I am trying to get the best result with enableHighAccuracy: true and the user has disabled GPS Access the error callback does not get called. Instead it just times out.
Is this known behaviour and I have to live with it or is there something I could do?
I am using boilerplate code:
var positionOptions = {
enableHighAccuracy: true,
timeout: 1000*30,
maximumAge: 0
};
function positionSuccess(location) {
console.log(location);
};
function positionError(error) {
console.log(error);
};
navigator.geolocation.getCurrentPosition(
positionSuccess,
positionError,
positionOptions
);
Edit: this is tested on Huawei/Android 4.0.3, Moto G/Android 4.4.2, Samsung GT-I9100/Android 4.1.2, LG ???/Android 4.1.2
The geolocation on Cordova can be very tricky to get working correctly. I'm still occasionally battling with it myself. If you get a timeout make sure the geolocation code is even compatible with your test device by extending the timeout to ~300,000 ms (5 minutes). Yeah, if you're in a region with a bad signal it can take that long. Also try getting your location via wifi. And test on a live device (check out TestDevice). Android simulators are iffy.
If geolocation is crucial to your application, you should alert your users of the problem when you get each of these error codes. Tell your user that they need to enable one form of access or another and how to go about doing that.
Also, you can consider running getCurrentPosition where enableHighAccuracy: false, and if that fails run getCurrentPosition again but this time set enableHighAccuracy: true. Only after both methods have timed out, prompt the user with an error.
By the way, in my experience while on an Android, Cordova is usually able to lock onto a location within 2-3 seconds when using 3/4G in an urban environment. If not by then it pretty much never locks on. Good luck!
I ran into a peculiar problem today: We need the users geolocation to provide our service and it is working well so far (implementation before the recent Android Location API release, have not updated it yet). We register like this
((LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE))
.requestLocationUpdates((provider == WPS)?
LocationManager.NETWORK_PROVIDER : LocationManager.GPS_PROVIDER,
minTime, minDist, onChange(ctx, provider)); // onChange create a pending intent
and on certain events we call
Location gpsLocation = LocMngr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Location wpsLocation = LocMngr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
On a HTC One S running on Android 4.0.3 and HTC Sense 4.0 we never receive location updates and the last known location returns null for gps and a 2 day old location for wps. WIFI, GPS and Mobile Data is turned on, i've tried walking around outside and saw the device trying to get a gps fix, but apparently it did not get one. Other devices have no problem with receiveing location updates from gps or wps using the same code...
This only occurs on this device (it's a test device so bootloader is locked, not rooted or any other funky stuff that might break brick it)
I am at a loss, any ideas?
UPDATE
Since we rebooted the device the problem did not occur again, I am still wondering what caused the problem...
UPDATE 2
I ran into the same Problem yesterday with a Galaxy Nexus official Android 4.2.2. So this seems to be a problem of Android in general.
Now that apparently nobody knows how to solve this, is there any way to detect when the Location API is not sending any fixes anymore? Apart from checking the timestamp of the lastKnownLocation()?