Viewing version 13.0.2. Open the latest package page.

permission_handler

13.0.2

Permission plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions.

Download archive

Readme

pub package Build status style: effective dart codecov

On most operating systems, permissions aren't just granted to apps at install time. Rather, developers have to ask the user for permission while the app is running.

This plugin provides a cross-platform (iOS, Android) API to request permissions and check their status. You can also open the device's app settings so users can grant permission.
On Android, you can show a rationale for requesting permission.

See the FAQ section for more information on common questions when using the permission_handler plugin.

Setup

While the permissions are being requested during runtime, you'll still need to tell the OS which permissions your app might potentially use. That requires adding permission configuration to Android* and iOS-specific files.

Upgrade pre-1.12 Android projects

Since version 4.4.0 this plugin is implemented using the Flutter 1.12 Android plugin APIs. Unfortunately, this means App developers also need to migrate their Apps to support the new Android infrastructure. You can do so by following the Upgrading pre 1.12 Android projects migration guide. Failing to do so might result in unexpected behavior. The most common known error is the permission_handler not returning after calling the .request() method on permission.

AndroidX

As of version 3.1.0, the permission_handler plugin switched to the AndroidX version of the Android Support Libraries. This means you need to make sure your Android project is also upgraded to support AndroidX. Detailed instructions can be found here.

The TL;DR version is:

  1. Add the following to your "gradle.properties" file:
android.useAndroidX=true
android.enableJetifier=true
  1. Make sure you set the compileSdkVersion in your "android/app/build.gradle" file to 35:
android {
  compileSdkVersion 35
  ...
}
  1. Make sure you replace all the android. dependencies to their AndroidX counterparts (a full list can be found here).

Add permissions to your AndroidManifest.xml file. There are debug, main, and profile versions which are chosen depending on how you start your app. In general, it's sufficient to add permission only to the main version. Here's an example AndroidManifest.xml with a complete list of all possible permissions.

Requires Flutter 3.24.0 or higher and Xcode 15.0 or higher.

With SPM, Package.swift automatically detects which permissions to enable by reading your app's Info.plist. A permission is compiled in when its corresponding usage description key is present:

Permission group Info.plist key
PermissionGroup.calendar (< iOS 17) NSCalendarsUsageDescription
PermissionGroup.calendarWriteOnly / calendarFullAccess (iOS 17+) NSCalendarsFullAccessUsageDescription or NSCalendarsWriteOnlyAccessUsageDescription
PermissionGroup.reminders NSRemindersUsageDescription
PermissionGroup.contacts NSContactsUsageDescription
PermissionGroup.camera NSCameraUsageDescription
PermissionGroup.microphone NSMicrophoneUsageDescription
PermissionGroup.speech NSSpeechRecognitionUsageDescription
PermissionGroup.photos NSPhotoLibraryUsageDescription or NSPhotoLibraryAddUsageDescription
PermissionGroup.photosAddOnly NSPhotoLibraryAddUsageDescription
PermissionGroup.location NSLocationWhenInUseUsageDescription or NSLocationAlwaysAndWhenInUseUsageDescription
PermissionGroup.locationWhenInUse NSLocationWhenInUseUsageDescription
PermissionGroup.locationAlways NSLocationAlwaysAndWhenInUseUsageDescription
PermissionGroup.mediaLibrary NSAppleMusicUsageDescription
PermissionGroup.sensors NSMotionUsageDescription
PermissionGroup.bluetooth NSBluetoothAlwaysUsageDescription or NSBluetoothPeripheralUsageDescription
PermissionGroup.appTrackingTransparency NSUserTrackingUsageDescription
PermissionGroup.assistant NSSiriUsageDescription
PermissionGroup.notification (enabled by default — see below)
PermissionGroup.criticalAlerts (disabled by default — see below)

Because you must already add these keys to Info.plist for any permission to work, a single-flavor app needs no additional configuration.

Info.plist files are located through the INFOPLIST_FILE setting of your Xcode project and .xcconfig files, so build-configuration specific plists (Info-Debug.plist, Runner/Info-$(CONFIGURATION).plist, …) are picked up as well. When an app has several of them, the keys are merged: a permission declared in any one of them is compiled into every build configuration.

Special cases: permissions without an Info.plist key

PermissionGroup.notification has no required Info.plist key and is enabled by default. To opt out, disable it via environment variable before building:

# When building from terminal (flutter run / flutter build)
export PERMISSION_NOTIFICATIONS=0

# When building from Xcode GUI (set once per Mac session, then restart Xcode)
launchctl setenv PERMISSION_NOTIFICATIONS 0

PermissionGroup.criticalAlerts requires a special entitlement granted by Apple and is disabled by default to avoid compiling unused code into apps that don't need it. Enable it explicitly:

# When building from terminal
export PERMISSION_CRITICAL_ALERTS=1

# When building from Xcode GUI
launchctl setenv PERMISSION_CRITICAL_ALERTS 1

After changing any env var or Info.plist key, clear Xcode's package cache once so Package.swift is re-evaluated:

rm -rf ~/Library/Developer/Xcode/DerivedData

Then run flutter build ios or rebuild in Xcode as usual.

Apps with flavors

Merging is wrong when your flavors need different permissions: a permission declared only in Info-dev.plist is compiled into your production binary too, which is grounds for App Store rejection (ITMS-90683). Declare a permission_handler.yaml next to your pubspec.yaml to give each flavor its own Info.plist, and select the flavor before building:

strict: true
flavors:
  dev:
    info-plist: ios/Runner/Info-dev.plist
    configurations: [Debug-dev, Profile-dev, Release-dev]
  prod:
    info-plist: ios/Runner/Info-prod.plist
    configurations: [Debug-prod, Profile-prod, Release-prod]
