Aditi K
Aditi K

Reputation: 1554

How to get last known location for Location manager in Android?

I am using simple location manager object to get lastKnownLocation() of device but getting null object in return can any one tell me why ?

Code :

public Location getLocation() {
    LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);        
    if (locationManager != null) {          
        Location lastKnownLocationGPS = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        if (lastKnownLocationGPS != null) {             
            return lastKnownLocationGPS;
        } else {                
            Location loc =  locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
            System.out.println("1::"+loc);----getting null over here
            System.out.println("2::"+loc.getLatitude());
            return loc;
        }
    } else {            
        return null;
    }
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.location);
    getLocation();-----calling service

 }

permissions given :

 <uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

so is anything missing to set up? I have checked my location service is on in device please give some links for working examples

Upvotes: 18

Views: 54766

Answers (9)

Homayoon Ahmadi
Homayoon Ahmadi

Reputation: 2833

Here is a better solution:

@Nullable
public static Location getLastKnownLocation(Context context, LocationManager locationManager) {
    if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
            ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return null;
    }

    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);

    String provider = locationManager.getBestProvider(criteria, true);
    if (provider == null) return null;

    return locationManager.getLastKnownLocation(provider);
}

This line: criteria.setAccuracy(Criteria.ACCURACY_FINE); does the trick.

Upvotes: 0

sahil333
sahil333

Reputation: 11

Working it out in Kotlin: Sorry for the horrible indentation

  1. Add these two dependencies in your gradle app file

     implementation 'com.google.android.gms:play-services-maps:17.0.0'
     implementation 'com.google.android.gms:play-services-location:17.0.0'
    
  2. Add these permissions in the manifest file outside applicationtag

     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    
  3. Declare variable outside onCreate

     private lateinit var fusedLocationClient: FusedLocationProviderClient
    
  4. Now inside onCreate :

     fusedLocationClient= LocationServices.getFusedLocationProviderClient(this)
    
     getCurrentLocation()
    
  5. No define fetchLastLocation method Note:Here getCurrentLocation means the last location.

     private fun getCurrentLocation(){
     if(checkPermissions())
     {
         if(isLocationEnabled()){
             //final latitude and longitude
             if (ActivityCompat.checkSelfPermission(
                     this,
                     Manifest.permission.ACCESS_FINE_LOCATION
                 ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
                     this,
                     Manifest.permission.ACCESS_COARSE_LOCATION
                 ) != PackageManager.PERMISSION_GRANTED
             ) {
                 requestPermission()
                 return
             }
             // fusedLocationClient.getCurrentLocation()
             fusedLocationClient.lastLocation.addOnCompleteListener(this){ task->
                 val location:Location?=task.result
                 if(location==null)
                 {
                     Toast.makeText(this,"NULL Received",Toast.LENGTH_SHORT).show()
                 }
                 else{
                     Toast.makeText(this,"Location SUCCESS",Toast.LENGTH_SHORT).show()
                     val geocoder = Geocoder(this, Locale.getDefault())
                     val addresses: MutableList<android.location.Address>? = geocoder.getFromLocation(location.latitude, location.longitude, 1)
                     cityName = addresses!![0].locality
                     startActivity(intent)
                 }
             }
         }
         else
         {
             Toast.makeText(this,"Turn on location",Toast.LENGTH_SHORT).show()
             val intent= Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
             startActivity(intent)
         }
     }
     else
     {
         //request permission here
         requestPermission()
     }
    

    }

  6. Now define other methods for permission request

     private fun requestPermission() {
     ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.ACCESS_COARSE_LOCATION,android.Manifest.permission.ACCESS_FINE_LOCATION),
         PERMISSION_REQUEST_ACCESS_LOCATION)
     }
    
     companion object{
     private const val PERMISSION_REQUEST_ACCESS_LOCATION=100
     }
    
     private fun checkPermissions():Boolean {
     if (ActivityCompat.checkSelfPermission(
             this,
             android.Manifest.permission.ACCESS_FINE_LOCATION
         ) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
             this,
             android.Manifest.permission.ACCESS_COARSE_LOCATION
         ) == PackageManager.PERMISSION_GRANTED
     ) {
         return true
     }
     return false
     }
    
     override fun onRequestPermissionsResult(
     requestCode: Int,
     permissions: Array<out String>,
     grantResults: IntArray
     ) {
     super.onRequestPermissionsResult(requestCode, permissions, grantResults)
     if(requestCode== PERMISSION_REQUEST_ACCESS_LOCATION)
     {
         if(grantResults.isNotEmpty() && grantResults[0]==PackageManager.PERMISSION_GRANTED){
             Toast.makeText(applicationContext,"Granted",Toast.LENGTH_SHORT).show()
             getCurrentLocation()
         }
         else{
             Toast.makeText(applicationContext,"DENIED",Toast.LENGTH_SHORT).show()
         }
     }
     }
    
     private fun isLocationEnabled():Boolean{
     val locationManager:LocationManager=getSystemService(Context.LOCATION_SERVICE) as LocationManager
     return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)||locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
     }
    

