Dealing with FusedLocationProviderClient, LocationRequest and LocationCallback classes when you need to fetch the current user location can be cumbersome. You don’t want to add this logic to the ViewModel because you will get stub exceptions when running unit tests (and generally, it’s bad practice). Do you add it to the activity/fragment, and then pass the data to the ViewModel? What happens if you need the location in another activity/fragment? This can get messy quick.

With the help of Flow and dependency injection, we can make this task a little smoother. Kotlin Coroutines introduced Flow, which is an Coroutines implementation of the Reactive Steams API. I won’t go into the workings of Flow, it has already been covered many times (see here), but the gist of it is: Asynchronous cold stream of values.

How does this apply to location updates? Well, we can wrap the location update logic we wrote above in a Flow builder. Here’s an example:

LocationUpdatesUseCase is doing a few things here:

Now we can fetch location updates using:

Our location updates will be returned to the caller when a terminal event is called on the Flow(e.g. collect). Using Flow in this way has a few advantages: