We used this code to retrieve our current location:
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationAvailability;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResponse;
import com.google.android.gms.location.SettingsClient;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
public class StartOutletVisitActivity {
ActivityStartOutletVisitBinding uiBinding;
FusedLocationProviderClient mFusedLocationClient;
LocationRequest locationRequest;
LocationCallback locationCallback;
@SuppressLint("MissingPermission")
@Override
protected void onCreate(Bundle savedInstanceState) {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(StartOutletVisitActivity.this);
locationCallback = new LocationCallback(){
@Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
return;
}
for (Location loc : locationResult.getLocations()) {
}
}
@Override
public void onLocationAvailability(LocationAvailability locationAvailability) {
//Log.d(TAG, "locationAvailability is " + locationAvailability.isLocationAvailable());
super.onLocationAvailability(locationAvailability);
}
};
binding.btnGetLocation.setOnClickListener(v -> {
mFusedLocationClient.getLastLocation()
.addOnSuccessListener(this, new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
if (location != null) {
// Do reverse geolocation to get human-readable address
DeviceLocation devLoc = LocationUtil.getAddressFromLocation(StartOutletVisitActivity.this, location.getLatitude(),
location.getLongitude());
binding.txtLocation.setText("Your address: "+devLoc.getAddressLine1());
}
}
});
createLocationRequest();
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
SettingsClient client = LocationServices.getSettingsClient(StartOutletVisitActivity.this);
Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());
task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
if (e instanceof ResolvableApiException) {
try {
ResolvableApiException resolvable = (ResolvableApiException) e;
resolvable.startResolutionForResult(StartOutletVisitActivity.this, 500);
} catch (IntentSender.SendIntentException sendEx) {
}
}
}
});
});
}
@Override
public void onResume() {
super.onResume();
startLocationUpdates();
}
@Override
protected void onPause() {
super.onPause();
mFusedLocationClient.removeLocationUpdates(locationCallback);
}
@SuppressLint("MissingPermission")
void startLocationUpdates(){
mFusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null);
}
void createLocationRequest() {
locationRequest = new LocationRequest();
locationRequest.setInterval(5000);
locationRequest.setFastestInterval(2000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
}
A few salespersons (who are on different cities accross diferent islands in Indonesia) complain that this app doesn't detect their current location accurately, e.g they are on City A, yet their detected location is on City B (on different island).
After reading this, seems like the more accurate way is getCurrentLocation(). And yes, this still uses the old play services library (v17.x, while the latest is v21.x). I'm still curious, though. Beside the older play service library, and assuming no fake GPS apps are used, what's the cause of this error? Those salespersons tolds us that they don't travel to another cities in last few months.