raychenon/gray-sky-weather

View on GitHub
app/src/main/java/io/betterapps/graysky/geoloc/UserLocationDelegate.kt

Summary

Maintainability
A
0 mins
Test Coverage
package io.betterapps.graysky.geoloc

import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import android.location.Location
import androidx.core.app.ActivityCompat
import com.google.android.gms.location.FusedLocationProviderClient
import timber.log.Timber

/**
 * self contained class to get location permission and the user current location
 */
class UserLocationDelegate {

    companion object {
        val REQUEST_PERMISSIONS_REQUEST_CODE = 35
    }

    val MANIFEST_ACCESS_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION

    private val context: Context
    private val activity: Activity
    private val fusedLocationClient: FusedLocationProviderClient

    constructor(activity: Activity) {
        this.activity = activity
        this.context = activity as Context
        fusedLocationClient = FusedLocationProviderClient(activity)
    }

    fun requestPermissions(showRationale: () -> Unit) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity, MANIFEST_ACCESS_LOCATION)) {
            // Provide an additional rationale to the user. This would happen if the user denied the
            // request previously, but didn't check the "Don't ask again" checkbox.
            Timber.i("Displaying permission rationale to provide additional context.")
            showRationale()
        } else {
            // Request permission. It's possible this can be auto answered if device policy
            // sets the permission in a given state or the user denied the permission
            // previously and checked "Never ask again".
            Timber.i("Requesting permission")
            startLocationPermissionRequest()
        }
    }

    /**
     * use last location instead of listening to updates of location (no spying)
     * https://developer.android.com/training/location/retrieve-current
     */
    fun getLastLocation(geoListener: (loc: Location?) -> Unit) {
        checkLocationPermission(context)
        Timber.i("getLastLocation ")
        // TODO on emulator , last location is null
        if (fusedLocationClient?.lastLocation == null) {
            Timber.i("getLastLocation null ")
            geoListener(null)
            return
        }

        fusedLocationClient?.lastLocation
            .addOnCompleteListener(activity) { task ->
                if (task.isSuccessful && task.result != null) {
                    // Got last known location. In some rare situations this can be null.
                    task?.result?.let { it -> geoListener(it) }
                } else {
                    Timber.i("getLastLocation task null")
                    geoListener(null)
                }
            }
    }

    /**
     * Return the current state of the permissions needed.
     */
    fun checkLocationPermission(context: Context?): Boolean {
        return (ActivityCompat.checkSelfPermission(context!!, MANIFEST_ACCESS_LOCATION) == PackageManager.PERMISSION_GRANTED)
    }

    fun onRequestPermissionsResultDelete(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray,
        geoListener: (loc: Location?) -> Unit
    ) {
        Timber.i("onRequestPermissionResult")
        if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
            if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission granted.
                getLastLocation(geoListener)
            } else {
                // If user interaction was interrupted, the permission request is cancelled and you
                // receive empty arrays.
                Timber.i("User interaction was cancelled.")
            }
        }
    }

    private fun startLocationPermissionRequest() {
        ActivityCompat.requestPermissions(
            activity,
            arrayOf(MANIFEST_ACCESS_LOCATION),
            REQUEST_PERMISSIONS_REQUEST_CODE
        )
    }
}