In my app I have an AlarmManager set to run an IntentService every so often to make a WebService Call to my server sending your current location
When the alarm is started I also start a Service that has a LocationManager to keep track of the location locally.
When I make the web service call to my server I use
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
String provider = locationManager.getBestProvider(criteria, true);
Location lastKnownLocation = locationManager.getLastKnownLocation(provider);
since I only need the location at this point in time and the next time the web service is called again I just get it again. But it appears even though I have a service running in my background that uses the GPS and gets the right location, calling
locationManager.getLastKnownLocation(provider);
when I make the web service to get the location it gives me a stale location and not the current one. Now I would think that since I already have a locationmanager running in another service that the getLastKnownLocation would get updated to the correct location everytime the onLocationChanged gets called but that is obviously not the case which makes no sense to me.
So my question now is how can I get my correct location in my IntentService since I cannot rely on getLastKnownLocation
I do no need to know the location everytime it changes I just need to know what it is at the time I make the web service call so starting another location manager does not seem like a good idea. The only thing I can think of to solve this is to store the location from my other service in SharedPreferences and just grab whatever is in there but that seems a little hacky and i dont like hacky.
any ideas?
The last known location for android gets updated only when any app requests for a location (app can be yours or any other on the device). You have to implement the location listener and then use locationManger.requestLocationUpdates(provider, minTime, minDistance, locationListener) to ask for the location update. The android system will get the location update on your request and set the lastKnownLocation for all apps to use.
The only reason I can think of the lastKnownLocation not being set is that the android system couldn't get the location. Check that the provider requested for the location update is enabled. Also you can use Passive Provider for piggybacking on the location requests of other apps and actively look for location only if there is no update for certain time out period (This approach should be better that constantly trying to get location updates which are costly).
Related
I have some code that runs multiple times per second in my app. I'm trying to get my location in every cycle. I am using the following:
Location myLastPos = LocationServices.FusedLocationApi.getLastLocation(googleApiClient)
My app also runs in the background using a PARTIAL_WAKE_LOCK. With the screen on everything seems OK. When I turn the screen off my app still runs normally but I no longer get location updates consistently.
It appears that I get updates much less frequently (often minutes in between updates). I'm checking the timestamp of the location using:
myLastPos.getElapsedRealtimeNanos()
I also found that even when the screen is on I get some strange results. Sometimes I get a few milliseconds between updates, other times I get a few seconds. This is all very concerning. Can someone either help me use FusedLocationApi properly or suggest an alternative. All I really want is to poll the gps directly for lat/long a few times a second without google libraries getting in the way.
The getLastLocation() method just gets the last known location that the device happens to know. The "last known location" here means exactly that: It may not be up-to-date. Locations do come with a time stamp which could be used to asses if the location might still be relevant.
The device doesn't determine its location on its own, but only when some application request the location. So your app is now dependent on other applications requesting location updates.
If you need updates every few seconds, then request regular location updates yourself.
Android documentation recommends the FusedLocationProvider, but the LocationManager is also a perfectly valid option, if there's any reason to avoid the Google Play services.
The basic idea is to first request location updates:
// Using LocationManager as an example.
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Using GPS, requesting location updates as soon as available and even for
// the smallest changes. Here 'this' refers to our LocationListener
// implementation.
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
The updates are then received by a listener:
#Override
public void onLocationChanged(Location location) {
// We received a location update.
// Copy the value from the method parameter to our
// class member variable.
mLocation = location;
}
And when you no longer need the updates you should cancel the request:
mLocationManager.removeUpdates(this);
The approach is very similar for the FusedLocationProvider.
I am trying to make an accurate location based app but I am a little bit confused on how the requestlocationupdates works.
If I put the requestlocationUpdates(LocationManager.GPS_PROVIDER, , ); as a location provider and I test my app. I see that if I haven't enabled the gps it takes updates from the network and when its enabled it takes it from the gps. What is the point of setting both network and gps providers to send updates if they switch on their own?
How does the third parameter of requestlocationUpdates work? I mean it says that it changes in the distance that I set but how it can detects that I have moved?
You can try with following code
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
where Criteria is a class indicating the application criteria for selecting a location provider. Providers maybe ordered according to accuracy, power usage, ability to report altitude, speed, and bearing, and monetary cost.
then
locationManager.requestLocationUpdates(provider,0, 0, new MyLocationListener());
Where second and third parameter are use to so that you can control the frequency at which your listener receives updates with the second and third parameter—the second is the minimum time interval between notifications and the third is the minimum change in distance between notifications—setting both to zero requests location notifications as frequently as possible.
keep in mind, once you requestLocationUpdates(...) means onLocationChanged(...) will be triggered when provider specified is enabled and you will get the latest coordinate in onLocationChanged method. There is a default location aka Cache location, or LastKnownLocation which that system will be use before detecting any new location.
Of course system will treated that you're moving when your current location is different than your previous location (cache location).
From android documentation LocationManager.getLastKnownLocation():
Returns a Location indicating the data from the last known location
fix obtained from the given provider.
Note that this location could be out-of-date, for example if the device was turned off and moved to another location.
How often provider updates device location ? How its works ?
The reason why I asking is that I dont want to use locationListener,
I just need to get current geo location on button click, and thats it.
Can I just do like this ?
final LocationManager mlocManager = (LocationManager) getActivity()
.getSystemService(Context.LOCATION_SERVICE);
final Location currentGeoLocation = mlocManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
How often provider updates device location ? How its works ?
It depends, and you may never know. If a device has good reception then updates about the user's location will fire rapidly.
Can I just do like this ?
Not really. If that is firing too soon then you will not get any location back. If the user doesn't have great reception then it could take 10 seconds before you have a reasonable idea of the user's location. I think you'll have to approach this slightly differently. I'm afraid I must recommend locationListeners :P
if you absolutely can't wait for a location you can try getLastKnownLocation(), but you need to be prepared to have a NULL result.
getLastKnownLocation() is just a cache of the last location from the provider you specified. In some cases there won't be one at all, like when the phone just rebooted. Even when there is a cached location it may not be accurate.
I have found plenty of examples of creating a location listener where you supply a particular provider, like so:
LocationManager lm =
(LocationManager) getSystemService(Context.LOCATION_SERVICE);
LocationListener ll = new mylocationlistener();
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, ll);
However, I don't need a precise location, but I'll take the best available. Is there a way to create a listener that works for the best available at the given time without creating a listener for each provider?
e.g. Use GPS if it is available, if not, Network, etc. Also, this is a widget, so I don't want to check what is available, then create a listener for that, since the widget will be up for a long duration and may live through enabling/disabling providers.
Thanks for the help
Have you considered using the PASSIVE_PROVIDER? That combined with getLastKnownLocation() might get you most of the way to what you want... You would call getLastKnownLocation() initially to establish a location if one was already known to the device, then the PASSIVE_PROVIDER would listen for updates from any location provider (i.e., location requests triggered from any other application on the device).
There would still be the possible scenario of no other application requesting location, so you'd likely want to trigger at least a single initial location fix using GPS_PROVIDER or NETWORK_PROVIDER.
Hey guys
i want to get the latitude and longitude of the users location.
I have tried developers site and stack overflow , there are loads of examples targeted on the moving user which use some thing like :-
onLocationChanged()
I dont need updates of the location , the user will just open it for a minute or two
so i need to find the location the time the application starts and what if the user has never used any geolocation app before hence i would also like an alternative for
LocationManager.getLastKnownLocation()
My code is :-
LocationManager lm = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
// connect to the GPS location service
Location loc = lm.getLastKnownLocation(lm.NETWORK_PROVIDER);
Toast.makeText(currentLocation.this, "Latitude -> "+Double.toString(loc.getLatitude())
+" Longitude is -> "+Double.toString(loc.getLongitude()), Toast.LENGTH_LONG).show();
and is working fine.
But i am scared that the getLastKnownLocation may return null when used for first time.
Thanks
Sign up for location updates and once you receive the first update, you can unregister for future updates.
In other words, create a LocationListener and register it with your LocationManager's requestLocationUpdates method. In the onLocationChanged method of your LocationListener, call the removeUpdates method on your LocationManager, with this as parameter.
It might take some time before you get a new location, but except for using getLastKnownLocation there's not really an alternative.