Skip to content

Instantly share code, notes, and snippets.

@JayDev-Lee
Last active March 14, 2024 07:34
Show Gist options
  • Save JayDev-Lee/bc5ae94e5bca8af8eb9858bc4d014edd to your computer and use it in GitHub Desktop.
Save JayDev-Lee/bc5ae94e5bca8af8eb9858bc4d014edd to your computer and use it in GitHub Desktop.
Android Activity, Fragment Permission Request Snippet
import android.app.Activity
import androidx.activity.result.ActivityResultLauncher
import androidx.core.app.ActivityCompat
import androidx.core.content.PermissionChecker
typealias PermissionRequest = () -> Unit
class CheckPermissionLauncher(
private val launcher: ActivityResultLauncher<Array<String>>,
private val permissions: Array<String>,
private val onShowRationale: ((request: PermissionRequest) -> Unit)? = null,
private val requiresPermission: (() -> Unit)
) {
fun launch(activity: Activity) {
if (permissions.all { PermissionChecker.checkSelfPermission(activity, it) == PermissionChecker.PERMISSION_GRANTED }) {
requiresPermission.invoke()
} else {
if (permissions.any { ActivityCompat.shouldShowRequestPermissionRationale(activity, it) }) {
val request = { launcher.launch(permissions) }
onShowRationale?.invoke(request)
} else {
launcher.launch(permissions)
}
}
}
}
private val legacyPermissions = arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
@RequiresApi(Build.VERSION_CODES.Q)
private val permissionsVersionQ = arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.READ_EXTERNAL_STORAGE
)
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
private val permissions = arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.READ_MEDIA_IMAGES
)
private val requestPermissions =
registerRequestPermissions(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) permissions
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) permissionsVersionQ
else legacyPermissions,
onShowRationale = ::onCameraShowRationale,
onPermissionDenied = ::onCameraPermissionDenied,
onNeverAskAgain = ::onCameraNeverAskAgain,
requiresPermission = ::takePicture
)
private fun onCameraShowRationale(request: PermissionRequest) {
request.invoke()
}
private fun takePicture() {
tempFile = try {
ImageUtils.createTempFile(requireContext())
} catch (e: IOException) {
Snackbar.make(
contentBinding.root,
getString(R.string.common_error_create_capture_file_failed),
Snackbar.Type.WARNING
).show()
return
}
val fileUri = FileProvider.getUriForFile(
requireContext(),
"${requireActivity().applicationInfo.packageName}.FileProvider", tempFile!!
)
requestActivity.launch(fileUri)
}
private fun onCameraPermissionDenied() {
DialogFactory.createDeniedPermissions(requireContext()) {
findNavController().navigateUp()
}.show()
}
private fun onCameraNeverAskAgain() {
DialogFactory.createNeverAskPermissions(requireContext()) {
findNavController().navigateUp()
}.show()
}
fun AppCompatActivity.registerRequestPermissions(
permissions: Array<String>,
onShowRationale: ((PermissionRequest) -> Unit)? = null,
onPermissionDenied: (() -> Unit)? = null,
onNeverAskAgain: (() -> Unit)? = null,
requiresPermission: (() -> Unit)
): CheckPermissionLauncher {
val activityResultLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissionResult ->
if (permissionResult.entries.all { result -> result.value }) {
requiresPermission.invoke()
} else {
if (!permissionResult.entries.any { result -> ActivityCompat.shouldShowRequestPermissionRationale(this, result.key) }) {
onNeverAskAgain?.invoke()
} else {
onPermissionDenied?.invoke()
}
}
}
return CheckPermissionLauncher(activityResultLauncher, permissions, onShowRationale, requiresPermission)
}
fun Fragment.registerRequestPermissions(
permissions: Array<String>,
onShowRationale: ((PermissionRequest) -> Unit)? = null,
onPermissionDenied: (() -> Unit)? = null,
onNeverAskAgain: (() -> Unit)? = null,
requiresPermission: (() -> Unit)
): CheckPermissionLauncher {
val activityResultLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissionResult ->
if (permissionResult.entries.all { result -> result.value }) {
requiresPermission.invoke()
} else {
if (!permissionResult.entries.any { result -> shouldShowRequestPermissionRationale(result.key) }) {
onNeverAskAgain?.invoke()
} else {
onPermissionDenied?.invoke()
}
}
}
return CheckPermissionLauncher(activityResultLauncher, permissions, onShowRationale, requiresPermission)
}
fun PermissionChecker.verifyPermissions(vararg grantResults: Int): Boolean {
if (grantResults.isEmpty()) return false
for (result in grantResults) {
if (result != PermissionChecker.PERMISSION_GRANTED) return false
}
return true
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment