Permissions and device capabilities
Capabilities like the camera, location, notifications, files and the microphone require user permission. The flow has three stages and all three must be handled:
- Check — is permission already granted
- Request — show the system dialog
- Handle refusal — the user can say no, and can even choose "don't ask again"
That last case is the one most often forgotten: in a permanently-denied state the dialog never appears again, and the only route left is sending the user to system settings.
| State | Meaning | Correct behaviour |
|---|---|---|
| granted | Permission granted | Proceed with the feature |
| denied | Refused, but you may ask again | Explain why it is needed and ask again |
| permanentlyDenied | The user chose not to be asked again | Show a button that opens system settings |
| restricted | Blocked by device policy such as parental controls | Offer an alternative; do not keep asking |
Interview tip. Here the UX matters as much as the API: showing the system dialog out of context, right at launch is the worst practice — most users refuse reflexively and you never get to ask again. The right approach is asking at the moment of need, with a short rationale first ("we need camera access to scan the document"). That is the pre-permission pattern, and it lifts acceptance rates substantially.
📚 Sources and documentation
- permission_handler packagepub.dev
All permission states and the `openAppSettings` method are listed in the README.
- Platform integrationofficialdocs.flutter.dev
- Android deploymentofficialdocs.flutter.dev