Search code examples
javaandroidgoogle-mapsandroid-studiogeolocation

Android studio does not check mFusedLocationProviderClient.getLastLocation().addOnSuccessListener and returns current location null


I am trying to get my updated location from my app. however my app does not check this block of code

public void onSuccess(Location location) {} inside mFusedLocationProviderClient.getLastLocation() .addOnSuccessListener(this, new OnSuccessListener(){} and returns me null location. Even my device location is turned on and the map shows my location. My code for accessing updated location is below:

  protected void onCreate(Bundle savedInstanceState) {
                mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
        }

          public void onMapReady(GoogleMap googleMap) {
                mMap = googleMap;

                Toast.makeText(this, "Map is ready", Toast.LENGTH_SHORT).show();
                if (mLocationPermissionGranted) {
                    getDeviceLocation();

                    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                            != PackageManager.PERMISSION_GRANTED &&
                            ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
                                    != PackageManager.PERMISSION_GRANTED) {
                        return;
                    }
                    mMap.setMyLocationEnabled(true);
                }
            }

        private void getDeviceLocation(){
                    try {
                        if(mLocationPermissionGranted) //true in my case
    {


                            mFusedLocationProviderClient.getLastLocation()
                                    .addOnSuccessListener(this, new OnSuccessListener<Location>() {

                                        @Override
                                        public void onSuccess(Location location) {
                                            // Got last known location. In some rare situations this can be null.
                                            if (location != null) {

                                                moveCamera(new LatLng(location.getLatitude(),location.getLongitude()),17);
                                               // mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(),location.getLongitude()),12),2000,null);

                                            }
                                            else{
                                                Toast.makeText(MapsActivity.this, "Unable to get current location", Toast.LENGTH_SHORT).show();
                                            }
                                        }

                                    });

                        }
                    }catch (SecurityException ex){

                    }
                }

I am getting the following exceptions in stacktrace

09-11 15:12:14.525 5864-5864/? E/Zygote: v2
09-11 15:12:14.530 5864-5864/? E/Zygote: accessInfo : 0
09-11 15:12:27.333 5864-5864/com.example.muzammil.maptestingproject E/BoostFramework: BoostFramework() : Exception_1 = java.lang.ClassNotFoundException: Didn't find class "com.qualcomm.qti.Performance" on path: DexPathList[[],nativeLibraryDirectories=[/system/lib, /vendor/lib]]
09-11 15:12:39.327 5864-5864/com.example.muzammil.maptestingproject E/art: The String#value field is not present on Android versions >= 6.0

Everything else is correct including manifest permissions and gradle dependencies. May be any body help me in solving my problem. Thanks in advance.


Solution

  • Fused Location Provider will give the location if at least one client is connected to it. If the client connects, it will immediately try to get a location. If your activity is the first client to connect and you call getLastLocation() that might not be enough time for the first location to come in.

    getLastLocation() is suitable where a location is needed immediately or none at all can be used. If you really want to wait for a location it's best to use requestLocationUpdates() and wait for the callback rather than busy waiting in a thread.

    Here is the method to get location using requestLocationUpdates()

        LocationCallback locationCallback;
        LocationRequest locationRequest;
        FusedLocationProviderClient fusedLocationClient;
    
        void getLocation() {
            locationRequest = LocationRequest.create()
                    .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                    .setInterval(30 * 1000)
                    .setFastestInterval(5 * 1000);
    
            locationCallback = new LocationCallback() {
                @Override
                public void onLocationResult(LocationResult locationResult) {
                    super.onLocationResult(locationResult);
                    //Location received 
                }
            };
    
            fusedLocationClient = LocationServices.getFusedLocationProviderClient(getApplicationContext());
            if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null);
        }
    

    And don't forget to remove location updated in onStop or onDestroy

    fusedLocationClient?.removeLocationUpdates(locationCallback)