Android Sweet Permission

Bu kod bloğu android deki multiple ve single izin alma işlerini yönetir. Amaç izni alana kadar yeniden iste. Kalıcı reddetme durumunda ayarları açabilmek için callabak ver.

class SweetPermission private constructor() {

    private var fragment: Fragment? = null
    private var activity: ComponentActivity? = null
    private var permissions: Array<String> = arrayOf()
    private lateinit var onSuccess: () -> Unit
    private lateinit var onOpenSettings: () -> Unit

    companion object {
        fun with(fragment: Fragment): SweetPermission = SweetPermission().apply {
            this.fragment = fragment
        }

        fun with(activity: ComponentActivity): SweetPermission = SweetPermission().apply {
            this.activity = activity
        }
    }

    fun permissions(permissions: Array<String>): SweetPermission {
        this.permissions = permissions
        registerLauncher()
        return this
    }

    private fun registerLauncher() {
        if (fragment != null && permissions.size == 1) {
            fragmentSingleLauncher
        } else if (fragment != null && permissions.size > 1) {
            fragmentMultipleLauncher
        }  else if (activity != null && permissions.size == 1) {
            activitySingleLauncher
        }  else if (activity != null && permissions.size > 1) {
            activityMultipleLauncher
        }
    }

    private var isRequested: Boolean = false

    private var fragmentSingleLauncher: ActivityResultLauncher<String>? = null
        get() {
            field = field ?: fragment?.registerForActivityResult(
                ActivityResultContracts.RequestPermission()
            ) { isGranted: Boolean ->
                isRequested = true
                if (isGranted) onLocalSuccess()
                else check(onSuccess, onOpenSettings)
            }
            return field
        }

    private var fragmentMultipleLauncher : ActivityResultLauncher<Array<String>>? = null
        get() {
            field = field ?: fragment?.registerForActivityResult(
                ActivityResultContracts.RequestMultiplePermissions()
            ) { result ->
                isRequested = true
                if (result.all { it.value }) onLocalSuccess()
                else check(onSuccess, onOpenSettings)
            }
            return field

        }


    private var activitySingleLauncher: ActivityResultLauncher<String>? = null
        get() {
            field = field ?: activity?.registerForActivityResult(
                ActivityResultContracts.RequestPermission()
            ) { isGranted: Boolean ->
                isRequested = true
                if (isGranted) onLocalSuccess()
                else check(onSuccess, onOpenSettings)
            }
            return field
        }

    private var activityMultipleLauncher: ActivityResultLauncher<Array<String>>? = null
        get() {
            field = field ?: activity?.registerForActivityResult(
                ActivityResultContracts.RequestMultiplePermissions()
            ) { result ->
                isRequested = true
                if (result.all { it.value }) onLocalSuccess()
                else check(onSuccess, onOpenSettings)
            }
            return field
        }


    private fun onLocalSuccess() = onSuccess()

    fun check(
        onSuccess: () -> Unit, onOpenSettings: () -> Unit
    ) {
        this.onSuccess = onSuccess
        this.onOpenSettings = onOpenSettings

        val singleMode = permissions.size == 1

        if (this.fragment != null) checkFragmentMode(this.fragment!!, singleMode)
        else if (this.activity != null) checkActivityMode(this.activity!!, singleMode)
    }

    private fun checkFragmentMode(fragment: Fragment, singleMode: Boolean) {
        if (hasPermissions(fragment.context, *permissions)) {
            onSuccess.invoke()
            return
        }

        if (isRequested.not()) {

            if (singleMode) fragmentSingleLauncher?.launch(permissions.first())
            else fragmentMultipleLauncher?.launch(permissions)

            return
        }

        val disabledList = getDisabledPermissions(fragment, *permissions)
        if (disabledList.isNotEmpty()) {
            onOpenSettings.invoke()
            return
        }
        val requesting = getRequestablePermission(fragment, *permissions)
        if (singleMode) fragmentSingleLauncher?.launch(permissions.first())
        else fragmentMultipleLauncher?.launch(requesting)
    }

    private fun checkActivityMode(activity: Activity, singleMode: Boolean) {
        if (hasPermissions(activity, *permissions)) {
            onSuccess.invoke()
            return
        }

        if (isRequested.not()) {

            if (singleMode) activitySingleLauncher?.launch(permissions.first())
            else activityMultipleLauncher?.launch(permissions)

            return
        }

        val disabledList = getDisabledPermissions(activity, *permissions)
        if (disabledList.isNotEmpty()) {
            onOpenSettings.invoke()
            return
        }
        val requesting = getRequestablePermission(activity, *permissions)
        if (singleMode) activitySingleLauncher?.launch(permissions.first())
        else activityMultipleLauncher?.launch(requesting)
    }


    private fun hasPermissions(context: Context?, vararg permissions: String): Boolean =
        permissions.all {
            context?.let { ct ->
                ActivityCompat.checkSelfPermission(
                    ct, it
                )
            } == PackageManager.PERMISSION_GRANTED
        }


    private fun getDisabledPermissions(
        activity: Activity, vararg permissions: String
    ): Array<String> {
        val notGranted = permissions.filter {
            ActivityCompat.checkSelfPermission(
                activity, it
            ) != PackageManager.PERMISSION_GRANTED
        }
        val disabled = notGranted.filterNot {
            ActivityCompat.shouldShowRequestPermissionRationale(
                activity, it
            )
        }
        return disabled.toTypedArray()
    }

    private fun getDisabledPermissions(
        fragment: Fragment, vararg permissions: String
    ): Array<String> {
        val notGranted = permissions.filter {
            fragment.context?.let { ct ->
                ContextCompat.checkSelfPermission(
                    ct, it
                )
            } != PackageManager.PERMISSION_GRANTED
        }
        val disabled = notGranted.filterNot {
            fragment.shouldShowRequestPermissionRationale(
                it
            )
        }
        return disabled.toTypedArray()
    }


    private fun getRequestablePermission(
        activity: Activity, vararg permissions: String
    ): Array<String> {
        val notGranted = permissions.filter {
            ContextCompat.checkSelfPermission(
                activity, it
            ) != PackageManager.PERMISSION_GRANTED
        }
        return notGranted.filter {
            ActivityCompat.shouldShowRequestPermissionRationale(
                activity, it
            )
        }.toTypedArray()
    }

    private fun getRequestablePermission(
        fragment: Fragment, vararg permissions: String
    ): Array<String> {
        val notGranted = permissions.filter {
            fragment.context?.let { ct ->
                ContextCompat.checkSelfPermission(
                    ct, it
                )
            } != PackageManager.PERMISSION_GRANTED
        }
        return notGranted.filter {
            fragment.shouldShowRequestPermissionRationale(
                it
            )
        }.toTypedArray()
    }
}

Yorumlar

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Bu site reCAPTCHA ve Google tarafından korunmaktadır Gizlilik Politikası ve Kullanım Şartları uygula.

The reCAPTCHA verification period has expired. Please reload the page.