Search code examples
androidgoogle-mapsonresumelocation-servicesandroid-fusedlocation

How to Resume LocationServices to request location updates in onResume Method


My app uses Google Maps Api, to display user's current location and seems to be working fine except for two issues:

1 User's location is not being updated in realtime unless app is relaunched.

2 I don't know how to resume LocationServices.FusedLocationApi in onResume method, hence once user leaves the app, GPS does not restart.

I tried following most of the suggestions found in tutorials and similar questions on this site (like this Where should I request location updates in A service?) but nothing has worked for my case so far.

Here's my code:

public class MainActivity extends AppCompatActivity
implements GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener
{

private static final int ERROR_DIALOG_REQUEST = 9001;
GoogleMap mMap;

private GoogleApiClient mLocationClient;
private LocationListener mListener;
private View view;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (servicesOK()) { // If map is available, load it.
        setContentView(R.layout.activity_map);

        if (initMap()){
            mLocationClient = new GoogleApiClient.Builder(this)
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this).build();
            mLocationClient.connect();

        } else {
            Toast.makeText(this, "Map not connected!", Toast.LENGTH_SHORT).show();
        }
    } else {
        setContentView(R.layout.activity_main);
    }
}

public boolean servicesOK (){
    // Checks if GooglePlayServices (Google Map) connection is established
    int isAvailable = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

    if (isAvailable == ConnectionResult.SUCCESS) {
        return true;
    } else if (GooglePlayServicesUtil.isUserRecoverableError(isAvailable)) {
        Dialog dialog =
                GooglePlayServicesUtil.getErrorDialog(isAvailable, this, ERROR_DIALOG_REQUEST);
        dialog.show();
    } else {
        Toast.makeText(this, "Mapping unsuccessful!", Toast.LENGTH_SHORT).show();
    }
    return false;
}

private boolean initMap() {
    if (mMap == null) {
        SupportMapFragment mapFragment =
                (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mMap = mapFragment.getMap();
    }
    return (mMap != null);
}

private void gotoLocation(double lat, double lng) {
    LatLng latLng = new LatLng(lat, lng);
}

public void showCurrentLocation(MenuItem item) {
    Location currentLocation = LocationServices.FusedLocationApi
            .getLastLocation(mLocationClient);

    if (currentLocation == null) {
        Toast.makeText(this, "Couldn't connect to map!", Toast.LENGTH_SHORT).show();
        Log.d("Hello", "Couldn't connect to map" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!********************************");

    } else {
        LatLng latLng = new LatLng(
                currentLocation.getLatitude(),
                currentLocation.getLongitude()
        );
        CameraUpdate update = CameraUpdateFactory.newLatLngZoom(
                latLng, 15
        );
        mMap.animateCamera(update);
    }
}

@Override
public void onConnected(Bundle connectionHint) {
    // Executed when connection is successful
    Toast.makeText(this, "Map ready!", Toast.LENGTH_SHORT).show();

    Location currentLocation = LocationServices.FusedLocationApi
            .getLastLocation(mLocationClient);

    LatLng latLng1 = new LatLng(
            currentLocation.getLatitude(),
            currentLocation.getLongitude()
    );

    //Adds Marker when map is connected!
    MarkerOptions options = new MarkerOptions().position(latLng1).visible(true).title("Me!")              .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_VIOLET));
    mMap.addMarker(options);

    mListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            Toast.makeText(MainActivity.this,
            "Location changed!", Toast.LENGTH_SHORT).show();
            gotoLocation(location.getLatitude(), location.getLongitude());
        }
    };

        // Requests user's current location
    LocationRequest request = LocationRequest.create();
    request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    request.setInterval(10000); // TODO: 11/12/15 Change this to 90000 (90 secs)!!!!!!!!!!!!!
    request.setFastestInterval(3000); // TODO: 11/12/15 Change this to 60000 (60 secs)!!!!!!!!!
    LocationServices.FusedLocationApi.requestLocationUpdates(
            mLocationClient, request, mListener
    );
}

@Override
protected void onPause() { // Stops location updates
    super.onPause();
    LocationServices.FusedLocationApi.removeLocationUpdates(
            mLocationClient, mListener
    );
    Log.d("Hello", "The map has been paused!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!********************************");
}

@Override
protected void onResume() { // Resumes location updates
    super.onResume();
    Log.d("Hello", "The map has been resumed!!!!!!!!!!!!!!!!!********************************");

//Moves camera to user's current location!
        LocationRequest request = LocationRequest.create();
        request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        Location currentLocation = LocationServices.FusedLocationApi
                .getLastLocation(mLocationClient);
        if (currentLocation == null) {
            Toast.makeText(this, "Couldn't connect to map!", Toast.LENGTH_SHORT).show();
        } else {
            LatLng latLng = new LatLng(
                    currentLocation.getLatitude(),
                    currentLocation.getLongitude()
            );
            CameraUpdate update = CameraUpdateFactory.newLatLngZoom(
                    latLng, 15
            );
            mMap.animateCamera(update);
        }
}

@Override
public void onConnectionSuspended(int i) {
    // Executed when connection is stopped
    Log.d("Hello", "The connection was suspended!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!********************************");
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// Executed when connection is unsuccessful
    Log.d("Hello", "The connection failed!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!********************************");
}

}


Solution

  • I finally solved the problem by using this answer.

    Rather than onResume() (which didn't work for me after weeks of trying), I used onRestart()

    @Override
    protected void onRestart(){
        super.onRestart();
        onConnected(Bundle.EMPTY);
    }
    

    And it worked perfectly!