dart run permission_handler_apple:select prod
flutter run --flavor prod

Only the selected flavor's Info.plist is read and nothing is merged, so a flavor can never inherit another flavor's permissions. See Per-flavor permissions for the build phase that catches a stale selection.

Builds started from Xcode.app

Automatic detection finds your app through the build's working directory, which points at the Flutter project for flutter run, flutter build ios and xcodebuild. Builds started from Xcode.app run with / as their working directory and cannot be detected, so point the manifest at your Info.plist explicitly:

launchctl setenv PERMISSION_HANDLER_INFO_PLIST /absolute/path/to/ios/Runner/Info.plist
rm -rf ~/Library/Developer/Xcode/DerivedData

Troubleshooting

If no Info.plist is found, every permission is compiled out and all permission checks report denied. Xcode discards Swift package manifest output, so the warning about this only reaches you from the command line:

cd your_app
PERMISSION_HANDLER_VERBOSE=1 swift package --manifest-cache none \
  --package-path ios/Flutter/ephemeral/Packages/.packages/permission_handler_apple \
  dump-package > /dev/null

That prints the Info.plist files that were used, the active flavor if you declared one, and the value every PERMISSION_* macro resolved to.

More detail

The permission_handler_apple README documents this in full, including every PERMISSION_HANDLER_* environment variable and the per-flavor workflow.

Add permission to your Info.plist file. Here's an example Info.plist with a complete list of all possible permissions.

IMPORTANT: You will have to include all permission options when you want to submit your App. This is because the permission_handler plugin touches all different SDKs and because the static code analyzer (run by Apple upon App submission) detects this and will assert if it cannot find a matching permission option in the Info.plist. More information about this can be found here. This has been fixed since version 8.0.0, now permission_handler by default excludes all permissions and developers only have to enable those that the app really needs.

The permission_handler plugin use macros to control whether a permission is enabled.

You must list the permission you want to use in your application:

  1. Add the following to your Podfile's post_install block:
post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)

    target.build_configurations.each do |config|
      # You can remove unused permissions here
      # for more information: https://github.com/Baseflow/flutter-permission-handler/blob/main/permission_handler_apple/ios/Classes/PermissionHandlerEnums.h
      # When you don't need a permission, just change its value to 0
      # e.g. 'PERMISSION_CAMERA=0' instead of 'PERMISSION_CAMERA=1'
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

        ## dart: PermissionGroup.calendar
        'PERMISSION_EVENTS=1',
        
        ## dart: PermissionGroup.calendarFullAccess
        'PERMISSION_EVENTS_FULL_ACCESS=1',

        ## dart: PermissionGroup.reminders
        'PERMISSION_REMINDERS=1',

        ## dart: PermissionGroup.contacts
        'PERMISSION_CONTACTS=1',

        ## dart: PermissionGroup.camera
        'PERMISSION_CAMERA=1',

        ## dart: PermissionGroup.microphone
        'PERMISSION_MICROPHONE=1',

        ## dart: PermissionGroup.speech
        'PERMISSION_SPEECH_RECOGNIZER=1',

        ## dart: PermissionGroup.photos
        'PERMISSION_PHOTOS=1',

        ## The 'PERMISSION_LOCATION' macro enables the `locationWhenInUse` and `locationAlways` permission. If
        ## the application only requires `locationWhenInUse`, only specify the `PERMISSION_LOCATION_WHENINUSE`
        ## macro.
        ##
        ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
        'PERMISSION_LOCATION=1',
        'PERMISSION_LOCATION_WHENINUSE=0',

        ## dart: PermissionGroup.notification
        'PERMISSION_NOTIFICATIONS=1',

        ## dart: PermissionGroup.mediaLibrary
        'PERMISSION_MEDIA_LIBRARY=1',

        ## dart: PermissionGroup.sensors
        'PERMISSION_SENSORS=1',

        ## dart: PermissionGroup.bluetooth
        'PERMISSION_BLUETOOTH=1',

        ## dart: PermissionGroup.appTrackingTransparency
        'PERMISSION_APP_TRACKING_TRANSPARENCY=1',

        ## dart: PermissionGroup.criticalAlerts
        'PERMISSION_CRITICAL_ALERTS=1',

        ## dart: PermissionGroup.assistant
        'PERMISSION_ASSISTANT=1',
      ]

    end
  end
end
  1. For the permissions you want to use, keep them as is. For example, if you need access to the calendar make sure the code looks like this:

            ## dart: PermissionGroup.calendar
            'PERMISSION_EVENTS=1',
    
  2. When you DON'T need a permission, change its value to 0 e.g. 'PERMISSION_CAMERA=0' instead of 'PERMISSION_CAMERA=1'

  3. And delete the corresponding permission description in Info.plist e.g. when you don't need camera permission, just delete 'NSCameraUsageDescription'

The following lists the relationship between Permission and The key of Info.plist:

