public Location getLastKnownLocation() {
LocationManager mLocationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
List<String> providers = mLocationManager.getProviders(true);
Location bestLocation = null;
for (String provider : providers) {
Location l = mLocationManager.getLastKnownLocation(provider);
if (l == null) {
continue;
}
if (bestLocation == null
|| l.getAccuracy() < bestLocation.getAccuracy()) {
bestLocation = l;
}
}
if (bestLocation == null) {
return null;
}
return bestLocation;
}
Why this function returns incorrect Location?? The mistake is about 8-9 kilometers
Because getLastKnownLocation doesn't return the current location. It returns the last location it figured out via that provider. That position could be an hour old- it will still return it, if it has it. If you want to get an accurate location you need to turn on the location provider by calling requestUpdates or requestSingleUpdate, then wait for the onLocationChanged function to be called at least once. Anything else may be a stale location.
It's because you're using getLastKnownLocation() : location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
getLastKnownLocation(String Provider) : Returns a Location indicating the data from the last known location fix obtained from the given provider.
This can be done without starting the provider. Note that this location could be out-of-date, for example if the device was turned off and moved to another location.
From : http://developer.android.com/reference/android/location/LocationManager.html#getLastKnownLocation%28java.lang.String%29
Related
I am using LocationManager to get the last known location. I found out that it returns null unless the GPS is turned on.
here is my code
mLocationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
List<String> providers = mLocationManager.getProviders(true);
Location bestLocation = null;
for (String provider : providers) {
#SuppressLint("MissingPermission") Location l = mLocationManager.getLastKnownLocation(provider);
if (l == null) {
continue;
}
if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {
// Found best last known location: %s", l);
bestLocation = l;
}
}
is there any way to get last known location without needing to turn GPS on?
After I disable location services on my phone and then enable them getLastKnownLocation() returns null although the provider it used is enabled.
Does anyone know how to solve this problem?
Also, if I open Google maps app and then return to my app it seems to solve the problem.
Code:
private Location getLastKnownLocation() {
LocationManager mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
List<String> providers = mLocationManager.getProviders(true);
Location bestLocation = null;
for (String provider : providers) {
boolean enabled = mLocationManager.isProviderEnabled(provider);
#SuppressLint("MissingPermission")
Location l = mLocationManager.getLastKnownLocation(provider);
if (l == null) {
Log.d("DebuggingLocation", "Skipped " + provider + " " + String.valueOf(enabled));
continue;
}
if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {
bestLocation = l;
}
}
return bestLocation;
}
Logs:
D/DebuggingLocation: Skipped passive true
D/DebuggingLocation: Skipped gps true
D/DebuggingLocation: Skipped network true
Problem solved by requesting location updates for passive, gps and network providers.
I want to get current GPS location when button is clicked. I have written this code (given below) but this gives NullPointerException for location object that is Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);. please tell what is problem with my code?
Code:
#Override
public void onClick(View v) {
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
}
String cur_loc = "latitude = " + location.getLatitude() + "\n" + location.getLongitude(); //this is line 54 in my code
Toast.makeText(ctx, cur_loc, Toast.LENGTH_LONG).show();
}
AndroidManifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
getLastKnownLocation (String provider) may well return null. see Documentation :
Returns a Location indicating the data from the last known location
fix obtained from the given provider.
This can be done without starting the provider. Note that this
location could be out-of-date, for example if the device was turned
off and moved to another location.
If the provider is currently disabled, null is returned.
try this method:
private Location getLastKnownLocation() {
mLocationManager = (LocationManager)getApplicationContext().getSystemService(LOCATION_SERVICE);
List<String> providers = mLocationManager.getProviders(true);
Location bestLocation = null;
for (String provider : providers) {
Location l = mLocationManager.getLastKnownLocation(provider);
if (l == null) {
continue;
}
if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {
// Found best last known location: %s", l);
bestLocation = l;
}
}
return bestLocation;
}
Now use it as:
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Location myLocation = getLastKnownLocation();
I have a problem with getting current location because, I have in my MainActivity the listener:
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MINIMUM_TIME_BETWEEN_UPDATE,
MINIMUM_DISTANCECHANGE_FOR_UPDATE,
new MyLocationListener()
);
And I have a second activity where I would, when i click on button, calculate distance from my location and gps coordinate that I will pass with distanceTo and return true if the distance is beetween 0 and 200.
So I have a function in SecondActivity
private boolean checkCoordinate(String gps) {
LocationManager lm = (LocationManager) getSystemService(App.getContext().LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return false;
}
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
double currentLongitude = location.getLongitude();
double currentLatitude = location.getLatitude();
Location loc1 = new Location("");
loc1.setLatitude(currentLatitude);
loc1.setLongitude(currentLongitude);
String[] sep = gps.split(",");
double latitude = Double.parseDouble(sep[0]);
double longitude = Double.parseDouble(sep[1]);
Location loc2 = new Location("");
loc2.setLatitude(latitude);
loc2.setLongitude(longitude);
float distanceInMeters = loc1.distanceTo(loc2);
if(distanceInMeters < 200){
return true;
}else{
return false;
}
}
But the problem is that someTimes and maybe when I don't change my location the function:
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
return null, and I don't understand how know my current location because I have already set requestLocationUpdates.
so I how can know my current location?
getLastKnownLocation will return null if GPS based location is disabled in system or there was no GPS fix since system startup. If you want to ensure there is a location you can use the requestSingleUpdate-method, it will not return until there is a location available.
It might also be a good idea to not use the APIs based on specific provider name if it's not important to use a specific provider (usually it is not important how you got the location). The API contains methods that take a Criteria-object instead of a provider name and you can define very precisely what accuracy level etc. you want.
I am trying to get my current coordinates with network provider and not gps provider.
I was able to figure out the solution for that but I am a bit confused with the concept in this scenario.
Working Code
Here's my code for getting my coordinates:
public void getLocation(){
locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
if(appUtils.isOnline()){
try{
Geocoder geocoder = new Geocoder(
MainActivity.this.getApplicationContext(),
Locale.getDefault());
Location locationNetwork = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
List<Address> list;
if(locationNetwork!=null){
Toast.makeText(context,"Network Available!!",Toast.LENGTH_LONG).show();
list = geocoder.getFromLocation(locationNetwork.getLatitude(),locationNetwork.getLongitude(),3);
if(list!=null&&list.size()>0){
latitude = list.get(0).getLatitude();
longitude = list.get(0).getLongitude();
Toast.makeText(context,String.valueOf(latitude) + " (....) " + String.valueOf(longitude),Toast.LENGTH_LONG).show();
int count = 0;
while (latitude==null||longitude==null){
latitude = list.get(count).getLatitude();
longitude = list.get(count).getLongitude();
count++;
Toast.makeText(context,String.valueOf(latitude) + " --- " + String.valueOf(longitude),Toast.LENGTH_LONG).show();
}
}
}else{
Toast.makeText(context,"No response!!",Toast.LENGTH_LONG).show();
}
}catch (IOException e){
e.printStackTrace();
}
}else{
Toast.makeText(context,"Server not responding",Toast.LENGTH_LONG).show();
}
}
This piece of code is working perfectly fine when the gps is enabled. If gps is disabled, it doesn't work.
Now, if we are setting the location to NETWORK_PROVIDER:
Location locationNetwork = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Why do we still require gps ?
Now if I change it to PASSIVE PROVIDER:
Location locationNetwork = locationManager
.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
It works fine with the passive provider. Why is it that ?
Can someone explain what is the major difference here and what would be the right way to get the coordinates with network provider ?
I know this question is been asked several times and I did went through it. I just want to get cleared with this concept.
Thank's in advance.. :)
It doesn't require GPS to use the network provider, I've done it many times. However, getLastKnowLocation may not return a value if either it has never had an app request updates for that provider, or if the last time that happened was too long ago. You cannot count on that function always returning non-NULL. If you want to ensure that you get a location, use requestSingleUpdate instead. This will always get you a location (assuming the provider you use is enabled), but may take some time- a result may not be immediately available.
(There is one other time that function may never return- if you use the GPS provider and it can't get a lock on enough sattelites to find a location. Such as if you're in an underground parking garage).
This is the bit of code that I use to quickly get the current location, by checking all available network options.
private double[] getGPS(){
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
List<String> providers = lm.getProviders(true);
/* Loop over the array backwards, and if you get an accurate location, then break out the loop*/
Location l = null;
for (int i=providers.size()-1; i>=0; i--) {
l = lm.getLastKnownLocation(providers.get(i));
if (l != null) break;
}
double[] gps = new double[2];
if (l != null) {
gps[0] = l.getLatitude();
gps[1] = l.getLongitude();
}
return gps;
}