locationmanager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationlistener);
I understand that this line of code is supposed to update the device location as frequently as possible right? Specifically, every 0miliseconds and 0metres (minimum).
Okay, the word 'minimum' is key here but still, why sometimes the location is not updated for maybe as long as 30+ seconds? I have timed the actual time between one update and the next, while on WiFi, and it took 38 seconds even though I had 0 and 0 in the code. I even tried it with 1000ms (1second) but still doesn't update as frequent.
How do I make this update more frequently? Why does it respond this way?
Thank you!
The short answer is: you can't (make it update more frequently).
The documentation indicates that you will get "updates as frequently as possible" if you specify min_distance and min_time as zero. So what you are seeing is "as frequently as possible". Usually you won't get an update unless something has changed, so if you aren't moving you won't necessarily get an update. Also, since you are using Network location and not GPS, the accuracy of locations isn't that good so you shouldn't expect updates that frequently.
Also, each hardware vendor implements the location providers differently. So the frequency of updates is determined by the hardware vendor's implementation.
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.
Android 8 only allows background location updates a few times per hour. This isn't a problem since I only request them about once an hour and only if the device isn't STILL and there arn't already passive updates doing the job. So maybe a few times a day. No detectable battery use on Android 7.
However, I do have an accuracy requirement and I discard locations with horizontal accuracy worse than about 1000 feet (Basically cell tower locations). The problem is that the network location comes almost instantly, and then the app is throttled and never receives the next update which might come from the GPS. Typically I would wait a minute to get a location with the desired accuarcy and then give up. On Android 8, even if I wait an hour I just get the network location every 20 minutes or so because of the throttling.
I can't find any LocationRequest setting for miniumum accuracy which would solve the problem entirely. PRIORITY_HIGH_ACCURACY absolutley does NOT do this. It is only a "hint". setSmallestDisplacement() doesn't help because it doesn't affect the first update. Batching updates helps on rare occasions in my testing but not with any reliability.
Further, waiting in PRIORITY_HIGH_ACCURACY for any length of time is not reasonable from a user perspective since the location indicator will be active on the device the whole time, even if the app is being throttled.
Does anyone have suggestions on how I could solve this problem? Perhaps Android does not intend for PRIORITY_HIGH_ACCURACY to be used in the background at all, although I can find nothing about this in the documentation.
If you need GPS, just use the GPS provider. Don't screw around with the Criteria, request what you really need.
I have a background service which works periodically by timer.scheduleAtFixedRate.
It wakes up every amount of time (let's say 60 seconds for example) and checks for the location.
The location is checked by locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 60000, 5, listener); and the actual location is collected from the listener's onLocationChanged.
Now, when the phone is outside and GPS reception is good, this works fine.
But, if the phone is inside, the GPS is almost always active - looking for a signal, and the battery is drained rapidly.
I created another thread using a Handler and a Runnable in order to conrol the GPS active time accurately:
I used locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener); and locManager.removeUpdates(listener); so I can open and close the GPS as I want.
In this case, I can open the GPS for the exact amount of time, but found out that it doesn't lock in an area with good reception even after 10 seconds. So here I'm draining the battery again...
I'm using API level 7, hence I cannot use locationManager.requestSingleUpdate.
I have two questions:
Is there any way to optimize this process?
Will upgrading to API level 9 (and use locationManager.requestSingleUpdate) improve the process significantly? I mean, does it worth upgrading?
How about NETWORK_PROVIDER explained here?
You could have a system that if you cannot find a location in limited set of time, which means you are inside or GPS reception is not good enough, you can use the network location instead. Since that uses less battery, it would at least be a workaround or alternative. But the presicion would be lower.
This is a very strange behaviour. If I have something like this (time interval set to 30 minutes):
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,30 * 60 * 1000,100,mLocationListener);
My first fix takes forever and sometimes I don't get it at all (I waited for about 20 minutes) However if I choose a smaller interval for the time (30 seconds) I get it right away.
I thought that the values minTime and minDistance are only for getting new consecutive updates, and it wouldn't affect the first fix. I should get the first fix as soon as it's available. Am I doing something wrong?
Thanks
I'd suggest to use two locationManagers, one as you are already doing for long-term updates, and another to get the first fix. Then you can unregister the second one as soon as you get the callback from it.
I heard of this pattern from Reto Meier and it's called "back-off" location. We are using it in mixare with the coarse location manager to get the first fix, and the GPS to get more precise infos. You can check the code here: https://github.com/mixare/mixare/blob/master/src/org/mixare/MixContext.java starting at line 150 (more or less)
HTH,
Daniele
You may check, if well-known 3rd party GPS tools (like GPS Status) have problems as well, or there is something with your code.
Please keep in mind that satellite visibility -- and therefore GPS signal quality -- may change quickly and first fix in a few days may take substantially longer than usual.
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.