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()
}
}
Bir yanıt yazın