Permission Info.plist Macro
PermissionGroup.calendar (< iOS 17) NSCalendarsUsageDescription PERMISSION_EVENTS
PermissionGroup.calendarWriteOnly (iOS 17+) NSCalendarsWriteOnlyAccessUsageDescription PERMISSION_EVENTS
PermissionGroup.calendarFullAccess (iOS 17+) NSCalendarsFullAccessUsageDescription PERMISSION_EVENTS_FULL_ACCESS
PermissionGroup.reminders NSRemindersUsageDescription PERMISSION_REMINDERS
PermissionGroup.contacts NSContactsUsageDescription PERMISSION_CONTACTS
PermissionGroup.camera NSCameraUsageDescription PERMISSION_CAMERA
PermissionGroup.microphone NSMicrophoneUsageDescription PERMISSION_MICROPHONE
PermissionGroup.speech NSSpeechRecognitionUsageDescription PERMISSION_SPEECH_RECOGNIZER
PermissionGroup.photos NSPhotoLibraryUsageDescription PERMISSION_PHOTOS
PermissionGroup.photosAddOnly NSPhotoLibraryAddUsageDescription PERMISSION_PHOTOS_ADD_ONLY
PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse NSLocationUsageDescription, NSLocationAlwaysAndWhenInUseUsageDescription, NSLocationWhenInUseUsageDescription PERMISSION_LOCATION
PermissionGroup.locationWhenInUse NSLocationWhenInUseUsageDescription PERMISSION_LOCATION_WHENINUSE
PermissionGroup.notification PermissionGroupNotification PERMISSION_NOTIFICATIONS
PermissionGroup.mediaLibrary NSAppleMusicUsageDescription, kTCCServiceMedia PERMISSION_MEDIA_LIBRARY
PermissionGroup.sensors NSMotionUsageDescription PermissionGroupSensors
PermissionGroup.bluetooth NSBluetoothAlwaysUsageDescription, NSBluetoothPeripheralUsageDescription PermissionGroupBluetooth
PermissionGroup.appTrackingTransparency NSUserTrackingUsageDescription PermissionGroupAppTrackingTransparency
PermissionGroup.criticalAlerts UNAuthorizationOptionCriticalAlert PermissionGroupCriticalAlerts
PermissionGroup.assistant NSSiriUsageDescription PermissionGroupAssistant
  1. Clean & Rebuild

How to use

There are a number of Permissions. You can get a Permission's status, which is either granted, denied, restricted, permanentlyDenied, limited, or provisional.

var status = await Permission.camera.status;
if (status.isDenied) {
  // We haven't asked for permission yet or the permission has been denied before.
  // On Android this also covers a permanently denied permission: the OS does not
  // expose the difference without requesting, so call `request()` to find out.
}

// You can also directly ask permission about its status.
if (await Permission.location.isRestricted) {
  // The OS restricts access, for example, because of parental controls.
}

Can use also this style for better readability of your code when using the Permission class.

await Permission.camera
  .onDeniedCallback(() {
    // Your code
  })
  .onGrantedCallback(() {
    // Your code
  })
  .onPermanentlyDeniedCallback(() {
    // Your code
  })
  .onRestrictedCallback(() {
    // Your code
  })
  .onLimitedCallback(() {
    // Your code
  })
  .onProvisionalCallback(() {
    // Your code
  })
  .request();

Call request() on a Permission to request it. If it has already been granted before, nothing happens.
request() returns the new status of the Permission.

if (await Permission.contacts.request().isGranted) {
  // Either the permission was already granted before or the user just granted it.
}

// You can request multiple permissions at once.
Map<Permission, PermissionStatus> statuses = await [
  Permission.location,
  Permission.storage,
].request();
print(statuses[Permission.location]);

Some permissions, for example, location or acceleration sensor permissions, have an associated service, which can be enabled or disabled.

if (await Permission.locationWhenInUse.serviceStatus.isEnabled) {
  // Use location.
}

You can also open the app settings:

if (await Permission.speech.request().isPermanentlyDenied) {
  // The user opted to never again see the permission request dialog for this
  // app. The only way to change the permission's status now is to let the
  // user manually enable it in the system settings.
  openAppSettings();
}

On Android, only the result of request() can be permanentlyDenied; status reports denied instead. Android does not expose whether a permission is permanently denied: a permission that was never requested, one that the user reset to "Ask every time" in the app settings and a permanently denied one all look the same to the app. Requesting a permanently denied permission is cheap, the OS resolves it immediately without showing a dialog. The Android "permanently denied" guide covers this in full: what each status means on Android, the request-driven pattern to use instead, and how to audit an existing app for code that relies on the old behavior.

On Android, you can show a rationale for using permission:

bool isShown = await Permission.contacts.shouldShowRequestRationale;

Some permissions will not show a dialog asking the user to allow or deny the requested permission.
This is because the OS setting(s) of the app are being retrieved for the corresponding permission.
The status of the setting will determine whether the permission is granted or denied.

The following permissions will show no dialog:

  • Notification
  • Bluetooth

The following permissions will show no dialog, but will open the corresponding setting intent for the user to change the permission status:

  • manageExternalStorage
  • systemAlertWindow
  • requestInstallPackages
  • accessNotificationPolicy

The locationAlways permission can not be requested directly, the user has to request the locationWhenInUse permission first. Accepting this permission by clicking on the 'Allow While Using App' gives the user the possibility to request the locationAlways permission. This will then bring up another permission popup asking you to Keep Only While Using or to Change To Always Allow.

FAQ

Permission.status never returns permanentlyDenied on Android. What can I do?

That is intentional as of permission_handler_android 14.1.0. Android does not expose whether a permission is permanently denied, so a status check reports denied for every denied runtime permission. Call request() and branch on its result: it returns permanentlyDenied without showing a dialog when the permission really is permanently denied. See the Android "permanently denied" guide for the full behavior table, the pattern to use and an audit checklist for existing apps.

Requesting "storage" permissions always returns "denied" on Android 13+. What can I do?

On Android, the Permission.storage permission is linked to the Android READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions. Starting from Android 10 (API 29) the READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions have been marked deprecated and have been fully removed/disabled since Android 13 (API 33).

If your application needs access to media files Google recommends using the READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, or READ_MEDIA_AUDIO permissions instead. These can be requested using the Permission.photos, Permission.videos, and Permission.audio respectively. To request these permissions make sure the compileSdkVersion in the android/app/build.gradle file is set to 33.