Upvotes: 1

larsaars
larsaars

Reputation: 2350

Best method I have found:

private Location getLastKnownLocation() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return null;
    }

    List<String> providers = locationManager.getProviders(true);
    Location bestLocation = null;
    for (String provider : providers) {
        Location l = locationManager.getLastKnownLocation(provider);
        if (l == null) {
            continue;
        }
        if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {
            // Found best last known location:
            bestLocation = l;
        }
    }

    return bestLocation;
}

The locationManager variable you can get from the system service LOCATION.

Upvotes: 3

Aman Kumar Gupta
Aman Kumar Gupta

Reputation: 3021

To fetch the last location, you can refer to the above provided answers where you can use Location Manager or FusedLocationClient

But You can also make use of LocationServices which is faster than other approaches.

So let me provide a brief working :

1) Add these two dependencies in your gradle app file

implementation 'com.google.android.gms:play-services-maps:17.0.0'
implementation 'com.google.android.gms:play-services-location:17.0.0'

2) Add these permissions in the manifest file outside applicationtag

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

3) Declare variable outside onCreate

private FusedLocationProviderClient fusedLocationClient;

4) Now inside onCreate :

fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
fetchLastLocation();

5) No define fetchLastLocation method

private void fetchLastLocation() {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                //    Activity#requestPermissions
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for Activity#requestPermissions for more details.
//                    Toast.makeText(MainActivity.this, "Permission not granted, Kindly allow permission", Toast.LENGTH_LONG).show();
                showPermissionAlert();
                return;
            }
        }
        fusedLocationClient.getLastLocation()
                .addOnSuccessListener(this, new OnSuccessListener<Location>() {
                    @Override
                    public void onSuccess(Location location) {
                        // Got last known location. In some rare situations this can be null.
                        if (location != null) {
                            // Logic to handle location object
                            Log.e("LAST LOCATION: ", location.toString());
                        }
                    }
                });

    }

6) Now define other two method for permission request

@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case 123: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
                    // permission was denied, show alert to explain permission
                    showPermissionAlert();
                }else{
                    //permission is granted now start a background service
                    if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                            && ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                        fetchLastLocation();
                    }
                }
            }
        }
    }

    private void showPermissionAlert(){
        if (ActivityCompat.checkSelfPermission(MainHomeActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(MainHomeActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainHomeActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 123);
        }
    }

Note : Replace context with your class context

You will get your location in Logcat.

Hope this will hope you or somebody else

Upvotes: 4

rivaldy
rivaldy

Reputation: 137

before get last location, maybe you want get current location, check if null or have. if not set last loccation if you want use FusedLocationProviderClient and before use it adding this:

implementation 'com.google.android.gms:play-services-location:16.0.0'

on your build.gradle(Module: app), and call method zoomMyCuurentLocation() whean activity create.

private void zoomMyCuurentLocation() {
    LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
    Criteria criteria = new Criteria();
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);
    }
    Location location = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, false));
    if (location != null) {
        double lat = location.getLatitude();
        double longi = location.getLongitude();
        LatLng latLng = new LatLng(lat,longi);
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14.f));
        Log.d(TAG, "zoomMyCuurentLocation: location not null");
    } else {
        setMyLastLocation();
    }
}

