i'm working on app, which must get latitude and longitude. in my case requestLocationUpdates (String provider, long minTime, float minDistance, LocationListener listener) is not in option. why? because i must get location just when user do something that location is needed (let's say he hits button). and i need location exactly on the time, when button is hit. in requestLocationUpdates, we can set minTime-if i set this let's say on 30000 the location at the "button hit time" won't be as good as i want. of the same reason minDistance is also not as good as i want. if i understant function requestLocationUpdates correct-when minTime and minDistance are set to 0, location is updating all the time. please correct me if i'm wrong. app is for company that i'm working at and that app will be used through the day and night. so if app will check for location updates all the time, battery would be often empty. thst's why i need location just at the time, that button is hit. i found requestSingleUpdate function. but i can't use it in eclipse =( like it doesn't exists.
is there some other way to do this or am i missing something?
The requestSingleLocation method new for API level 9. If you are targeting an earlier API level, this method will not be available to you.
One of the problems with obtaining location information is that it can take time to get a fix. This is more of a problem with the GPS location provider than the network provider. If you are only using the network provider, then there may not much of a delay with getting the location information when the user clicks the button (I say this knowing nothing about what your app does with the data, or what type of user experience you are trying to provide).
Something else you can try is the PASSIVE_PROVIDER. It allows you to get location updates that were requested from other apps. This will mean that you have to request the ACCESS_FINE_LOCATION permission however. You may also need to leave something running to receive the location updates (likely a service or a BroadCastReceiver). The BroadcastReceiver approach should not use that much additional battery life since it only runs when the Intent is received along with the PASSIVE_PROVIDER only getting locations when some other app requested them anyways.
The other sticky point with the PASSIVE_PROVIDER is that you should eventually call removeUpdates. Where and when to call this really depends on how your app is structured and how you handle the user exiting the app.
You can use getLastKnownLocation method, but it can be out-of-date. requestLocationUpdates is asynchronous because gps needs to "warm-up" to find new location.
requestSingleUpdate method is available since api level 9, but you can implements it's using requestLocationUpdates and disabling updates after first callback to LocationListener.
Related
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 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!
I have a Service implementing LocationListener listening for both GPS and Network.
The application is dependant on a constant location-feed, but it seems when GPS has a hard time getting a locationfix network location doesnt step in.
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000 * 30,0, LocationReporterService.this);
manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000 * 60 * 2,0, LocationReporterService.this);
Questions
How do I make sure that I always get a location?
How can I make sure that if I dont get a GPS-location, I get a Network-location?
Is it a known bug?
Should I have 2 services, GPSLocationService and NetworkLocationsService?
Is there a solution to this? :)
I agree with most of comments from AlexBottoni good answer, although in some points I can't suppot him.
Overview
First, just to check that you are doing it right...
You setup the same LocationListener for both providers. To indentify from where you are reciving the location you need to test it like this:
public void onLocationChanged(Location fix) {
if(fix.getProvider().equals(LocationManager.GPS_PROVIDER)){
//here Gps
} else if(fix.getProvider().equals(LocationManager.NETWORK_PROVIDER)){
//here Network
}
Also, you setup a different acquisition frequency. Gps is providing a new location every 30 seconds and Network every 2 minutes.
As you didn't impose a minimum distance, you should receive a new Location from each one of the providers (as long as they can get a fix) with the frequency requested. If you don't receive a fix, is because they weren't able to acquire one.
Also, it may takes a little longer then requested to get the fix (mainly with Gps), because it may take some time to shyncronize with satellites and fix a location.
Fallback
There is no builted-in fallback from one provider to the other. They are independet, as said by Alex. I'm using the following approach to implement fallback:
Register Gps listener and start a timer
On every GPS location, restart timer
If timer reachs end, register Network listener (Gps listener keeps registered)
If new Gps location arrives, unregister Network listener, restart timer
Preferable Provider
Although Gps may not be available everyhere, is far most precise then Network. In my town, I get 6 meters accuracy with GPS and 1 Km with Network :-(
Two services
Doesn't matter where you register the listener, activity or service, separate ot together, as long as you request them and the provider can get a fix, you will get the location (assuming no bugs in application :-))
Final Notes
Ensure you have the permissions need (ACCESS_FINE_LOCATION, INTERNET, etc).
Ensure that phone setup have Network Location enabled (usually default is disable)
Most Gps receivers support updating information about satellite location, which improves fix time. You can use GPS Satus from the market, to do it.
Regards.
This is really weird because, AFAIK, Android does not fall back to the second choice (network location provider) only if and when the first one (GPS) does not work. The two location providers are indipendent and should be sending location updates to you listeners indipendently to each other. Hence, the first one (GPS) should not be able to block the second one (network) in any case.
Regarding your questions:
How do I make sure that I always get a location?
You don't. There is no way to be sure. There are cases in which you cannot get any location fix just because no location reference is available. This is often the case in metro/underground stations. No GPS, no cellular antennas (not everybody lives in NYC or London...), no wi-fi hotspots so no way to determine your current position. Believe it or not, in the new hospital of my town, we have this situation at the moment because GPS constellation is not visible (indoor...), no wi-fi hotspots have been installed yet and the only available CellID antenna is just a few hundred meters away so you get the same signal everywhere, both outside and inside the building.
How can I make sure that if I dont get a GPS-location, I get a Network-location?
You cannot, either. It depends on the available networks. Anyway, you can check what you get from the location providers in your code and switch from one to the next until you get a usable location fix.
Is it a known bug?
No, it is not a bug. It is more a known limit of the existing technology.
Should I have 2 services, GPSLocationService and NetworkLocationsService?
It is something to try. As nick already said, this should not be a problem but a check should not hurt.
Is there a solution to this? :)
If your app is intended to be used mainly in a urban environment (a town), most likely you should use the network location engine as your main location engine. Nowadays, every village and town is covered by a large set on cellular phone antennas and by a large set of wi-fi hotspot so you are more likely to get a good location fix from the network location provider than from the GPS one. This is particularly true in towns with high buildings and narrow roads (that does not just mean NYC. Even here in Venice we have problems with the GPS). The network engine is also faster in getting a first fix and works indoor as well.
Fall back to GPS only if and when the network location engine does not work.
How can I get a single GPS fix of my location just by calling one function? Just for this example how can I get the Lat and Lon into a toast.
What have you tried?
Here are two of the official pages for location: http://developer.android.com/reference/android/location/Location.html
http://developer.android.com/reference/android/location/LocationManager.html
But to get the most recent location and show it in a Toast:
LocationManager locMan = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
Location loc = locMan.getLastKnownLocation(LocationManager.GPS_PROVIDER);
String lat = String.valueOf(loc.getLatitude());
String longitude = String.valueOf(loc.getLongitude());
Toast.makeText(context, lat+","+longitude, Toast.LENGTH_LONG).show();
If you want to request a new location, it is more code, and I will not cover that here. You can do some google searching or searching on here to find how to use it. The method you need is requestLocationUpdates or requestSingleUpdate. I'm guessing you would prefer requestSingleUpdate
I do not think that you can just make one call and get a location fix. GPS / Android just doesn't work that way. The phone may have a last known location, but that last known location may have been taken/recorded hours ago and miles away. The location returned by the getLastKnownLocation() method has a time stamp and an accuracy that can be used to see if the location is "good enough".
Locations are typically determined by setting up a listener, listening for updates and stopping the listener when you have a good enough fix. See Obtaining User Location for a good worked example, especially the details in the example isBetterLocation() method.
I find it best to create an Asynchronous task that actively registers and deregisters GPS/network/passive listeners depending on whether the application has a good enough location, or not, and have that class export a getMyPosition() method that returns a Location object if a good enough position has been established, or null if not. Then the main code can make a simple one line function call to get the current position. But only because there is an asynch task behind the scenes doing the hard work.
I try to make my asynch task actively deregister the GPS listener and turn off the GPS circuits to save battery live when I have a good enough fix. How long I turn off the listeners depends on the needs of the application. Leaving the passive listener left on (registered) allows my task/application to listen into the GPS position reports caused by any other application on the device "for free".
Getting a good enough position is not a one function call deal, unless you make it so with lots of behind the scenes work.
I'm using
myLocation = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
to retrieve the current location at the start-up of my application.
As the Android documentation states, this location can be "out-of-date", since the method returns the location when the GPS was used the last time.
How can I actively request the current location from the GPS? I thought about using LocationListener, however that might be a bit of an overkill, since I only need the location once (at the start of my app).
Any ideas?
Your initial intuition is correct - you need to use a LocationListener to request updates. Given that you require only a single position, you can unregister the LocationListener after the first value returns.
In practice though, it's probably wise to listen for a little bit longer. Location Based Services (particularly GPS) have a tendency to 'jump around' a bit when they first get their fix. Your best bet is to listen for a set amount of time, or a set number of updates, or until a certain level of accuracy has been achieved (the Location Listener will return the accuracy of the position returned).