Search code examples
androidlocationlistenerandroid-fusedlocation

Location listener have problems to works in some devices and problems to migrate to FusedLocationListener


I´ve the following code that get current location o device:

public class MapPlace extends AppCompatActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener
{
    private LocationRequest mLocationRequest;
    private GoogleApiClient mGoogleApiClient;
    private Location mLastLocation;
    // location coordinates
    double dLatitude = 0.0;
    double dLongitude = 0.0;

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

          if (mGoogleApiClient == null || !mGoogleApiClient.isConnected())
          {
               buildGoogleApiClient();
               mGoogleApiClient.connect();
          }

          MapFragment mapF = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
         if (mapF != null)
            mapF.getMapAsync(this);
        }

        protected synchronized void buildGoogleApiClient()
        {
           mGoogleApiClient = new GoogleApiClient.Builder(this)
             .addConnectionCallbacks(this)
             .addOnConnectionFailedListener(this)
             .addApi(LocationServices.API)
             .build();
        }

        @Override
        public void onConnected(Bundle bundle) {
           mLocationRequest = new LocationRequest();
           mLocationRequest.setInterval(1000);
           mLocationRequest.setFastestInterval(1000);
           mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
           LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
         }

         @Override
         public void onConnectionSuspended(int i) {}

         @Override
         public void onConnectionFailed(ConnectionResult connectionResult) {}

         @Override
         public void onLocationChanged(Location location)
         {
             mLastLocation = location;
             dLatitude = mLastLocation.getLatitude();
             dLongitude = mLastLocation.getLongitude();

         }
    }
}

This code works fine, but in some devices is not working, to get success using this code I have to restart the device or close and reopen the activity, so I want to avoid this issue.

As recommend this stack overflow aswer I tried to migrate to LocationFusedLocation to solve this issue but I face some problems adding GooglePlayServicesClient implements in java class because this library is temporally deprecated as said this link. So... what can I do? Is there other way to do that?


Solution

  • It looks like you're already using GoogleApiClient, so you don't need any help there. Your code is already updated to the non-deprecated way of doing it.

    Just a couple changes should solve your problems, and I see one more issue not mentioned.

    First, you mention that you're having trouble with the Location listener, and that you need to re-start the Activity to get it working again.

    To fix that, just move the code that connects the GoogleApiClient from onCreate() to onResume():

    @Override
    public void onResume() {
        super.onResume();
    
        if (mGoogleApiClient == null || !mGoogleApiClient.isConnected())
        {
            buildGoogleApiClient();
            mGoogleApiClient.connect();
        }
    
        MapFragment mapF = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
        //only call getMapAsync() again if mMap is null:
        if (mapF != null && mMap == null)
            mapF.getMapAsync(this);
    
    }
    

    The other issue is that you should un-register for Location updates in onPause(), so that your app doesn't continue to request location updates when the user leaves your app:

    @Override
    public void onPause() {
        super.onPause();
    
        //added to stop location updates when Activity is no longer active
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
    }
    

    Here is the full class code that should work for you, note that I also added a GoogleMap reference, and set it in the onMapReady() callback (you may already have this in your full code):

    public class MapPlace extends AppCompatActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener
    {
        private LocationRequest mLocationRequest;
        private GoogleApiClient mGoogleApiClient;
        private Location mLastLocation;
        // location coordinates
        double dLatitude = 0.0;
        double dLongitude = 0.0;
    
        GoogleMap mMap;
    
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_map_place);
    
        }
    
        @Override
        public void onResume() {
            super.onResume();
    
            if (mGoogleApiClient == null || !mGoogleApiClient.isConnected())
            {
                buildGoogleApiClient();
                mGoogleApiClient.connect();
            }
    
            MapFragment mapF = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
            //only call getMapAsync() again if mMap is null:
            if (mapF != null && mMap == null)
                mapF.getMapAsync(this);
    
        }
    
        @Override
        public void onPause() {
            super.onPause();
    
            //added to stop location updates when Activity is no longer active
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }
    
    
        @Override
        public void onMapReady(GoogleMap googleMap) {
            mMap = googleMap;
        }
    
        protected synchronized void buildGoogleApiClient()
        {
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();
        }
    
        @Override
        public void onConnected(Bundle bundle) {
            mLocationRequest = new LocationRequest();
            mLocationRequest.setInterval(1000);
            mLocationRequest.setFastestInterval(1000);
            mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }
    
        @Override
        public void onConnectionSuspended(int i) {}
    
        @Override
        public void onConnectionFailed(ConnectionResult connectionResult) {}
    
        @Override
        public void onLocationChanged(Location location)
        {
            mLastLocation = location;
            dLatitude = mLastLocation.getLatitude();
            dLongitude = mLastLocation.getLongitude();
    
        }
    
    }