Android Location 权限管理

写了一个LocationPermissionGranter类, 用Fragment隐藏了requestPermissions和onRequestPermissionsResult回掉的部分, 实现无论在Activity还是Fragment中都简单易用,并且不受屏幕旋转等影响。

使用方法:

LocationPermissionGranter(this).requirePermission(object : LocationPermissionGranter.LocationPermissionListener {
    override fun onLocationPermissionGranted() {
        showMessage("onLocationPermissionGranted")
    }
    override fun onLocationPermissionDenied(shouldShowDialog: Boolean) {
        showMessage("onLocationPermissionDenied shouldShowDialog" + shouldShowDialog)
    }
})

代码:

import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentActivity
import android.support.v4.content.ContextCompat

class LocationPermissionGranter(private val activity: FragmentActivity) {

    fun hasPermission(): Boolean =
            ContextCompat.checkSelfPermission(activity.applicationContext, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED

    fun requirePermission(listener: LocationPermissionListener? = null) {
        val fragment = getPermissionFragment()
        fragment.listener = listener
        fragment.requestLocationPermission()
    }

    private fun getPermissionFragment(): LocationPermissionFragment {
        var fragment = activity.supportFragmentManager.findFragmentByTag(TAG) as? LocationPermissionFragment
        if (fragment == null) {
            fragment = LocationPermissionFragment()
            val fragmentManager = activity.supportFragmentManager
            fragmentManager
                    .beginTransaction()
                    .add(fragment, TAG)
                    .commitNowAllowingStateLoss()
        }
        return fragment
    }

    class LocationPermissionFragment : Fragment() {
        var listener: LocationPermissionListener? = null

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            retainInstance = true
        }

        fun requestLocationPermission() {
            requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), PERMISSION_REQUEST_CODE)
        }

        override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults)
            if (requestCode != PERMISSION_REQUEST_CODE) {
                return
            }
            if (permissions.size == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                listener?.onLocationPermissionGranted()
            } else {
                listener?.onLocationPermissionDenied(shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION))
            }
        }

        companion object {
            const val PERMISSION_REQUEST_CODE = 10000
        }
    }

    /** Listener to handle Callback for the result from requesting permissions (Might be called after onSaveInstanceState) **/
    interface LocationPermissionListener {
        fun onLocationPermissionGranted()
        fun onLocationPermissionDenied(shouldShowDialog: Boolean)
    }

    companion object {
        val TAG: String = LocationPermissionGranter::class.java.simpleName
    }
}
comments powered by Disqus