If your application needs access to Android's file system, it is possible to request the MANAGE_EXTERNAL_STORAGE permission (using Permission.manageExternalStorage). As of Android 11 (API 30), the MANAGE_EXTERNAL_STORAGE permission is considered a high-risk or sensitive permission. Therefore it is required to declare the use of these permissions if you intend to release the application via the Google Play Store.

Requesting Permission.locationAlways always returns "denied" on Android 10+ (API 29+). What can I do?

Starting with Android 10, apps are required to first obtain permission to read the device's location in the foreground, before requesting to read the location in the background as well. When requesting the 'location always' permission directly, or when requesting both permissions at the same time, the system will ignore the request. So, instead of calling only Permission.location.request(), make sure to first call either Permission.location.request() or Permission.locationWhenInUse.request(), and obtain permission to read the GPS. Once you obtain this permission, you can call Permission.locationAlways.request(). This will present the user with the option to update the settings so the location can always be read in the background. For more information, visit the Android documentation on requesting location permissions.

onRequestPermissionsResult is called without results. What can I do?

It is probably caused by a difference between compileSdkVersion and targetSdkVersion. It can be depending on the flutter version that you use. targetSdkVersion = flutter.targetSdkVersion in the app/build.gradle indicates that the targetSdkVersion is flutter version dependant. For more information: issue 1222

Checking or requesting a permission terminates the application on iOS. What can I do?

First of all make sure all that the ios/Runner/Info.plist file contains entries for all the permissions the application requires. If an entry is missing iOS will terminate the application as soon as the particular permission is being checked or requested.

