-1

I am using GoogleApiClient to get user location. I created a singleton class to get user location. Here is that class:

public class LocationUtils {

    private static LocationUtils locationUtils;
    private GoogleApiClient googleApiClient;

    public static LocationUtils getInstance() {

        if(locationUtils == null)
            locationUtils = new LocationUtils();
        return locationUtils;
    }

    private LocationUtils() {}

    public Location getLocation(Context context){

        final Location[] location = {null};

        googleApiClient = new GoogleApiClient.Builder(App.getContext())
                .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
                    @Override
                    public void onConnected(Bundle bundle) {
                        if(ContextCompat.checkSelfPermission(App.getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
                            location[0] =  LocationServices.FusedLocationApi.getLastLocation(googleApiClient );

                        googleApiClient.disconnect();
                    }

                    @Override
                    public void onConnectionSuspended(int i) {

                    }
                })
                .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                    @Override
                    public void onConnectionFailed(ConnectionResult connectionResult) {

                    }
                })
                .addApi( LocationServices.API )
                .build();

        googleApiClient.connect();

        return location[0];

    }



}

I want to get user location with LocationUtils.getInstance().getLocation(context) . When i call getLocation() method, it should connect to GoogleApiClient, return user location and disconnect to GoogleApiClient for every call. But when i call that method, it returns null. The main thread does not wait for onConnected() method and returns location object as null. How can it waits for onConnect() method ? OR how can i return Location object in onConnected() ?

SOLVED according to Tim Castelijns's answer

First i created an interface:

public interface LocationCallbackInterface {
    void onComplete(Location location);
}

then used it in getLocationMethod() :

public void getLocation(Context context, final LocationCallbackInterface callback){

final Location[] location = {null};

googleApiClient = new GoogleApiClient.Builder(App.getContext())
        .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
            @Override
            public void onConnected(Bundle bundle) {
                if(ContextCompat.checkSelfPermission(App.getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    location[0] = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
                    //Toast.makeText(App.getContext(), "location came :" + location[0].toString(), Toast.LENGTH_LONG).show();
                    callback.onComplete(location[0]);
                }

                googleApiClient.disconnect();
            }

            @Override
            public void onConnectionSuspended(int i) {

            }
        })
        .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
            @Override
            public void onConnectionFailed(ConnectionResult connectionResult) {

            }
        })
        .addApi( LocationServices.API )
        .build();

googleApiClient.connect();

}

then called that method in an activity:

 LocationUtils.getInstance().getLocation(getActivity(), new LocationCallbackInterface() {

            @Override
            public void onComplete(Location location) {
                if (location != null) {
                    Toast.makeText(getActivity(), "location :" + location.toString(), Toast.LENGTH_SHORT).show();
                    initCamera(location);
                } else
                    Toast.makeText(getActivity(), "location is null", Toast.LENGTH_SHORT).show();
            }
        });
cimenmus
  • 1,386
  • 4
  • 18
  • 31

1 Answers1

2

Since the location is acquired asynchronously, you should use a callback to return the location, otherwise your return value will always be null because the googleApiClient is not done yet.

Define an interface like this

public interface LocationCallback {
    void onComplete(Location location);
}

Change

public Location getLocation(Context context)

to

public Location getLocation(Context context, LocationCallback callback)

and call it like this

LocationUtils.getLocation(context, new LocationCallback() {
    @Override
    onComplete(Location location) {
        // when this is called, you will have a location.
    }
});
Tim
  • 41,901
  • 18
  • 127
  • 145