Last active
March 14, 2024 07:34
-
-
Save JayDev-Lee/bc5ae94e5bca8af8eb9858bc4d014edd to your computer and use it in GitHub Desktop.
Android Activity, Fragment Permission Request Snippet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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