If the application requires access to SiriKit (by requesting the Permission.assistant permission), also make sure to add the com.apple.developer.siri entitlement to the application configuration. To do so create a file (if it doesn't exists already) called Runner.entitlements in the ios/Runner folder that is part of the project. Open the file and add the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.developer.siri</key>
	<true/>
</dict>
</plist>

The important part here is the key with value com.apple.developer.siri and the element <true/>. It is possible that this file also contains other entitlements depending on the needs of the application.

Issues

Please file any issues, bugs, or feature requests as an issue on our GitHub page. Commercial support is available if you need help with integration with your app or services. You can contact us at hello@baseflow.com.

Want to contribute

If you would like to contribute to the plugin (e.g. by improving the documentation, solving a bug, or adding a cool new feature), please carefully review our contribution guide and send us your pull request.

Author

This Permission handler plugin for Flutter is developed by Baseflow. You can contact us at hello@baseflow.com

Changelog

13.0.2

  • Updates the README to detect a permanent denial on Android from the result of request(), as status cannot detect it.
  • Updates permission_handler_android to version 14.1.0, which fixes status reporting permanentlyDenied after the user selected "Ask every time" in the Android app settings (see issue #1206).
  • Adds the Android "permanently denied" guide, explaining the changed Android behavior, the request-driven pattern to use and how to audit an existing app for code that relies on the old behavior.

13.0.1

  • Updates documentation on how to configure the permission handler on macOS / iOS.

13.0.0

  • BREAKING CHANGE: , android compilesdk now set to version compileSdkVersion 37
  • Added support for the new Android 17 permission ACCESS_LOCAL_NETWORK

12.0.3

  • Rewrites the "iOS - CocaoPods" section in the README.md to match version 8.0.0 of the permission_handler.
  • Fixes several smaller typo's in the README.md.

12.0.2

  • Updates the documentation to include instructions on Swift Package Manager (SPM) support.

12.0.1

  • Updates the correspondence between permission groups and the key values of Info.plist in the README.md.

12.0.0+1

  • Updated README documentation from compileSdkVersion 33 to compileSdkVersion 35
  • Updates example project IPHONEOS_DEPLOYMENT_TARGET = 11.0 to 12.0

12.0.0

  • BREAKING CHANGE: Updates permission_handler_android dependency to version 13.0.0. Updated Android compileSdkVersion to 35 .

11.4.0

  • Updates dependencies to latest versions.
  • Migrates away from deprecated imperative Flutter gradle settings.

11.3.1

  • Documents the use of the PERMISSION_LOCAITON_WHENINUSE macro on iOS.

11.3.0

  • Adds a new permission Permission.backgroundRefresh to check the background refresh permission status via:
    • Updates permission_handler_apple dependency to version 9.1.5.
    • Updates permission_handler_platform_interface dependency to version 3.11.6.

11.2.1

  • Adds PermissionGroup.photosAddOnly to the README.

11.2.0

  • Adds the Permission.assistant which allows users to request permissions to access SiriKit on iOS and macOS platforms. This is a no-op on all other platforms.

11.1.0

  • Adds support for iOS 17+ Calendar access levels.
  • Deprecates Permission.calendar. Use Permission.calendarWriteOnly to request a write-only access to the calendar. For full access to calendar use Permission.calendarFullAccess.
  • For Permission.calendarFullAccess on iOS 17+ use PERMISSION_EVENTS_FULL_ACCESS in Podfile instead of PERMISSION_EVENTS.
  • Adds web support by endorsing permission_handler_html as the web implementation of the permission handler. Only some permissions are supported at this time.
  • Updates permission_handler_android dependency to version 12.0.1.
  • Updates permission_handler_apple dependency to version 9.2.0.
  • Updates permission_handler_windows dependency to version 0.2.0.
  • Updates permission_handler_platform_interface dependency to version 4.0.2.

11.0.1

  • Adds extension methods to the PermissionStatus enum allowing developers to register callback methods, which will improve code readability.

11.0.0

  • BREAKING CHANGE: Updates permission_handler_android dependency to version 11.0.0.
  • Updates permission_handler_apple dependency to version 9.1.4.
  • Updates permission_handler_platform_interface dependency to version 3.11.5.

10.4.5

  • Updates the mentions of Android versions in the README, now following a format of 'Android {name} (API {number})'. For example: 'Android 13 (API 33)'.

10.4.4

  • Adds a section to the FAQ clarifying how to request background location permission on Android 10+ (API 29+).

10.4.3

  • Updates example app to show relevant permissions on Android and iOS platforms.
  • Updates the documentation for the Permission.bluetooth permission regarding the limitations of the permission on iOS.

10.4.2

  • Adds a FAQ section to the README.md file.

10.4.1

  • Updates AndroidManifest documentation in the example application with regards to the use of READ_EXTERNAL_STORAGE, READ_MEDIA_IMAGES, READ_MEDIA_VIDEO and READ_MEDIA_AUDIO permissions.

10.4.0

  • Adds support for the new Android 13 permission: BODY_SENSORS_BACKGROUND.

10.3.0

  • Adds support for the "Provisional" permission status introduced with iOS 12+.

10.2.1

  • Fix missing POST_NOTIFICATIONS permission in the Android example project.

10.2.0

  • Added support for the new Android 13 permissions: SCHEDULE_EXACT_ALARM, READ_MEDIA_IMAGES, READ_MEDIA_VIDEO and READ_MEDIA_AUDIO

10.1.0

  • Added support for the new Android 13 permission: NEARBY_WIFI_DEVICES.

10.0.2

  • Adds a link to the issue tracker which shows up as "View/report issues" on pub.dev.

10.0.1

  • Fix the PermissionHandlerEnums link in the README.md

10.0.0

  • BREAKING CHANGE: Updated Android compileSdkVersion to 33 to handle the new POST_NOTIFICATIONS permission.

    When updating to version 10.0.0 make sure to update the android/app/build.gradle file and set the compileSdkVersion to 33.

9.2.0

  • Federated permission_handler_windows for the Windows version.

9.1.0

  • Moved out Android and iOS implementations into their own packages.

9.0.2

  • Fixes regression when requesting 'locationAlways' permission on Android 9 (Pie) and earlier.

9.0.1

  • Fixes bug when requesting locationAlways permissions on Android.
  • Solves a compilation error when building the example App on Android.

9.0.0

  • iOS: Bluetooth permission dialog now appears when requested instead of when the app is initialized. Note: Requesting Bluetooth status will also prompt the permission dialog (see issue #591).

8.3.0

  • Updated Android Gradle Plugin to 4.1.0 and Gradle Wrapper to 6.7 which is in line with the current Flutter stable version (Flutter 2.5.3).

8.2.6

  • Fixed broken Androidx migration link in the README.md.

8.2.5

  • Fixed broken link in the README.md.

8.2.4

  • Solved bug where output would log that there is no permission in the manifest for BLUETOOTH_SCAN, BLUETOOTH_ADVERTISE, and BLUETOOTH_CONNECT on Android 11 devices and lower(see issue #691).

8.2.3

  • iOS: Enhanced the bluetooth permission for iOS 13 and up, so the user gets prompted with the "Bluetooth" permission dialog (see issue #591).

8.2.2

  • Updated the README.md to mention setting the compileSdkVersion to 31;
  • Added an additional note to version 8.2.0 release notes to inform people to update the compileSdkVersion.

8.2.1

  • Resolved an issue where checking permissions on pre-Android M devices always resolved to PermissionStatus.denied (see issue #60);
  • Updated the url_launcher dependency in the example App to ^6.0.12.

8.2.0

IMPORTANT: When updating to version 8.2.0 make sure to also set the compileSdkVersion in the app/build.gradle file to 31.

  • Added support for the new Android 12 Bluetooth permissions: BLUETOOTH_SCAN, BLUETOOTH_ADVERTISE, and BLUETOOTH_CONNECT.
  • Updated Android compile and target SDK to 31 (Android 12 (S)).
  • Updated Gradle and dependencies of the Android project.
  • Updated application of the example app

8.1.6

  • Android: Fixed a NullPointerException when changing permissions in the Location Settings intent.

8.1.5

  • Android: Fixed deprecation warnings/errors when compileSdkVersion was set to 31 (Android S/12).

8.1.4+2

  • iOS: fixed memory error that occurred on iOS 12.2 and below (see issue #638).

8.1.4+1

  • Fix a bug where after allowing the location permission and requesting it again would lead to a memory error.

8.1.4

  • Fix bug where requesting locationAlways permission sometimes returns PermissionStatus.Denied instead of PermissionStatus.Granted.

8.1.3

  • Fix bug where locationAlways returns PermanentlyDenied;
  • Updated the README.md for requesting the locationAlways permission the correct way.

8.1.2

  • Suppress deprecation warnings on iOS for code that specifically targets older iOS versions (see issue #607).

8.1.1

  • Fixed deprecation issue when checking phone capabilities on iOS (see issue #597).

8.1.0

  • Added support for iOS 12+ Critical Alerts permission requesting.
    • NOTE: This requires applying to Apple and receiving a special entitlement from them in order to work. See this article for an explanation of how to use Critical Alerts.
  • Added support for Android M+ Access Notification Policy permission requesting (ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS).
    • Note: This opens a general page in settings, not specific to the package.

8.0.1

  • Updated API documentation for the PermissionStatus.permanentlyDenied status.

8.0.0+2

  • Fix broken Podfile link noted at 8.0.0.
  • Fix the information link noted at Podfile.

8.0.0+1

  • Updated the README.md setup section about the Podfile and changed a minor spelling mistake.

8.0.0

This release contains the following breaking changes:

  • Starting from this version the permissions on iOS are disabled by default. To enable permission, specify the correct GCC_PREPROCESSOR_DEFINITIONS in the ios/Podfile file. For an example check out the Podfile of the example application.
  • Added support for the "AppTrackingTransparency" permission on iOS.

7.2.0

  • Added support for the "REQUEST_INSTALL_PACKAGES" permission on Android.

7.1.1

  • Improved the example app by using the Baseflow Plugin Template and moving all the functionality to the main.dart file.

7.1.0

  • Added support for the "SYSTEM_ALERT_WINDOW" permission on Android.

7.0.0

This release contains the following breaking changes:

  • Updated compile SDK version to 30 in the build.gradle for handling the MANAGE_EXTERNAL_STORAGE permission;
  • Added the MANAGE_EXTERNAL_STORAGE permission for Android R and up;
  • Registered listeners on the plugin level to prevent memory leaks or unwanted behavior.

6.1.3

  • Implement equality operator on the Permission class;
  • Updated the README.md with instructions on enabling/ disabling the Bluetooth permissions on iOS;
  • Corrected some spelling mistakes in the CHANGELOG.md.

6.1.2

  • Correctly handle the ACCESS_MEDIA_LOCATION and ACCESS_ACTIVITY_RECOGNITION permissions on pre-Android Q devices (permissions should be implicitly granted on pre-Android Q).

6.1.1

  • Added unit tests to guard API against breaking changes.

6.1.0

  • Added support for Bluetooth permissions;
  • Workaround for ignoring battery optimizations on pre-M Android devices (see PR #376).

6.0.1+1

  • Fixed content of the README.md file.

6.0.1

  • Fixed deprecation warning when building Android projects.

6.0.0

This release includes the following breaking changes:

  • Migrated to null safety
  • Removed PermissionStatus.undetermined, PermissionStatus.denied will be used instead (see our "Changes in 6.0.0" wiki page for more details).

5.1.0+2

  • Solve mismatch with permission constants between Dart and Android (due to the addition of permission on iOS);
  • Fix the compile error that occurred when on iOS the "PERMISSION_PHOTOS" macro is deactivated (meaning code dealing with the PHPhotoLibrary library is removed from the code base).

5.1.0+1

  • Recreate the iOS part of the example project based on the Flutter stable channel (the previous version was accidentally created with the Flutter beta channel).

5.1.0

  • Added support for the limited photo permission available on iOS 14 and up;
  • Fixed deprecated warning on iOS;
  • Added support for the "READ_PHONE_NUMBERS" permission on Android;
  • Fix a link to the contribution guide in the README.md.

5.0.1+2

  • Pin dependency on permission_handler_platform_interface on version 2.0.1.

5.0.1+1

  • Fixes Typo
  • Issue #233 * on 5.0: Solved a bug that prevented Android applications running in the background to check the permission status.

5.0.1

  • Update permission_handler_platform_interface 2.0.1

5.0.0+hotfix.10

  • Revert pull-request #317

5.0.0+hotfix.9

  • Solved an issue where kCLAuthorizationStatusAuthorizedWhenInUse was returning PermissionStatusDenied (see #317)

5.0.0+hotfix.8

  • Solved an issue on iOS where requesting notification permissions returned prematurely (see pull-request #297)

5.0.0+hotfix.7

  • ** Mistake release please don't use this version **

5.0.0+hotfix.6

  • Solved an issue on iOS where requesting notification permissions always resulted in a "granted" result (see pull-request #289)

5.0.0+hotfix.5

  • Remove the use of the deprecated pre-iOS 8 API causing users to compile issues (see issue #277).

5.0.0+hotfix.4

  • Solve issue on Android causing an IllegalStateException (#267).

5.0.0+hotfix.3

  • Includes the changes of 4.4.0+hotfix.4 (which was released to be backward compatible).

5.0.0+hotfix.2

  • Removed some residual usages of the PermissionStatusUnknown constants in #ifdef statements that were not found by the compiler.

5.0.0+hotfix.1

  • Make sure all enums from permission_handler_platform_interface: 2.0.0 are exposed through the permission_handler.

5.0.0

  • BREAKING: Implemented more intuitive API exposed by permission_handler_platform_interface: 2.0.0 (#230).

4.4.0+hotfix.4

  • Android: solved issue where permission_handler is used in a service (see #251)

4.4.0+hotfix.3

IGNORE THIS VERSION, it was released by accident and contains the same code as 4.4.0+hotfix.2

4.4.0+hotfix.2

  • Issue #235: Solved a bug that made it impossible to request service status on Android 7;
  • Issue #237: Solved a bug that crashes the application when canceling the "Ignore battery optimizations" request for permissions.

4.4.0+hotfix.1

  • Issue #233: Solved a bug that prevented Android applications from running in the background to check the permission status.

4.4.0

  • Updated plugin structure to conform to the Flutter federated plugin architecture. This will make it easier to add new platform implementations (see: https://medium.com/flutter/how-to-write-a-flutter-web-plugin-part-2-afdddb69ece6);
  • Android: Migrate to FlutterPlugin Android API (better support for Add-to-App);
  • Android: Suppress JAVA warnings which are generated to old platform code (only executes on older platforms);
  • Android: Fixed issue which sometimes results in illegal cast exception.

4.3.0

  • Allow requesting location permissions when location services are disabled (on iOS this will redirect the user to the Location settings page);
  • Android: Add support for requesting Activity Recognition permissions;
  • Confirm to Effective Dart guidelines;
  • Documented all public API members;
  • Fixed several typos in the README.md.

4.2.0+hotfix.3

  • Android: Fixes a bug which in some cases caused the permission neverAskAgain to be returned incorrectly.

4.2.0+hotfix.2

  • Android: Fixes a bug where permissions are reported as neverAskAgain incorrectly after calling requestPermissions method.

4.2.0+hotfix.1

  • Android: Fixes a bug where permissions are reported as neverAskAgain incorrectly.

4.2.0

  • Android: Methods checkPermissionStatus and requestPermissions now support the additional neverAskAgain status.

4.1.0

  • iOS: Added option to exclude permissions logic using macros. This allows developers to submit their app to the AppStore without having to include all permissions in their Info.plist;
  • Android: Support ANSWER_PHONE_CALLS permission for API 26 and higher;
  • Android: Support ACCESS_MEDIA_LOCATION permission for API 26 and higher;
  • Android: Synchronized Gradle version with Flutter stable (1.12.13+hotfix.5).

4.0.0

  • iOS: Added support for requesting permissions on the DOCUMENTS and DOWNLOADS folder (thanks to @phranck);
  • Android: Fix the PROCESS_OUTGOING_CALLS permissions which have been deprecated in API 29.

3.3.0

  • Android: Add support for requesting the background location permission within the locationAlways group.
  • Android: Update AGP, Gradle, and AndroidX dependencies

3.2.2

  • Fixed problem with dependency on specific version of gradle wrapper on Android.

3.2.1+1

  • Reverted the update of the 'meta' plugin since Flutter SDK depends on version 1.1.6

3.2.1

  • Updated dependency on 'meta' to the latest version.

3.2.0

  • Add support for Androids' "ignore battery optimizations" permission;
  • Improve error logging;
  • Documented support for AndroidX.

3.1.0

  • Support service status inquiry for phone permission on iOS & Android.

3.0.2

  • Fixed bug when rapidly requesting permissions (#23);
  • Rename Enums.h to PermissionHandlerEnums.h to prevent conflicts with the geolocator (#104);
  • Update the Android permission request code to prevent conflicts with geolocator (#111);
  • Update Gradle infrastructure.

3.0.1

  • Mark the Swift pod as static

3.0.0

  • Converted the iOS version from Swift to Objective-C, reducing the size of the final binary considerably.

2.2.0

  • Added new method checkServiceStatus to allow users to check if the location services (on Android and iOS) and motion services (iOS only) are enabled;
  • When checking permission status (using checkPermissionStatus) return PermissionStatus.disabled when permissions are granted or denied and the location services (on Android and iOS) or the motion services (iOS only) are disabled.

2.1.3

  • Fixed bug on iOS where the result of the openAppSettings call always returned false;
  • Upgrade the Android plugin to support AndroidX and the latest Gradle and Kotlin versions;
  • Added Swift version number to the Podfile of the plugin;
  • Updated flutter static analyses to conform to the latest recommendations.

2.1.2

  • Make sure the Permission Handler compiles with the latest iOS SDK

2.1.1

  • Update to the latest version of Swift (4.2);
  • Make sure that the correct Swift version is set in the Podfile of consuming Apps;
  • Updated configuration for static code analyses, so it complies with the Flutter recommendations.

2.1.0

  • Added Android support to check if location services are enabled. If location services are not running the permission check returns PermissionStatus.DISABLED.

2.0.1

  • Fix bug with dependency on com.android.support:support-compat library
  • Update used Kotlin and Gradle versions

2.0.0

  • Make methods non-static so users can create an instance or override

1.0.1

  • Converted the plugin into a library so that developers don't have to import additional files;
  • Updated the README.md to fix the example code.

1.0.0

  • Initial release.

Installing

export PUB_HOSTED_URL=https://pub.mirror.p-hatan.com
flutter pub add 'permission_handler:13.0.2'
pubspec.yaml
name: permission_handler
description: Permission plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions.
repository: https://github.com/baseflow/flutter-permission-handler
issue_tracker: https://github.com/Baseflow/flutter-permission-handler/issues
version: 13.0.2

environment:
  sdk: ^3.6.0
  flutter: ">=3.24.0"
resolution: workspace

flutter:
  plugin:
    platforms:
      android:
        default_package: permission_handler_android
      ios:
        default_package: permission_handler_apple
      web:
        default_package: permission_handler_html
      windows:
        default_package: permission_handler_windows

dependencies:
  flutter:
    sdk: flutter
  meta: ^1.7.0
  permission_handler_android: ^14.1.0
  permission_handler_apple: ^9.5.0
  permission_handler_html: ^0.1.4+0
  permission_handler_windows: ^0.2.2
  permission_handler_platform_interface: ^4.4.0

dev_dependencies:
  flutter_lints: ^5.0.0
  flutter_test:
    sdk: flutter
  mockito: ^5.4.5
  plugin_platform_interface: ^2.0.0

Version history

VersionPublishedArchiveSHA-256
1.0.0On demandDownloadd48c2d18…ff308d
1.0.1On demandDownload814bf75e…784d54
2.0.0On demandDownloaded6ff6e5…c2a4d9
2.0.1On demandDownload31c76efe…b2f857
2.1.0On demandDownload29279b2b…a1df16
2.1.1On demandDownloada532d7c1…6f39e5
2.1.2On demandDownloadb21dbe8e…c9448f
2.1.3On demandDownload09f941d4…96617f
2.2.0On demandDownload4e89fed7…8c33ac
3.0.0On demandDownload2226abbb…2f6a2c
3.0.1On demandDownload32875deb…55ad09
3.0.2On demandDownload362c6d6f…a6f6d3
3.1.0On demandDownload108f0bd6…080ba8
3.2.0On demandDownload289d9979…9711a9
3.2.1On demandDownloadf7bf0f0c…10d1f6
3.2.1+1On demandDownload5897c997…74752c
3.2.2On demandDownload3ab824fe…64a226
3.3.0On demandDownloade5a26079…408b39
4.0.0On demandDownloade6d7237b…514762
4.1.0On demandDownload84230178…91e74e
4.2.0On demandDownload36a36572…46b20b
4.2.0+hotfix.1On demandDownload678d505e…c1896d
4.2.0+hotfix.2On demandDownload3b16f208…8a9199
4.2.0+hotfix.3On demandDownloadd438e91d…98d6a3
4.3.0On demandDownloaddadfaa50…35b221
4.4.0On demandDownloaddb14db6c…e74f4a
4.4.0+hotfix.1On demandDownload6d5ed509…e8a3f1
4.4.0+hotfix.2On demandDownload48b27ce3…c2fcd1
4.4.0+hotfix.3On demandDownloadfa593e4e…464e45
4.4.0+hotfix.4On demandDownload01bf998e…f1e461
5.0.0On demandDownloade502bcba…66c667
5.0.0+hotfix.1On demandDownload20f007e1…9fa1d8
5.0.0+hotfix.2On demandDownload4d693194…f080cb
5.0.0+hotfix.3On demandDownload77997818…92bf89
5.0.0+hotfix.4On demandDownload95f9ba7b…262428
5.0.0+hotfix.5On demandDownload6be17db2…16a6d1
5.0.0+hotfix.6On demandDownloada6e941d0…82a81a
5.0.0+hotfix.7On demandDownloadb3abf1f3…b40b94
5.0.0+hotfix.8On demandDownload05d2bfcf…6c5dd2
5.0.0+hotfix.9On demandDownloadc77088f9…588661
5.0.0+hotfix.10On demandDownload63def3e3…5ddb43
5.0.1On demandDownload1c2f4592…bf1da1
5.0.1+1On demandDownloadf9deef3b…51fb00
5.0.1+2On demandDownloadd29e3ffc…90dc64
5.1.0On demandDownloadcb74a941…81936f
5.1.0+1On demandDownload2839b5c2…43e45d
5.1.0+2On demandDownloadfb466608…5442b7
6.0.0On demandDownload7c008a35…d740d2
6.0.1On demandDownloadd2be34a0…a060bc
6.0.1+1On demandDownload77177973…c8edbd
6.1.0On demandDownloadbf8ce752…ee80ef
6.1.1On demandDownloada38db821…f8fdb4
6.1.3On demandDownload390a98f0…c2b720
7.0.0On demandDownload4412a3f9…21c958
7.1.0On demandDownloadea2e6e8b…0dd52d
7.2.0On demandDownloade968207c…cccf0a
8.0.0On demandDownload11686112…38c30b
8.0.0+1On demandDownloadcad6e77d…6baf66
8.0.0+2On demandDownloadabf730a2…c5eb1a
8.0.1On demandDownload2fd85d9f…6385c1
8.1.0On demandDownload3e69eebc…707d11
8.1.1On demandDownloade2c6c552…1e2040
8.1.2On demandDownload06ddb3f8…eb1ba6
8.1.3On demandDownload93f79b81…4078ba
8.1.4On demandDownloadebd8f2d5…3c4d48
8.1.4+1On demandDownload9db75d4c…092658
8.1.4+2On demandDownloada06e4ff1…9fcf2a
8.1.5On demandDownload5c3a27f2…8d7821
8.1.6On demandDownload807decc3…bd8d8d
8.2.0On demandDownload8e5cc4d0…6bc1b6
8.2.1On demandDownload153a3a04…4b1935
8.2.2On demandDownload5268617b…258423
8.2.4On demandDownload7a0766ed…5cae50
8.2.5On demandDownloade9618389…54cc65
8.2.6On demandDownloadb3f3a117…f64311
8.3.0On demandDownload4356882e…8b128d
9.0.1On demandDownload14c4f2b9…d86391
9.0.2On demandDownloaddf879207…6dbbf7
9.1.0On demandDownloade474a8b0…7100db
9.2.0On demandDownload5749ebeb…f6bbf3
10.0.0On demandDownloadae51809c…37fc9c
10.0.1On demandDownload4a0063f4…ee5577
10.0.2On demandDownload769cd7c9…51cf67
10.1.0On demandDownload551f8c33…d33524
10.2.0On demandDownload33c6a125…b8d6a8
10.2.1On demandDownload97c39c9c…8f09ff
10.3.0On demandDownload1b6b3e73…76c331
10.4.0On demandDownload2fd3a61a…28876c
10.4.1On demandDownload37fcc3c3…c2912d
10.4.2On demandDownload415af30b…04bcd6
10.4.3On demandDownload63e5216a…01af81
10.4.4On demandDownloadceb46041…95addb
10.4.5On demandDownloadbc56bfe9…94baa5
11.0.0On demandDownloadad65ba9a…aede70
11.0.1On demandDownload284a6617…4fcac8
11.1.0On demandDownload860c6b87…ff4f78
11.2.0On demandDownload45ff3fbc…2087d6
11.2.1On demandDownload3c84d49f…8ad4f9
11.3.0On demandDownload74e962b7…6bfe44
11.3.1On demandDownload18bf33f7…113ecb
11.4.0On demandDownload59adad72…5d7849
12.0.0On demandDownloade78d066c…f32c54
12.0.0+1On demandDownload2d070d86…77470f
12.0.1On demandDownloadbc917da3…1caae1
12.0.2On demandDownloadca045d03…864b98
12.0.3Cached · Upstream SHA-256 matchedDownloadfe54465b…4784f6
13.0.0On demandDownload06149cba…5ab7b5
13.0.1On demandDownloade7317eb2…302b30
13.0.2Cached · Upstream SHA-256 matchedDownloade6bcecad…544fbd

Dependencies

flutter { "sdk": "flutter" }

meta "^1.7.0"

permission_handler_android "^14.1.0"

permission_handler_apple "^9.5.0"

permission_handler_html "^0.1.4+0"

permission_handler_platform_interface "^4.4.0"

permission_handler_windows "^0.2.2"