/FancyLocationProvider

Wrapper of FusedLocationProviderClient for Android to support modern usage like LiveData and Flow

Primary LanguageKotlinMIT LicenseMIT

FancyLocationProvider

CircleCI jitpack

Wrapper of FusedLocationProviderClient for Android to support modern usage like LiveData or Flow.

Install

Add Jitpack repository to your root build.grable:

allprojects {
  repositories {
    ...
    maven { url 'https://jitpack.io' }
  }
}

Then add dependency in your module build.gradle:

dependencies {
  implementation 'com.github.jintin:FancyLocationProvider:2.0.0'
}

Usage

LiveData

Here is an example of how you can create a LocationLiveData in ViewModel layer, just provide Context and the LocationRequest with your own config.

class MainViewModel(application: Application) : AndroidViewModel(application) {
    private val locationRequest =
        LocationRequest.create()
            .setInterval(3000)
            .setFastestInterval(3000)
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)

    val locationLiveData = LocationLiveData(application, locationRequest)
}

And here is how you observe the update on View layer.

// check for the location permission first
locationLiveData.observe(this) {
    when (it) {
        is LocationData.Success -> // get location by "it.location"
        is LocationData.Fail -> // Fail to get location
    }
}

Flow

val locationFlow = LocationFlow(application, locationRequest)

// check for the location permission first
// should inside coroutine
locationFlow.get().collect {
    when (it) {
        is LocationData.Success -> // get location by "it.location"
        is LocationData.Fail -> // Fail to get location
    }
}

You can go to ./app module for more information.

Custom Location Provider

FancyLocationProvider using GMS as the default location provider as it serve the most use case. But you can also used it with any other provider you want like Huawei HMS. Just create the custom provider implement the ILocationProvider interface like this:

class LocationProvider(
    private val context: Context,
    private val locationRequest: LocationRequest
) : ILocationProvider {

    private val locationProviderClient by lazy {
        LocationServices.getFusedLocationProviderClient(context)
    }
    private val locationListener by lazy {
        LocationListener()
    }

    @RequiresPermission(anyOf = [Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION])
    override fun requestLocationUpdates(locationObserver: ILocationObserver) {
        locationListener.locationObserver = locationObserver
        locationProviderClient.requestLocationUpdates(
            locationRequest,
            locationListener,
            Looper.getMainLooper()
        )
    }

    override fun removeLocationUpdates() {
        locationProviderClient.removeLocationUpdates(locationListener)
    }

    private class LocationListener : LocationCallback() {
        var locationObserver: ILocationObserver? = null

        override fun onLocationResult(result: LocationResult?) {
            result?.lastLocation?.let {
                locationObserver?.onLocationResult(it)
            }
        }

        override fun onLocationAvailability(availability: LocationAvailability?) {
            if (availability?.isLocationAvailable == false) {
                locationObserver?.onLocationFailed()
            }
        }
    }
}

Then you can create the custom provider and transform it into LiveData or Flow.

private val locationProvider: ILocationProvider = LocationProvider(context, locationRequest)

val locationFlow: LocationFlow = locationProvider.asFlow()
val locationLiveData: LocationLiveData = locationProvider.asLiveData()

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/Jintin/FancyLocationProvider.

License

The package is available as open source under the terms of the MIT License.

Buy Me A Coffee