I've got an app which sets up two location listeners (one for GPS and one for network) and then chooses the location from the best one available, which should be GPS. However, if GPS is turned on, it will always choose the GPS location, even if the person starts the app up indoors. This has led to the GPS location being used even if the last known GPS location is from miles away and the network location is actually much more accurate.
Is there any way around this issue or is it just something that will need to be accepted as an issue with using GPS & network? Is the standard practice just to assume that GPS is always more accurate even though it's possible that it might not be in certain instances?
If you are using the network provider to fetch the location they are not very accurate when compared to GPS. So it can be a good idea to fetch the accuracy of your position using network provider when you are indoors as GPS doesnt function well indoors and you can use GPS to get the location updates when you are outdoor.
You can use GetAccuracy() method of Location class and see for the value it returns. Let Say if getAccuracy() retruns 25 then you can leave this value wait for another gps value until you get the desired value. Remember the value it returns is the radius of the circle in meters.
Related
This is how I start the location listener:
LocationServices.FusedLocationApi.requestLocationUpdates(mLocationClient, REQUEST, this, Looper.getMainLooper());
Where my request looks like this:
public LocationRequest REQUEST = LocationRequest.create().setInterval(PS_MEDIUM_REQ_TIME).setFastestInterval(PS_MEDIUM_REQ_TIME)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
The issue is when I get into the metro, not having gps signal, it get the data from networking. And 3G etc, works via repeaters, so it will throw my location to the nearest data Tower. I would prefer it to simply just not give locations, in this case, cause throwing my location a couple of kilometers far away is not an acceptable case.
So my question is: is it possible to force it to accept only gps coordinates? Or to atleast check from where they come, so I know if to accept or not?
This is from the docs of the LocationRequest:
Applications cannot specify the exact location sources, such as GPS, that are used by the LocationClient.
But when using the LocationManager you can request location updates specifying a location provder, for example LocationManager.GPS_PROVIDER.
See LocationManager
Since you need to use the FusedLocationProviderApi you might want to use the Location.getAccuracy() method to reject or accept location readings. The accuracy is given as 68% confidence radius. A smaller value means higher accuracy. The higher the accuracy, the more likely it was acquired using GPS.
There also is a Location.getProvider() method which returns the provider if it was set. If the provider wasn't set it will return null.
Additionally you could use LocationRequest.setPriority(int) and use LocationRequest.PRIORITY_HIGH_ACCURACY as parameter to make sure you only get the most accurate readings.
Some resources say getLastKnownLocation() merely gives a location of some previous app's Location Change Listener.
But one thing I feel is missing from the conversation -- if the phone has GPS enabled, isn't this GPS tracking/updating as the phone moves? So if I call getLastKnownLocation(), isn't it getting the current GPS from the phone's constantly-updated GPS?
If so, then why do people warn against using it / accuse it of potentially getting a "stale" location? If the GPS is being tracked / updated, and getLastKnownLocation() makes a one-time grab of it's current position, what makes getLastKnownLocation() bad?
What am I mistaken about the Locations service or GPS?
The documentation says: Returns a Location indicating the data from the last known location fix obtained from the given provider.
Also, about the "out of date location": This can be done without starting the provider. Note that this location could be out-of-date, for example if the device was turned off and moved to another location. ("This" refers to getting the last known location).
Also, taken from LocationProvider docs:
Each provider has a set of criteria under which it may be used; for example, some providers require GPS hardware and visibility to a number of satellites; others require the use of the cellular radio, or access to a specific carrier's network, or to the internet. They may also have different battery consumption characteristics or monetary costs to the user.
if the phone has GPS enabled, isn't this GPS tracking/updating as the phone moves?
Well, it is, but not constantly. This has to do with battery consumption, if the phone was constantly updating the GPS location, the battery life would suffer a lot. The GPS location is usually updated when some app requests it. But even that request is not guaranteed to succeed. For example, suppose your going into a tunnel. Some application requests to update the GPS coordinates right before entering the tunnel and it succeeds. Now, you've entered the tunnel, which is 5km long. Most probably your device won't be able to get a GPS fix from the tunnel, so for the next 5km (at least) getLastKnownLocation() will return an outdated value, since the devices last known location was at the entrance of the tunnel.
What you could do is explicitly request to update the GPS location, that however might take some time and there are no guarantees that it will succeed.
You have the assumption "if the phone has GPS enabled, isn't this GPS tracking/updating as the phone moves". This assumption is incorrect. The GPS functionality takes up a lot of battery life so it should be used sparingly and almost certainly not all the time.
Hi i am working on a real time location tracking application where i have used Fused Location provider Api. I was able to get the location updates when the device is moving. But i was also able to get the location updates even if the device is stationary on a table when i am indoor. So I have calculated the distance between the last location and the current location triggered in Onlocationchanged event and checked whether the distance is less than 30 metres, to know the device is actually moving. But sometimes the distance i get is greater than 400 metres (indoor/Device is Stationary). How Can i ignore the onlocationchange event when i am indoor? Any suggestions are appreciated.Thanks in advance.
Unfortunately I don't believe there's much you can do about it.
The reason you see those updates with great changes it's because indoors, you won't get a GPS lock, so the device is relying on cell tower and WiFi hotspot triangulation to determine your location, and something around 200m to 1km is the best you'll get with this kind of technology.
A possible attempt to hack-around it would be to:
check the source and precision of the location update
use the activity recognition API to guess if the device really moved
but both are a hack, around the technology limitation and might not be as reliable.
I have re-read the whole documentation and as I understand, this API intelligently fuses the providers to give you an accurate result.
The Fused Location Provider intelligently manages the underlying location technology and gives you the best location according to your needs.
To my understanding, it will use Network and WiFi and GPS to give you a location. Now it is only logical to assume if one of those 3 is unavailable, it will use the remaining 2.
My problem is I'm testing my app to get Location when both WiFi and GPS are off. That will leave Location Service with the network provider only. But I'm getting Latitude and Longitude = 0.0
Long story short, either way I'm wrong in assuming that it will work relying only on network (no GPS, no WiFi) or there is something else I don't know or haven't read yet. Which of this 2 is my issue?
PS: my LocationRequest configuration is set to setInterval(30000) to setFastestInterval(60000) (30 and 60 seconds respectively, for each update.
getBestKnownLocation Returns a Location indicating the data from the last known location fix obtained from the given provider. This can be done without starting the provider. Note that this location could be out-of-date, for example if the device was turned off and moved to another location.
when the Last Known Location updated in Android? is it updated if when there's an application listening for the location provider, if so what if there's no application that it ask for the location and then you asked for LastKnownLocation() ?
I thinki LastKnownLocation() is updating when some programs in your phone use this function requestLocationUpdates.
Please see Start location strategy
I did some investigations: I turned on GPS and waited to get a fix. Then I turned GPS off and drove 50km (31 miles). Then I used the code from A Deep Dive Into Location to get all the getLastKnownLocation. I tried it twice, first with GPS turned off and second with GPS turned on, but without a fix:
1) with GPS turned off I got
- Provider: network, correct location with accuracy 680m
- Provider: passive (mProvider=network), same location as above, same time as above
- Provider: gps, location null
So I learned that when gps is turned off you get no getLastKnownLocation from the GPS location provider.
2) with GPS turned on I got
- Provider: network, correct location with accuracy 652m
- Provider: passive (mProvider=network), same location as above, same time as above
- Provider: gps, location as it was 2h earlier with accuracy 12m, time was also 2h earlier
Here I learned that old messages are not invalidated, even it is obvious that they are wrong.
So to sum it up: when a provider is active, it stores the last received location retreivable via getLastKnownLocation. If the provider is deactivated, you don't even get getLastKnownLocation. Please note that I tested this with the GPS-Provider, other providers may react in a different way.