With the more recent version of Android... you are supposed to check if the user has given you permission before you use their location info. I\'ve gone through the android
Before you get the last known location you need to check four things:
I recommend to use a state-machine or a bool for each thing and ask for the location only if all four is true. For example:
protected void getLastKnownLocationIfReady(){
if(isGoogleApiConnected && isPermissionGranted && isLocationEnabled && isGoogleMapReady){
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
LatLng myLat = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(myLat));
}
}
call getLastKnownLocationIfReady() function every time you change one of the boolean variables.
so your onConnected would look like for example:
@Override
public void onConnected(@Nullable Bundle bundle) {
isGoogleApiConnected = true;
getLastKnownLocationIfReady();
}
check permission like:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, FINE_LOCATION_PERMISSION_REQUEST);
} else {
isPermissionGranted = true;
getLastKnownLocationIfReady();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case FINE_LOCATION_PERMISSION_REQUEST: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
isPermissionGranted = true;
getLastKnownLocationIfReady();
}
}
}
}
you can ask for enable the location like:
public void requestLocationAccess(){
if(mLocationRequest == null) createLocationRequest();
final LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true); //this is the key ingredient
com.google.android.gms.common.api.PendingResult result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback(){
@Override
public void onResult(@NonNull LocationSettingsResult result){
final Status resultStatus = result.getStatus();
switch(resultStatus.getStatusCode()){
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied.
isLocationEnabled = true;
getLastKnownLocationIfReady();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user a dialog. You need to override OnActivityResult if you want to handle the user's interaction with the dialog.
resultStatus.startResolutionForResult(this, REQUEST_LOCATION);
break;
default:
break;
}
}
});
}
modify your onMapReady like:
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
isGoogleMapReady = true;
getLastKnownLocationIfReady();
}