Android Google Api Get Task Result Without Callback

May 13, 2019
Kotlin Corutines Extension for Google Play Services

Tasks.await

Google Api usually return a Task object, when we use addOnCompleteListener or addOnSuccessListener to retrieve the desired result.

val fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)

fusedLocationClient.lastLocation
        .addOnSuccessListener { location : Location? ->
            // Got last known location. In some rare situations this can be null.
        }

If we are already in a background thread, we might want to retrieve the result without a callback. Use Tasks.await to get the result synchronously without callback.

val result = Tasks.await(fusedLocationClient.lastLocation)

You might want to handle the following exception

  • ExecutionException - The Task failed, this is the same exception you’d get in a non-blocking failure handler.
  • InterruptedException - An interrupt occurred while waiting for the task to complete.
  • TimeoutException - if specified a timeout: Tasks.await(task, 500, TimeUnit.MILLISECONDS)

NOTE: When you use Tasks.await, the real exception is hidden in ExecutionException.cause (e.g. java.util.concurrent.ExecutionException: com.google.firebase.FirebaseNetworkException: A network error ...)

Kotlin Coroutines: Task to Deferred

If you are using kotlin coroutines, you can utiliaze kotlinx-coroutines-play-services.

Include dependencies

dependencies {
    // https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-play-services
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.2.1'
}

Usage

val result = fusedLocationClient.lastLocation.await()

NOTE: Unlike Tasks.await, you can handle the real exception without the need to look into ExecutionException.cause.

NOTE: There is also convinient function to change such as Deferred.asTask and Task.asDeferred.

References

This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.