private void setMyLastLocation() {
    Log.d(TAG, "setMyLastLocation: excecute, and get last location");
    FusedLocationProviderClient fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    fusedLocationClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
        @Override
        public void onSuccess(Location location) {
            if (location != null){
                double lat = location.getLatitude();
                double longi = location.getLongitude();
                LatLng latLng = new LatLng(lat,longi);
                Log.d(TAG, "MyLastLocation coordinat :"+latLng);
                mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14.f));
            }
        }
    });
}

Upvotes: 6

Gautam Pansheriya
Gautam Pansheriya

Reputation: 31

            // Get the location from the given provider
            Location location = locationManager
                    .getLastKnownLocation(provider);

            locationManager.requestLocationUpdates(provider, 1000, 1, this);

Upvotes: 2

Mayur
Mayur

Reputation: 114

Below is the way I am trying to get last location.

private void setUpMap(){
    //Location location = mMap.getMyLocation();
    mMap.setMyLocationEnabled(true);
    //mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
    mMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
        @Override
        public void onMyLocationChange(Location location) {
             mMap.addMarker(new MarkerOptions().position(new LatLng(location.getLatitude(), location.getLongitude())).title("My Location"));
             mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(),location.getLongitude()),10));
             mMap.setOnMyLocationChangeListener(null);
        }
    });
}

Upvotes: 1

Aditi K
Aditi K

Reputation: 1554

Silly thing as answer to this ...I restarted my device ...and it worked...Please ensure that your service for location are enabled and working properly

Upvotes: 4

Archit Jain
Archit Jain

Reputation: 507

The thing i use to get Location with Name of the place is

GPSTracker gpsTracker = new GPSTracker(CameraActivity.this);
String stringLatitude = "", stringLongitude = "", nameOfLocation="";
    if (gpsTracker.canGetLocation()) {
        stringLatitude = String.valueOf(gpsTracker.latitude);
        stringLongitude = String.valueOf(gpsTracker.longitude);
        nameOfLocation = ConvertPointToLocation(stringLatitude,stringLongitude);
    }

