1

This question seems like a duplicate of this one but trust me I've tried the solutions but couldn't figure out the reason behind my problem. I'm a newbie in Kotlin and I'm requesting location updates with the FusedLocationProvider.

Relevant Code:

private lateinit  var mLocationCallback: LocationCallback? = null
private lateinit var mFusedLocationProviderClient: FusedLocationProviderClient
private lateinit var mLocationRequest: LocationRequest

mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(mContext)
// Create a LocationRequest
mLocationRequest = LocationRequest.create().apply {
    interval = java.util.concurrent.TimeUnit.SECONDS.toMillis(1000)
    smallestDisplacement = 0f
    // Sets the fastest rate for active location updates. This interval is exact, and your
    // application will never receive updates more frequently than this value.
    fastestInterval = java.util.concurrent.TimeUnit.SECONDS.toMillis(1000)
    // Sets the maximum time when batched location updates are delivered. Updates may be
    // delivered sooner than this interval.
    maxWaitTime = java.util.concurrent.TimeUnit.MINUTES.toMillis(1000)
    priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}

// Initialize the LocationCallback.
mLocationCallback = object : LocationCallback() {
    override fun onLocationResult(locationResult: LocationResult) {
        super.onLocationResult(locationResult)
        // Normally, you want to save a new location to a database. We are simplifying
        // things a bit and just saving it as a local variable, as we only need it again
        mCurrentLocation = locationResult.lastLocation
        //Get Date Time
        // saveLatLngData(this,mCurrentLocation.latitude.toString(),mCurrentLocation.longitude.toString())
        mTimeStamp = Calendar.getInstance().time
        Log.d(TAG, "LocationCallback=> TimeStamp: " + mDateFormat!!.format(mTimeStamp) + " Latitude: " + mCurrentLocation!!.latitude + " - Longitude: " + mCurrentLocation!!.longitude + " - Altitude: " + mCurrentLocation!!.altitude)
        mNotificationText = mDateFormat!!.format(mTimeStamp) + "\nLat: ${locationResult.lastLocation.latitude} | Long: ${locationResult.lastLocation.longitude}"
        createForegroundInfo()
    }
}

// Subscribe to location changes.
if (ActivityCompat.checkSelfPermission(mContext,Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext,Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
    if(mFusedLocationProviderClient != null)
    {
        mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest,mLocationCallback,Looper.getMainLooper())
        Log.d(TAG, "startMonitoring: mFusedLocationProviderClient is registered now.")
    }
    else
    {
        Log.d(TAG, "startMonitoring: mFusedLocationProviderClient is not initialized!")
    }
    return
}

//STOPPING LOCATION UPDATES (AFTER GETTING SOME VALUES) USING THE FOLLOWING CODE
if (mFusedLocationProviderClient != null) {
    try {
        val voidTask: Task<Void> = mFusedLocationProviderClient.removeLocationUpdates(mLocationCallback)
        if (voidTask.isSuccessful)
        {
            Log.d(TAG, "stopMonitoring: removeLocationUpdates successful.")
        }
        else
        {
            Log.d(TAG, "stopMonitoring: removeLocationUpdates updates unsuccessful! " + voidTask.toString())
        }
    }
    catch (exp: SecurityException)
    {
        Log.d(TAG, "stopMonitoring: Security exception.")
    }
}

Expected Behavior:

Upon calling the mFusedLocationProviderClient.removeLocationUpdates(mLocationCallback) method, the location updates should be removed and stopMonitoring: removeLocationUpdates successful. should be printed on the logger.

Problem:

Location updates are not being removed as I see stopMonitoring: removeLocationUpdates updates unsuccessful! on the logger which means that the else condition is executed.

I tried to find out the reason and applied some solutions as well. Please guide me a little about the possible options I have.

Itban Saeed
  • 1,660
  • 5
  • 25
  • 38
  • 2
    A Task is a wrapper for some future result. If you check it immediately, it’s pretty much guaranteed not to be finished yet. You need to check it using one of its callback methods or by calling `await()` on it in a coroutine. – Tenfour04 Sep 09 '21 at 03:41
  • 1
    Yes, launch a coroutine on the `Main` dispatcher and use `Task.await` from [`kotlinx-coroutines-play-services`](https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-play-services). It will throw an exception if it's not successful. – Marko Topolnik Sep 09 '21 at 06:30
  • Thank you so much for the guidance. Since I've just started learning Kotlin, I didn't know about it. And yes, I need to work on the basics first :) – Itban Saeed Sep 09 '21 at 08:50

1 Answers1

1

A Task takes some time to complete. You expect it to be finished right away, which is very unlikely to happen. You should do the check like this:

try {
    val voidTask: Task<Void> = mFusedLocationProviderClient.removeLocationUpdates(mLocationCallback)
    voidTask.addOnCompleteListener {
        if(it.isSuccessful) {
            Log.d("Location", "stopMonitoring: removeLocationUpdates successful.")
        } else {
            Log.d("Location", "stopMonitoring: removeLocationUpdates updates unsuccessful! " + voidTask.toString())
        }
    }
} catch (exp: SecurityException){
    Log.d("Location", "stopMonitoring: Security exception.")
}
daniyelp
  • 915
  • 1
  • 11
  • 26