BaabaPermissions class

Checks and requests runtime permissions, and walks the user through everything that can go wrong along the way.

final result = await BaabaPermissions.instance.request(
  AppPermission.camera,
  context: context,
);
if (result.isAllowed) openCamera();

One request runs the whole flow:

  1. Check. Already allowed, or nothing to ask for on this OS → done, no UI.
  2. Restricted (parental controls, MDM) → explain; nothing else helps.
  3. Rationale → per RationaleMode, explain why before the system prompt. "Not now" ends the flow without asking.
  4. Request — every stage of the plan, in order.
  5. Denied → offer to ask again, up to maxRetries times, then offer Settings.
  6. Permanently denied → numbered steps and an Open Settings button; waits for the user to come back and re-checks.
  7. Service off (location services, Bluetooth) → offer the switch.

Nothing here throws. Platform failures, a broken store, a dialog that cannot be shown: all are contained, reported to the observer, and reflected in the returned PermissionResult.

Requests are serialised — Android rejects a second request while one is in flight — so two screens asking at once simply queue.

Constructors

BaabaPermissions({PermissionConfig config = const PermissionConfig(), PermissionPlatform? platform, SettingsReturnWaiter? settingsWaiter, DateTime clock()?})

Properties

config ↔ PermissionConfig
The configuration. Assign a new one to change it; takes effect from the next call.
getter/setter pair
hashCode → int
The hash code for this object.
no setterinherited
results → Stream<PermissionResult>
Every final result of every request made through this instance, as it happens. Screens can listen to react to a grant made elsewhere.
no setter
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited

Methods

check(AppPermission permission) → Future<PermissionResult>
The current state, without asking and without any UI.
checkMany(List<AppPermission> permissions) → Future<PermissionResults>
clearHistory() → Future<void>
Forgets every stored PermissionHistory.
isAllowed(AppPermission permission) → Future<bool>
Shorthand for check(permission) then PermissionResult.isAllowed.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
openAppSettings() → Future<bool>
Opens this app's page in Settings. No waiting, no re-check.
openSettingsAndRecheck(List<AppPermission> permissions) → Future<PermissionResults>
Opens this app's page in Settings, waits for the user to come back, and re-checks permissions — for your own "Enable in Settings" button.
planFor(AppPermission permission) → Future<PermissionPlan>
Which native permissions permission maps to on this device — for debugging, and for checking a manifest against.
request(AppPermission permission, {BuildContext? context, PermissionRequestOptions? options}) → Future<PermissionResult>
Runs the full flow for one permission. See the class docs.
requestMany(List<AppPermission> permissions, {BuildContext? context, PermissionRequestOptions? options}) → Future<PermissionResults>
Runs the flow for several permissions at once, grouping them: one rationale listing them all, one system request per stage (Android shows these as a single flow), one Settings dialog for everything that ended up there.
toString() → String
A string representation of this object.
inherited
watch(AppPermission permission) → Stream<PermissionResult>
The state of permission now, then again whenever it changes: after the app returns to the foreground (the user may have changed it in Settings), and after any request through this instance.

Operators

operator ==(Object other) → bool
The equality operator.
inherited

Static Properties

instance → BaabaPermissions
The shared instance. Works without init — with default settings, and showing dialogs only when a call passes a context.
no setter

Static Methods

init(PermissionConfig config, {PermissionPlatform? platform, SettingsReturnWaiter? settingsWaiter}) → BaabaPermissions
Sets up the shared instance. Call once, before runApp:
reset() → void
Drops the shared instance. For tests.