2

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.

Dejan
  • 3,046
  • 3
  • 28
  • 43

2 Answers2

4

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)
Tausif
  • 778
  • 1
  • 5
  • 14
  • Even with this solution it freezes. Only way I was able to make this problem work was with 3rd party library (ie Locus), but it uses location all the time and I am trying to avoid this. – Dejan May 21 '21 at 06:30
  • It seems that your solution in combination with removing listeners in onPause and onDestroy and using main thread for requesting location did fix issue. I will mark your answer as solution. – Dejan May 21 '21 at 07:10
  • I forgot to mention remove location updates in onDestory. I have added this. Anyway thanks ! – Tausif May 21 '21 at 07:40
0

Scenario 1:After gets message that location is disabled and exits.kill the app from recent app tray now Enable location . Then open App from Home page as new Activity now it should update location. if it's working,nothing wrong in App.App is working properly.

Scenario 2:If you have fusedLocation.getLastLocation() in onCreate() method,move that code to onResume() method.because when you open the App from recent apps tray ,onStart() method will invoked first then onResume() not onCreate().Now enable location ,open the app from recent app tray,check location is updated or not.

   @Override
protected void onResume() {
    super.onResume();
    if (isLocationServiceEnabled) {
        startLocationUpdates();
    }
}
androidLearner
  • 1,654
  • 1
  • 7
  • 13
  • Location fetching is initiated short after onResume, and I am already doing scenario 1. Still when I turn on location even after check succeeds location fetching freezes. – Dejan May 21 '21 at 06:23