androidlocationandroid-fusedlocation

FusedLocationProviderClient not working correctly when Location turned on/off


I am using location to implement geofencing functionality (limiting app usage to one country) In first activity in application I am using FusedLocationProviderClient to get location like this:

Init part

fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);

and location part

fusedLocationClient.getLastLocation().addOnSuccessListener(this, location -> {
                if (location != null) {
                    //geofencing logic
                }
            });

This code works fine if location is enabled all the time on device. If user disables location in quick menu on top of phone or in settings and tries to enter app, it gets message that location is disabled and exits. After that if user tries to turn on location and enter app FusedLocationClient gets stuck and doesn't return location at all. After that it will only work if I reinstall application. Has anyone had this problem and tried to fix it other than using background location all the time with periodic updates?

PS Same thing happens if I try to use LocationService directly to access last known location.


Solution

  • Instead of getting the last known location, you can get location updates in specific intervals. Here is the code.

    Declare these fused location provider class and location callback class

    private var mFusedLocationProviderClient: FusedLocationProviderClient? = null
    private var mLocationRequest: LocationRequest? = null
    private var mLocationCallback: LocationCallback? = null  
    private const val LOCATION_REQUEST_INTERVAL: Long = 5000
    

    `

    Here is the necessary method for the location request

    private fun createLocationRequest() {
        mLocationRequest = LocationRequest.create()
        mLocationRequest!!.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
        mLocationRequest!!.setInterval(LOCATION_REQUEST_INTERVAL).fastestInterval =
        LOCATION_REQUEST_INTERVAL
        requestLocationUpdate()
    }
    
    private fun requestLocationUpdate() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED ) {
    
            Log.e("permission", "denied");
    
    
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return
        }
    
        mFusedLocationProviderClient!!.requestLocationUpdates(
            mLocationRequest,
            mLocationCallback,
            Looper.myLooper()
        )
    }
    

    Then call these "createLocationRequest" method and location callback classs in onCreate().

        mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(requireContext())
    
     createLocationRequest()
     mLocationCallback = object : LocationCallback() {
    
            override fun onLocationResult(locationResult: LocationResult) {
                super.onLocationResult(locationResult)
                 val lat  = locationResult.lastLocation.latitude
                 val lng = locationResult.lastLocation.longitude
                                    
         
            }
        }
    

    And remove location update listener in onPause() or onDestory() as per your requirement.

        mFusedLocationProviderClient!!.removeLocationUpdates(mLocationCallback)