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));
}
}
});
}
Answer from rivaldy on Stack Overflowbefore 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));
}
}
});
}
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
Videos
Fused Location Provider Client is the best way to do it. Try with this code for the getLastLocation() method:
FusedLocationProviderClient mLocationProvider = LocationServices.getFusedLocationProviderClient(activity);
mLocationProvider.getLastLocation().addOnSuccessListener(activity, location -> {
if (location != null) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
}
}).addOnFailureListener(e -> {
//some log here
});
Can you try below solution and let me know, because it's working fine for me.
Change your provider as
String provider = LocationManager.NETWORK_PROVIDER;
You have mentioned this provider in getLastLocation() method.
Also add below permissions to your manifest files
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
You can try the following code snippet:
public class LocationProvider
{
private static final String TAG = "DEBUG";
private static final String[] provider = new String[]
{
LocationManager.GPS_PROVIDER,
LocationManager.NETWORK_PROVIDER,
LocationManager.PASSIVE_PROVIDER
};
public Location getLocationByProvider(Context context)
{
Location location = null;
// LocationManager locationManager = (LocationManager) context.getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
try
{
for (int i = 0; i < provider.length; i++)
{
if (locationManager.isProviderEnabled(provider[i]))
{
// locationManager.requestLocationUpdates(provider[i], 0, 0, locationListenerGps);
location = locationManager.getLastKnownLocation(provider[i]);
if (location != null)
{
break;
}
}
}
}
catch (IllegalArgumentException e)
{
Log.d(TAG, "Cannot acces Provider " + provider);
}
return location;
}
}
you can also get best provider and then get location from best provider.
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
bestProvider = mLocationManager.getBestProvider(criteria, true);
Hope this will helps you. :-)
The documentation itself says that getLastLocation may return null in cases when location is not available. When it is null, call requestLocationUpdate method in the OnConnected() method, like this :
@Override
public void onConnected(Bundle connectionHint) {
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mCurrentLocation == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}
Before calling the requestLocationUpdates, create the mLocationRequest object:
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
When the location will be available, OnLocationChanged will get fired automatically. The rate of getting this callback is defined by the interval you put in setInterval() while creating the request object.
@Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
}
Your location object will get updated then.
Follow this link: http://developer.android.com/training/location/receive-location-updates.html
I have used pre-defined Map Activity.You can get your last known and current location thorough it.
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private GoogleMap mMap;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker;
LocationRequest mLocationRequest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkLocationPermission();
}
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
//Initialize Google Play Services
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
@Override
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onLocationChanged(Location location) {
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
//Place current location marker
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mMap.addMarker(markerOptions);
//move map camera
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
//stop location updates
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public boolean checkLocationPermission(){
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Asking user if explanation is needed
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted. Do the
// contacts-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
if (mGoogleApiClient == null) {
buildGoogleApiClient();
}
mMap.setMyLocationEnabled(true);
}
} else {
// Permission denied, Disable the functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
}
return;
}
// other 'case' lines to check for other permissions this app might request.
// You can add here other case statements according to your requirement.
}
}
}
Allow network state permission and location permissions in Android Manifest
If your requirement is only to get the current location of the user, then you need not use MapActivity, you can rely on LocationServices and ask for getLastLocation .Here is the below sample code which serves your purpose.
// Create an instance of GoogleAPIClient.
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
Since you would have implemented the listeners of GoogleApiClient, hence you can ask for location as shown in below code:
@Override
public void onConnected(Bundle bundle) {
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
startLocationUpdates();
}
protected void startLocationUpdates() {
Log.d(TAG, "startLocationUpdates--> Start Location Updates");
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
public void stopLocationUpdates() {
Log.d(TAG,"stopLocationUpdates--> Stop location updates");
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
stopService();
}
@Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " +
connectionResult.getErrorCode());
}
@Override
public void onLocationChanged(Location location) {
Log.d(TAG, "onLocationChanged--> Location is " + location.toString());
mCurrentLocation = location;
}
Also, if you want to keep track of location after a regular interval, you create an object of locationRequest like this from OnCreate(where you created object of GoogleApiClient):
protected void createLocationRequest() {
Log.d(TAG,"createLocationRequest--> Create Location Request");
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10 * 1000); //UPDATE_INTERVAL_IN_MS
mLocationRequest.setFastestInterval(5 * 1000); //FASTEST_UPDATE_INTERVAL_IN_MS
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
}
Here is the startLocation update method:
protected void startLocationUpdates() {
Log.d(TAG, "startLocationUpdates--> Start Location Updates");
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
I hope this answers your question, kindly mark this as answer if it solves your problem.
You are using LocationManager.NETWORK_PROVIDER to get locations. Your code implies you want GPS ("Gps Disabled")? In this case you should use LocationManager.GPS_PROVIDER.
LocationManager.NETWORK_PROVIDER is not very accurate (few hundred meters if locking to cell towers), so you might not detect the location change if you move less then 100m.
On the other hand, GPS is usually unavailable indoors or between tall buildings. Also GPS uses power so should not be used all the time (when app is in the background).
Read about Obtaining User Location, for the best approach to getting location with regards to accuracy vs service availability.
Hope this can help:
http://www.tutorials-android.com/learn/How_to_get_the_last_known_GPS_location.rhtml