public String ConvertPointToLocation(String Latitude, String Longitude) {
    String address = "";
    Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
    try {
        List<Address> addresses = geoCoder.getFromLocation(
                Float.parseFloat(Latitude), Float.parseFloat(Longitude), 1);

        if (addresses.size() > 0) {
            for (int index = 0; index < addresses.get(0)
                    .getMaxAddressLineIndex(); index++)
                address += addresses.get(0).getAddressLine(index) + " ";
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    return address;
}


GPSTracker.java

package in.appology.lss;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;

/**
 * Create this Class from tutorial :
 * http://www.androidhive.info/2012/07/android-gps-location-manager-tutorial
 * 
 * For Geocoder read this :
 * http://stackoverflow.com/questions/472313/android-reverse
 * -geocoding-getfromlocation
 * 
 */

public class GPSTracker extends Service implements LocationListener {
private final Context mContext;

// flag for GPS Status
boolean isGPSEnabled = false;

// flag for network status
boolean isNetworkEnabled = false;

boolean canGetLocation = false;

Location location;
double latitude;
double longitude;

// The minimum distance to change updates in metters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10
                                                                // metters

// The minimum time beetwen updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute

// Declaring a Location Manager
protected LocationManager locationManager;

public GPSTracker(Context context) {
    this.mContext = context;
    getLocation();
}

public Location getLocation() {
    try {
        locationManager = (LocationManager) mContext
                .getSystemService(LOCATION_SERVICE);

        // getting GPS status
        isGPSEnabled = locationManager
                .isProviderEnabled(LocationManager.GPS_PROVIDER);

        // getting network status
        isNetworkEnabled = locationManager
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        if (!isGPSEnabled && !isNetworkEnabled) {
            // no network provider is enabled
        } else {
            this.canGetLocation = true;

            // First get location from Network Provider
            if (isNetworkEnabled) {
                locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER,
                        MIN_TIME_BW_UPDATES,
                        MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

                Log.d("Network", "Network");

                if (locationManager != null) {
                    location = locationManager
                            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    updateGPSCoordinates();
                }
            }

            // if GPS Enabled get lat/long using GPS Services
            if (isGPSEnabled) {
                if (location == null) {
                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

                    Log.d("GPS Enabled", "GPS Enabled");

                    if (locationManager != null) {
                        location = locationManager
                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        updateGPSCoordinates();
                    }
                }
            }
        }
    } catch (Exception e) {
        // e.printStackTrace();
        Log.e("Error : Location",
                "Impossible to connect to LocationManager", e);
    }

    return location;
}

public void updateGPSCoordinates() {
    if (location != null) {
        latitude = location.getLatitude();
        longitude = location.getLongitude();
    }
}

/**
 * Stop using GPS listener Calling this function will stop using GPS in your
 * app
 */

public void stopUsingGPS() {
    if (locationManager != null) {
        locationManager.removeUpdates(GPSTracker.this);
    }
}

/**
 * Function to get latitude
 */
public double getLatitude() {
    if (location != null) {
        latitude = location.getLatitude();
    }

    return latitude;
}

/**
 * Function to get longitude
 */
public double getLongitude() {
    if (location != null) {
        longitude = location.getLongitude();
    }

    return longitude;
}

/**
 * Function to check GPS/wifi enabled
 */
public boolean canGetLocation() {
    return this.canGetLocation;
}

/**
 * Function to show settings alert dialog
 */
public void showSettingsAlert() {
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

    // Setting Dialog Title
    alertDialog.setTitle("GPS");

    // Setting Dialog Message
    alertDialog
            .setMessage("Please enable location in settings for accurate results!");

    // On Pressing Setting button
    alertDialog.setPositiveButton("Settings",
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Intent intent = new Intent(
                            Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                    mContext.startActivity(intent);
                }
            });

    // On pressing cancel button
    alertDialog.setNegativeButton("Cancel",
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });

    alertDialog.show();
}

/**
 * Get list of address by latitude and longitude
 * 
 * @return null or List<Address>
 */
public List<Address> getGeocoderAddress(Context context) {
    if (location != null) {
        Geocoder geocoder = new Geocoder(context, Locale.ENGLISH);
        try {
            List<Address> addresses = geocoder.getFromLocation(latitude,
                    longitude, 1);
            return addresses;
        } catch (IOException e) {
            // e.printStackTrace();
            Log.e("Error : Geocoder", "Impossible to connect to Geocoder",
                    e);
        }
    }

    return null;
}

/**
 * Try to get AddressLine
 * 
 * @return null or addressLine
 */
public String getAddressLine(Context context) {
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0) {
        Address address = addresses.get(0);
        String addressLine = address.getAddressLine(0);

        return addressLine;
    } else {
        return null;
    }
}

/**
 * Try to get Locality
 * 
 * @return null or locality
 */
public String getLocality(Context context) {
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0) {
        Address address = addresses.get(0);
        String locality = address.getLocality();

        return locality;
    } else {
        return null;
    }
}

/**
 * Try to get Postal Code
 * 
 * @return null or postalCode
 */
public String getPostalCode(Context context) {
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0) {
        Address address = addresses.get(0);
        String postalCode = address.getPostalCode();

        return postalCode;
    } else {
        return null;
    }
}

/**
 * Try to get CountryName
 * 
 * @return null or postalCode
 */
public String getCountryName(Context context) {
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0) {
        Address address = addresses.get(0);
        String countryName = address.getCountryName();

        return countryName;
    } else {
        return null;
    }
}

@Override
public void onLocationChanged(Location location) {
}

@Override
public void onProviderDisabled(String provider) {
}

@Override
public void onProviderEnabled(String provider) {
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}
}

Upvotes: 3

Related Questions