LocationManager still cant find last known location after GPS is turned on - android

I'm having a problem with android where even after the user turns their location service on, the LocationManager still can't find the users location.
Before I launch the activity that needs to use the user's location I call the following:
//Menu Activity
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
if(lm.isProviderEnabled(LocationManager.GPS_PROVIDER){
Intent nearby = new Intent(mActivityContext, NearbyActivity.class);
startActivity(nearby);
}else{
alertNoGps();
}
Once GPS is turned on the nearby activity can be launched, but the LocationManager still cannot find the users last known location. My relevant code for this is:
//Nearby Activity
try{
LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(location != null){
...
}else{
Toast.makeText ...
}
} catch(SecurityException e){
e.printStackTrace();
}
The phone I'm currently testing on is running Android Marshmallow 6.0.1. If the GPS is already turned on before the app is run through android studio then I have no problem getting the last known location. It's only when the GPS is turned off before I run the app and turn it on while the app is running that I have problems. What about LocationManger is causing this?
Edit: Also in the manifest I have both Fine and Coarse location permissions. I do not know if this is an issue with API 23 and above because of the extra permission checks required, but I have to imagine they are still handled by the Security Exception.

There are two different ways to retrieve the location, one is based on network and another is based on GPS services. Certainly, location based on GPS services would always be more accurate.
According to the documentation, it might take some time to receive the location using the GPS services. In this case, the last known location can be used to get the recently available location by using getLastKnownLocation() method.
Here, to get the last available location, you should change
LocationManager.GPS_PROVIDER to LocationManager.NETWORK_PROVIDER.
And if you wish to receive the accurate, real time location based on GPS services, I recommend you to use FusedLocationApi.
You can find it here
https://developer.android.com/training/location/receive-location-updates.html
Cheers..!!

This is exactly how it should work. Android clears the last known location for a provider when it is disabled, and will return null until a new point is polled for that provider.
In your situation, I would recommend that if you get null location point for last known location with GPS, just request for a single update.

I found out that similar to Pablo's answer, getLastKnownLocation() will be cleared and because it is a rather casual function can return null quite often. If GPS coordinates are more demanded, then you should be more forceful when trying to get GPS coordinates and use something like requestLocationUpdates() or Google's FusedLocationApi rather than getLastKnownLocation().
So now I am using FusedLocationApi with a GoogleApiClient I built using:
client = new GoogleApiClient.Builder(mActivityContext)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
After the client is connected I find the GPS location in the onConnected() method override which looks like:
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Location location = LocationServices.FusedLocationApi.getLastLocation(client);
This seems to be much more reliable in finding GPS coordinates.

Related

Android fused location api not providing consistent updates with screen off

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.

getLastKnownLocation is not the actual location

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).

Android LocationManager.getLastKnownLocation()

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.

getLastKnownLocation() always return the same location, even after device is moved

I set up my location manager by executing
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Then I call have a update button on my app so that when it is pressed, the I will call executing the following line
Location loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER)
However, the location that I get is always the same one, even after I held the device and walk straight for 20 meters and then wait for 10 minutes!
May I ask if I missed anything?
Thanks!
The getLastKnownLocation() method returns the last GPS location acquired. If you don't start GPS location acquisition to have it acquiring new locations, the value returned by this method will always be the same old value.
You will need to:
Register for location updates with lm.requestLocationUpdates()
Define you onLocationChange() listener to receive the new locations
Add permission android.permission.ACCESS_FINE_LOCATION in AndroidManifest.xml file
Enable GPS utilization in phone setings
regards

How to get current location on android

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.

Categories

Resources