Skip to content

Instantly share code, notes, and snippets.

@dmitriy-chernysh
Last active April 14, 2021 03:03
Show Gist options
  • Save dmitriy-chernysh/6e2d74924fdb6092110b467b9aeb3e20 to your computer and use it in GitHub Desktop.
Save dmitriy-chernysh/6e2d74924fdb6092110b467b9aeb3e20 to your computer and use it in GitHub Desktop.
Lifecycle observer to request runtime permission using Result API
//How to use this observer - see 02.Fragment.kt below
class RuntimePermissionObserver(
private val activity: FragmentActivity
) : LifecycleObserver {
private var onGranted: () -> Unit = {}
private var onDenied: () -> Unit = {}
private var onShouldShowRationale: () -> Unit = {}
private lateinit var launcher: ActivityResultLauncher<Array<String>>
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun onCreate() {
launcher = activity
.activityResultRegistry
.register(this.javaClass.name, ActivityResultContracts.RequestMultiplePermissions()) {
var isGranted = false
for (result in it) {
isGranted = result.value
}
if (isGranted)
onGranted()
else
onDenied()
}
}
fun launch(
permissions: Array<String>,
onGranted: () -> Unit = {},
onDenied: () -> Unit = {},
onShouldShowRationale: () -> Unit = {}
) {
this.onGranted = onGranted
this.onDenied = onDenied
this.onShouldShowRationale = onShouldShowRationale
when {
// You can use the API that requires the permission.
permissions.checkSelfPermission() -> onGranted()
// In an educational UI, explain to the user why your app requires this
// permission for a specific feature to behave as expected. In this UI,
// include a "cancel" or "no thanks" button that allows the user to
// continue using your app without granting the permission.
permissions.checkShouldShowRationale(activity) -> onShouldShowRationale()
else -> launcher.launch(permissions)
}
}
private fun Array<String>.checkSelfPermission(): Boolean {
var isGranted = false
for (permission in this) {
isGranted = ContextCompat.checkSelfPermission(
activity,
permission
) == PackageManager.PERMISSION_GRANTED
//if at least one permission is not granted, stop checking
if (!isGranted) break
}
return isGranted
}
private fun Array<String>.checkShouldShowRationale(
activity: FragmentActivity
): Boolean {
var isShouldShow = false
for (permission in this) {
isShouldShow = ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)
//if at least one permission should be rationale, stop checking
if (isShouldShow) break
}
return isShouldShow
}
}
private lateinit var permissionsObserver : RuntimePermissionObserver
....
....
....
override fun onAttach(context: Context) {
super.onAttach(context)
permissionsObserver = RuntimePermissionObserver(requireActivity())
lifecycle.addObserver(permissionsObserver)
}
.....
.....
.....
private fun openCamera() {
permissionsObserver.launch(
arrayOf(Manifest.permission.CAMERA),
onShouldShowRationale = {
//Show some explanation here
},
onGranted = {
//launch the Camera
},
onDenied = {
//show the message to user
}
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment