Like Andy said, the OnSuccessListener is asynchronous, so it will runs on a different Thread while your return value is on the main Thread.
You have different workaround :
Workaround 1) Declare in your scope a global result variable, that you can reuse anywhere in your class after you set it with your OnSuccessListener :
private Double result;
Workaround 2) Pass it to a method directly in its parameter :
public void codeQR(final Context context, final Activity activity){
client2 = LocationServices.getFusedLocationProviderClient(context);
client2.getLastLocation().addOnSuccessListener(activity, new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
latitude = location.getLatitude();
longitude = location.getLongitude();
result = (latitude +longitude);
anotherMethod(result);
}
});
}
Workaround 3) Create a callback Interface, put this callback in your method parameter, and then call your method wherever you need to access the "result" value :
//A) Create a callback Interface
public interface MyCallback {
void onCallback(Double result);
}
//B) Put this callback in your method parameter
public void codeQR(final Context context, final Activity activity, MyCallback myCallback){
client2 = LocationServices.getFusedLocationProviderClient(context);
client2.getLastLocation().addOnSuccessListener(activity, new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
latitude = location.getLatitude();
longitude = location.getLongitude();
result = (latitude +longitude);
myCallback.onCallback(result);
}
});
}
//C) Call your method wherever you need to access the "result" value
//For example, if you want to get the result value in the nextStep() method
private void nextStep(){
codeQR(this, this, new MyCallback() {
@Override
public void onCallback(Double result) {
Log.i("TestOfResult", "onCallback: " + result);
}
});
}
You can find more explanations about this interface on this link.
I hope this will help you, let us know if this worked or if you have questions !