I've been working on an app that needs to be location-aware, and I've noticed that there are two (or more) methods of receiving location: with Google Play services (as seen here developer.android.com/training/location/retrieve-current.html#GetLocation) and with Location Manager, Providers etc. (as seen here http://www.vogella.com/tutorials/AndroidLocationAPI/article.html#locationapi_criteria).
What is the difference between these methods (if there is any)? Which one is more accurate?
edit: ok, I see that I sent the wrong link on the first thing. Won't this code (http://developer.android.com/training/location/receive-location-updates.html) give me location updates? Generally, what's the most accurate way to get my location?
The one with the GPS is accurate and that which is based on Network is not. Google Play Service use FUSE api to get the GPS location first, if the location is found (that's great), otherwise it will try to get location fix from Network Tower. In Short the one with GPS is accurate
The first method provides the details of LastKnownLocation. ie. the last location received from GPS or network provider when you or other apps accessed the location services. After that there are chances you moved a lot and it need not be your current location. So if You are planning to create an application that requires accurate location tracing, You should fetch the location as in the "Vogella" method. If the current location is unavailable, you can try using the last known location (As a plan B :-)).
Related
I am using FusedLocationProviderClient to get location updates in a foreground service. On testing and observing for few days, I found wrong locations which was far away from my actual location by around 4 kms similar to this, but the LocationResult had an accuracy of 24 meters. How is this even possible?
It can be eliminated if the accuracy was around 4 kms. This behavior does not occur very often but occurs atleast once in 4 among 10 devices. It becomes a problem when I calculate distance traveled.
I can tell it's not a cached location because I used to turn off and on Location Services everyday. (As per docs, turning off Location Services clears cache location.)
Any idea why it's giving wrong location and how to eliminate it? And also clearing cache locations without turning off Location Services?
FusedLocationProvider CAN give incorrect results like that when gps connectivity for device is down(or insufficient satellites are in "view" to provide accurate data). It will use the nearest cell tower/location data provided by the wifi router(google tracks this automatically) giving WILDLY incorrect results in places where google doesn't have a strong location mapping presence - which is anywhere outside an urban center.
You have imho two options:
Use the non googleplay based solution based on location service - this has an option for ignoring non-gps location data(wifi/cellular).
LocationManager locationManager = (LocationManager)
getApplicationContext().getSystemService(LOCATION_SERVICE);
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_Provider);
You can even specify the number of satellites required for acceptable data so you can get REALLY accurate location data. You will lose information when the gps doesn't receive coordinates (like indoors), but in exchange will have less "noise" from incorrectly mapped location, as per your requirement.
Use a "snap to roads" API. There is a free version using open street map data called Project OSRM(Open Source Routing Machine) that provides a backend when hosted (locally or in cloud) using docker or building source yourself (details in link).
curl "http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true"
This request will return a location that is "snapped" to the nearest road. There are various options such as giving priority to highways etc. You can then discard the points that are not on the "path" that the user was previously on as rapidly shifting to a road 4km away and then coming back again is not likely.
I need to find location of the user in my app, and to see if he close to some specific places.
first I try to check if he close to those places by NETWORK_PROVIDER (to save battery power), and just if the answer is positive I use GPS to find accurate location.
How long worthwhile try to find a place through NETWORK_PROVIDER before I decide whether to use also GPS?
eg, after 1 sec or 20, the devise likely succeed to find location using network?
thanks!
It is really difficult to tell, I would suggest using Google play services location api instead. You can't know for sure if first received location is even remotely accurate, especially with network based that is useless in places where Google have no wifi ssid-location match.
Im writing an android aplication in which is required the actual location of the user, but I'm having trouble acquiring that location.
I'm using a LocationListener to listen for the location update, via Wifi (NETWORK_PROVIDER).
The problem is I don't get an update, and I imagine it only happens when I change network. If I don't get updates, I can use lastKnowLocation but it does not provide me with the actual user's location.
Is there a way to force a location update, via NETWORK_PROVIDER?
Cheers
Even better, I suggest you look at the new Location APIs in Google Play Services.
There's a training class for them as well.
I use network provider to get location in Android application. Sometimes I found the location would not be changed even after I arrived at a new place. At the same time, I found the locations were changed in Google Map. So I quit and restarted my application, and the locations wasn't changed either. But after a long period, or I reboot the phone, I could see the new location.
Does any one know what's the reason ? I have used getLastKnownLocation() to get the latest location in my application.
Update:
When this problem happened, I found the cellid and LAC was changed while the location wasn't changed. So it's very strange. I think Google Map may use cellid & LAC to get the location directly, so it can get the correct location.
More update:
When this problem happened, I used the cellid and LAC to get the location via HTTP POST request from Google server. This location was correct.
BTW, I found my question was like this question: Android network location takes hours to update location
I wouldn't trust getLastKnownLocation(). In my experience this isn't reliable.
You'd be better off requesting location callbacks using LocationManager.requestLocationUpdates(). If you only need the location once you can then unregister for the callbacks using LocationManager.removeUpdates() after that. If your application needs to be notified when the location changes then you can register for callbacks with a reasonable minium-time and/or minimum-distance parameter (based on whatever your application requires.
I want to make sure the location received by the LocationListener is a "real" one and doesn't come from a spoofed source (I.e the Application Location Spoofer). I don't care about "but the user sometimes want to spoof the location" - it's about an app which doesnt get distributed over the android market. The application does not need the location to be that accurate - it just has to be "real".
Do you think there is a way to check if the location has been spoofed?What do you think is a good way to prevent location spoofing?Is there maybe a android-method which gives me the real location nevertheless?Is there maybe a android-method to determine if the location has been spoofed?
Thoughts I had:
Check on a blacklist if a location-spoofing app is installed
Enable/disable different location providers and check against their returned locations
Run a background service watching the location (in a passive way) and check for sudden location changes
Please give me your thoughts and input to this issue.
From the Provider name: 'gps' or 'network' are proper
Most spoofers forget to send GPS status updates. That is something that you can use to your advantage
// returns true if mock location enabled, false if not enabled.
if (Settings.Secure.getString(getContentResolver(),
Settings.Secure.ALLOW_MOCK_LOCATION).equals("0"))
return false;
else return true;
The best method is this :
Mock location providers do not send NMEA data. So create a NMEA listener. If you don't get NMEA update but you get valid GPS updates in onLocationChanged() a spoof is being used.
Have a look on "Maintaining a current best estimate" topic on the following page:
Maintaining a current best estimate