dartnative_permissions
Runtime permissions for DartNative — request camera, microphone, photos, location, contacts, and notifications through the system dialogs (AVFoundation / Photos / CoreLocation / Contacts on iOS, the runtime-permission APIs on Android). One API, both platforms.
Why you'll like it
- Familiar —
Permission.camera.request(),.status,openAppSettings(), just likepermission_handler. - One surface, both platforms — the same
PermissionandPermissionStatuson iOS and Android; the plugin maps each to the right native API and OS version. - Honest statuses —
granted,denied,permanentlyDenied,restricted, pluslimitedfor iOS 14+ and Android 14+ partial photo access.
Highlights
Permission.x.request()— show the system prompt, get back aPermissionStatus.Permission.x.status— read the current status without a dialog.Permission.x.isGranted/.isLimited— quick boolean checks.openAppSettings()— jump to the app's Settings page (iOS Settings / Android app info).
Permissions: microphone, camera, photos, videos, notification, location,
locationWhenInUse, contacts, storage, and the Android "special" pair
ignoreBatteryOptimizations / accessNotificationPolicy (open the system screen;
granted on iOS).
Install
dependencies:
dartnative_permissions: ^1.0.0 # from dartpub.dev
dn pub get
void main() {
DartNativePluginRegistrant.registerAll();
runApp(const MyApp());
}
Quick look
import 'package:dartnative_permissions/dartnative_permissions.dart';
Request a permission:
final status = await Permission.microphone.request();
if (status.isGranted) {
// start recording…
}
Check the current status without prompting, and route the user to Settings if they've permanently denied it:
final status = await Permission.camera.status;
if (status.isPermanentlyDenied) openAppSettings();
Handle partial photo access:
final photos = await Permission.photos.request();
if (photos.isLimited) {
// user shared a selected subset of their library
}
limitedmeans partial access: on iOS 14+ the user shared a selected subset of their photo library; on Android 14+ they granted "Selected photos" access. Treat it likegrantedfor the photos the user picked.
Platform setup
iOS
For every permission you request, add its usage-description key to ios/Runner/Info.plist —
iOS shows it in the prompt and rejects apps that prompt without one:
| Permission | Info.plist key |
|---|---|
camera |
NSCameraUsageDescription |
microphone |
NSMicrophoneUsageDescription |
photos |
NSPhotoLibraryUsageDescription |
location, locationWhenInUse |
NSLocationWhenInUseUsageDescription |
contacts |
NSContactsUsageDescription |
notification |
(none) |
storage and videos have no iOS equivalent and always resolve to granted.
Android
Declare the <uses-permission> entries your app uses in
android/app/src/main/AndroidManifest.xml — only declared permissions are ever requested:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- Android 13+ -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
<!-- Android 14+ partial ("Selected photos") access -->
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED"/>
<!-- Legacy storage, Android 12 and below -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32"/>
Example
The example/ app lists every permission with its live, colour-coded status —
tap a row to request it, and use "Open app settings" to jump to Settings. Borrow from it
freely.
Credits & license
Ported from
permission_handler
(Baseflow, MIT), reworked to FFI.
Commercial plugin distributed via dartpub.dev — file issues on the plugin's page.