I am developing an android application wherein I need the user location updates pretty frequently. Say 2 times a minute.
Earlier I had been using Google Play Service's "Fused location service" but the location updates were not received as requested.
The location updates got stuck for sometime, the interval between updates jumped to 10min or so.Sometimes even if I put my priority to "PRIORITY_HIGH_ACCURACY" the same happened.
I then went back to the old "Location Manager" and when I used the "NETWORK_PROVIDER", I noticed that the location updates got stuck due to this provider. Also the GPS does not get activated immediately, it takes some time. I am trying to build my custom fused location provider. How can I efficiently switch between providers, without getting lags on location updates.
I want to know what are the best practices for getting location updates regularly, all the time, be it either NW, GPS or both. Like it should work for an application where location updates getting stuck cannot be afforded.
Battery drain is not an issue for me right now.I am aware of all the supporting docs that Google provides regarding location access.
Any help would be much appreciated.
Thankyou !
FusedLocationProvider really is the best option for obtaining locations at the moment, because it uses a lot more than just GPS or Network data to obtain location fixes. I have experienced issues regarding intervals being missed as well, but ultimately this is something down to luck depending on availability of GPS, Network, etc. etc.
My favourite usage of FusedLocationProvider so far is in conjunction with the AlarmManager class: Basically, the idea is to start location tracking at intervals specified by the Alarm Manager (this can be set to every 30 seconds such as in your case). Once the interval is hit, the location provider is to obtain a location fix as soon as possible (so in the setInterval method or whatever it's called, the parameter is a 0). This way, you can avoid having to wait another 30 seconds for a new location, instead having the location tracker attempt to provide a location as soon as possible after the interval specified by the Alarm Manager is hit.
By the way, when making custom location tracking wrappers, be careful of using the .getLastKnownLocation() method as it only uses cached locations - you could end up sending the same location to the user every 30 seconds.
Good luck!
Related
I'm building an app that should be able to report the users exact location. There is only a need for a single location, i.e. I don't need to track the device continuously.
I want the location to be as accurate as possible, and it's okay to wait a short while for the location to be determined (max 1-2 minutes).
I've been looking at FusedLocationProviderClient.getLastLocation(), but since I want the location to be as accurate and updated as possible it doesn't fit my needs.
So I started looking at using FusedLocationProviderClient.requestLocationUpdates() instead, and it seems like a better choice.
But I'm not sure how to best configure my LocationRequest to get as good accuracy as possible. For instance, would it be better to use setNumUpdates() so that I only receive a single update and use that as my location, or should I receive multiple updates in hopes of getting better accuracy (GPS locking to more satellites for example)? I'm thinking that if I use the second approach, I could look at the value of getAccuracy() from each location update and only keep the one with the highest accuracy. The downside is that if the device is moving and I keep receiving updates for a minute or so, the first location could have the highest accuracy, but since it's a minute old it's not accurate any more.
As stated above, I need just a single highly accurate location and it's okay for the app to wait 1-2 minutes for it if needed. What would be the best approach in this kind of scenario?
First, make sure the accurate location is turned on. look at Settings.Secure.LOCATION_MODE_HIGH_ACCURACY It has a noticeable advantage over only using GPS. Then listen for the location for a while and calculate the result you get to find out the best location. You can also detect if the user is moving if the number differs a lot or by using Activity Recognition API. It shouldn't be very hard to write this calculate function to get the best result.
I'm not sure about this but I really don't think waiting more than a few seconds gives you an advantage. to be sure you can simply alter this time and watch the result.
You might want to use LocationManager. In my experience FusedLocation will indeed appear to lock faster but may not be as accurate overall, or at least for a while. I have an app that also requires pretty accurate coordinates. My default is to use a LocationManager based approach but users can switch to a FusedLocation provider if they want faster locking (like when indoors).
This is a good overview https://developer.android.com/guide/topics/location/strategies
For the provider when requesting updates I'd use LocationManager.GPS_PROVIDER. It will take longer to lock since it will wait for satellites and not use Wifi or other towers. But you said that's OK. Something along these lines
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, YourLocationListener);
Once you start getting location updates via your listener's onLocationChanged() you can start to inspect the location for accuracy, movement from last location change, etc. to try and evaluate if the GPS receiver is still settling in on a location. Once you are satisfied with the quality of the fix you can stop receiving location updates (locationManager.removeUpdates(YourLocationListener)) and then run your logic that needs the location. The link I provided has good info about this too.
I'm currently working on an Android app that use location to operate. Imagine that when you run app, it will display all near-by hotel.
After reading the Internet, I applied Google Fused Location to my app but some problem occurred and I have no idea how to solve it.
Here are my approach:
When SplashActivity start, I run the LocationService to create location request and request location update. I use HIGH_ACCURACY option and use both GPS and Network Provider.
In onLocationChanged() I call Geocode Intent Service to parse lat lng to address.
When Geocode Intent Service complete, I receive the result thanks to ResultReceiver (I did the exact same way like Google tutorial) and send a Broadcast to SplashActivity.
When SplashActivity receive broadcast, I start my MainActivity.
Please let me know if my approach is a correct way to use FusedLocationService, this is the 1st time I make location-based app.
Sometime, onLocationChanged() took so long to response (about 3 minutes, sometime forever). I notice that this problem occurred only on Android OS 5, 6, 7 (I do request permissions) but again sometime it really fast (1-2 secs). This problem is killing me, I have no idea how to solve this.
I'm thinking about apply last known location to solve the above problem, but I wonder if there is a way to set a time-out for requestLocationUpdate(). And my app need user current location to display data, so I don't think last known location is a good idea. Anyway, it's good to hear your opinion about this.
Thanks for reading.
Firstly, considering a location is fresh or old could depend on your scenario. I meant, a ten minutes old location maybe useful for weather app, but doesn't sound good for tracking intent.
IMHO, the whole process seem a bit bad, you can give chance to receive location for user even after splash screen
Anyways, i have a scenario for you
Define a timeout value, for instance 10 seconds
Make location request with immediately values (set interval and fastest interval 0)
If you receive location, remove location updates, stop timeout and use location (for geocoder)
We couldn't receive location and timeout finished, refer to last known location
If the last known location is nice for us(mentioned in first paragraph) use location (for geocoder)
I just need to understand this clearly, getLastLocation() method will give me the last known location and requestLocationUpdates will give me the current location every period of time.
now, i am developing a simple app to track mobile phones, which will be in cars.
my Question are :
1- how exactly getLastLocation() works, will this last known location be updated when the location change
2- which is better, using getLastLocation() to have the initial location then update the current location by using the method onLocationChanged or using requestLocationUpdates to have an up to date location every n sec ?
getLastLocation gives you the last location which was there in LocationClient, it can be null sometimes, say if you don't have any other application installed which uses location services, that's a rare case as most phones have Google maps or some other location dependent apps installed.
getLastLocation is only helpful, when you want location for once and your done with it, but for location updates you should use requestLocationUpdates, and using a service, your application will always get notified, when the location changes.
I hope you are using the FusedLocation Provider from play services, so you can specify how fast location updates you need, to check cases of battery drain and performance.
Also to note here when you use requestLocationUpdates then only you will get any location change updates.
so according to android docs getLastLocation() :-
Returns the best most recent location currently available. If a
location is not available, which should happen very rarely, null will
be returned. The best accuracy available while respecting the location
permissions will be returned. This method provides a simplified way to
get location. It is particularly well suited for applications that do
not require an accurate location and that do not want to maintain
extra logic for location updates.
This is the problem with getLastLocation(),that it is not accurate and it may return null if it does not have any last known location in cache.I have faced this issue many times in my application.So for getting the accurate location you should use requestLocationUpdates() but define the interval according to your need at which time interval you want the updates as a very short time span may cause more power usage.
I am building an app that can use a user's current location on certain actions. Location is more of a benefit to the user rather than a critical part of the process. I'm only interested in very rough accuracy and it can be off by 5 or even 10 miles and still be of value. General plan was to see if the network provider was enabled and then just do
locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
Assuming that no other apps are running, will the phone automatically periodically update the network location? I.e. there will likely always be a value returned by this code which will meet my needs?
EDIT:
I've been doing a bit more research and I think the question I was really trying to ask here was if the Android operating system or the phone itself would update the last known location for the network provider as the phone locked onto different cell phone towers or wifi networks. The answer appears to be no. After force stopping all apps on my phone which I know to interaction with location services, the last known location has stopped updating. So, I'm guessing that these days chances are that most phones will have some location services running in the background updating the last known location but the phone itself won't do it. Hence I think I'll be going with some form of requesting location updates if the last known location is too old.
getLastKnownLocation() only returns the last fix. So if no location providers are being updated the return value of getLastKnownLocation() will not change. The location object will also provide you with accuracy and time of the fix.
I would look at this post for more information. You could use some version of the one shot location.
http://android-developers.blogspot.com/2011/06/deep-dive-into-location.html
Frohnzie is correct about getLastKnownLocation. Getting location is an expensive operation, so it only happens when an app requests it. I've often driven 30 miles or so, opened the foursquare app on my phone, and it showed me venus that were 30 miles away. Clearly they were using getLastKnownLocation.
For your use case, I would recommend LocationManager.requestLocationUpdates. You can specify an accuracy and a timeout. So if the phone can't quickly find a rough estimate of the user's location, you can just forego location since it is not crucial to your application.
I am experimenting with Androids location updates. The requestLocationUpdates is responsible for providing the updates. With the following code:
locationManager.requestLocationUpdates(provider, 300000, 10, this);
I am only supposed to receive updates 5 minutes and 10 meters apart. But the updates just keep coming in seconds apart and even when I am sitting still.
GPS is the provider I am using.
I need to space the updates out. What can I try?
The 10m is too small - I would increase that. GPS accuracy isn't great, and so every time it senses a small difference you will get another location. I'd bump it up to 100m and I expect you will then get a sensible number of locations coming through.
If you do want it more specific, then you'll need to handle the volume as more accurate means more volume.
Hers what i'd do:
First of all I check what providers are enabled. Some may be disabled on the device, some may be disabled in application manifest.
If any provider is available I start location listeners and timeout timer. It's 20 seconds in my example, may not be enough for GPS so you can enlarge it.
If I get update from location listener I use the provided value. I stop listeners and timer.
If I don't get any updates and timer elapses I have to use last known values.
I grab last known values from available providers and choose the most recent of them.
The 10m is too small for a GPS reading, try 100m. You'll also have issues with power saving mode, and app battery optimisation on most Android phones.
Android 10 and above has very strict background location updates, and may kill apps that run in the background. Later versions will also remove apps that have not be used recently.