requestWithCustomUi
Request grant with custom UI callback handlers.
This method provides an alternative to the state-based approach, allowing you to inject custom UI directly into the grant flow. Instead of observing state and showing dialogs, you provide callback functions that will be invoked when rationale or settings guidance is needed.
Use this when:
You want full control over the UI (custom dialogs, bottom sheets, etc.)
You're using a non-Compose UI framework
You want to integrate with existing dialog systems
You prefer imperative UI over declarative state
Use the standard request() method when:
Using Compose with GrantDialogHandler
Following the recommended state-based approach
You want consistent dialogs across the app
Parameters
Default message to show in rationale UI
Default message to show in settings UI
Called when rationale should be shown. Parameters: - message: The rationale message - onConfirm: Call this when user confirms (will trigger grant request) - onDismiss: Call this when user dismisses (will cancel flow)
Called when settings guidance should be shown. Parameters: - message: The settings message - onConfirm: Call this when user confirms (will open Settings) - onDismiss: Call this when user dismisses (will cancel flow)
Callback that executes ONLY when grant is granted
Example (Custom Material Dialog):
handler.requestWithCustomUi(
rationaleMessage = "Camera is needed to scan QR codes",
settingsMessage = "Please enable camera in Settings",
onShowRationale = { message, onConfirm, onDismiss ->
MaterialAlertDialogBuilder(context)
.setMessage(message)
.setPositiveButton("Continue") { _, _ -> onConfirm() }
.setNegativeButton("Cancel") { _, _ -> onDismiss() }
.show()
},
onShowSettings = { message, onConfirm, onDismiss ->
MaterialAlertDialogBuilder(context)
.setMessage(message)
.setPositiveButton("Open Settings") { _, _ -> onConfirm() }
.setNegativeButton("Cancel") { _, _ -> onDismiss() }
.show()
}
) {
// Grant granted
openCamera()
}Example (Bottom Sheet):
handler.requestWithCustomUi(
onShowRationale = { message, onConfirm, onDismiss ->
showBottomSheet {
RationaleBottomSheet(
message = message,
onAccept = onConfirm,
onCancel = onDismiss
)
}
},
// ...
)