A permissions plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions.
On most OSes, permissions aren't just granted to apps at install time.
Rather, developers have to ask users for permissions during runtime.
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 a permission.
On Android, you can show a rationale for requesting a permission.
## 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.
<details>
<summary>Android</summary>
## Features
<details>
<summary>
The current version of the plugin requires AndroidX.
</summary>
* Check if a permission is granted.
As of version 3.1.0 the <kbd>permission_handler</kbd> 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](https://flutter.dev/docs/development/packages-and-plugins/androidx-compatibility).
* Request permission for a specific feature.
* Open app settings so the user can enable a permission.
* Show a rationale for requesting permission (Android).
## Usage
The TL;DR version is:
To use this plugin, add `permission_handler` as a [dependency in your pubspec.yaml file](https://flutter.io/platform-plugins/). For example:
1. Add the following to your "gradle.properties" file:
```
android.useAndroidX=true
android.enableJetifier=true
```
2. Make sure you set the `compileSdkVersion` in your "android/app/build.gradle" file to 28:
```
android {
compileSdkVersion 28
```yaml
...
dependencies:
}
permission_handler:'^4.4.0'
```
```
3. Make sure you replace all the `android.` dependencies to their AndroidX counterparts (a full list can be found here: https://developer.android.com/jetpack/androidx/migrate).
</details>
Add permissions to your `AndroidManifest.xml` file.
There's a `debug`, `main` and `profile` version which are chosen depending on how you start your app.
In general, it's sufficient to add permission only to the `main` version.
[Here]((https://github.com/Baseflow/flutter-permission-handler/blob/develop/example/android/app/src/main/AndroidManifest.xml))'s an example `AndroidManifest.xml` with a complete list of all possible permissions.
</details>
<details>
<summary>iOS</summary>
> **NOTE:** 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](https://flutter.dev/docs/development/packages-and-plugins/androidx-compatibility).
Add permission to your `Info.plist` file.
>
[Here](https://github.com/Baseflow/flutter-permission-handler/blob/develop/example/ios/Runner/Info.plist)'s an example `Info.plist` with a complete list of all possible permissions.
>The TL;DR version is:
>
>1. Add the following to your "gradle.properties" file:
>
>```
>android.useAndroidX=true
>android.enableJetifier=true
>```
>2. Make sure you set the `compileSdkVersion` in your "android/app/build.gradle" file to 28:
>
>```
>android {
> compileSdkVersion 28
>
> ...
>}
>```
>3. Make sure you replace all the `android.` dependencies to their AndroidX counterparts (a full list can be found here: https://developer.android.com/jetpack/androidx/migrate).
### Android and iOS specific permissions
For this plugin to work you will have to add permission configuration to your `AndroidManifest.xml` (Android) and `Info.plist` (iOS) files. This will tell the platform which hardware or software features your app needs. Complete lists of these permission options can be found in our example app here:
-[AndroidManifest.xml](https://github.com/Baseflow/flutter-permission-handler/blob/develop/example/android/app/src/main/AndroidManifest.xml)(note that there is a debug, main and profile version which are used depending on how you start your App. In general it is sufficient to add permissions only to the `main` version);
> IMPORTANT: ~~On iOS 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 analyser (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](https://github.com/BaseflowIT/flutter-permission-handler/issues/26).
On iOS, the permission_handler plugin use [macros](https://github.com/BaseflowIT/flutter-permission-handler/blob/develop/ios/Classes/PermissionHandlerEnums.h) to control whether a permission is supported.
> 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 analyser (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](https://github.com/BaseflowIT/flutter-permission-handler/issues/26).
The <kbd>permission_handler</kbd> plugin use [macros](https://github.com/BaseflowIT/flutter-permission-handler/blob/develop/ios/Classes/PermissionHandlerEnums.h) to control whether a permission is supported.
By default, all the permissions listed [here](https://github.com/Baseflow/flutter-permission-handler#list-of-available-permissions) are supported.
By default, all the permissions listed [here](https://github.com/Baseflow/flutter-permission-handler#list-of-available-permissions) are supported.
You can remove permissions you don't use by:
You can remove permissions you don't use:
> 1. Add the following to your `Podfile` file:
>
> ```ruby
> post_install do |installer|
> installer.pods_project.targets.each do |target|
> target.build_configurations.each do |config|
> ... # Here are some configurations automatically generated by flutter
>
> # You can remove unused permissions here
> # for more infomation: https://github.com/BaseflowIT/flutter-permission-handler/blob/develop/ios/Classes/PermissionHandlerEnums.h
> # e.g. when you don't need camera permission, just add 'PERMISSION_CAMERA=0'
Checking the service status only makes sense for the `PermissionGroup.location` on Android and the `PermissionGroup.location`, `PermissionGroup.locationWhenInUse`, `PermissionGroup.locationAlways` or `PermissionGroup.sensors` on iOS. All other permission groups are not backed by a separate service and will always return `ServiceStatus.notApplicable`.
Defines the permission groups for which permissions can be checked or requested.
There are a number of [`Permission`](https://pub.dev/documentation/permission_handler_platform_interface/latest/permission_handler_platform_interface/PermissionGroup-class.html)s.
You can get a `Permission`'s `status`, which is either `undetermined`, `granted`, `denied`, `restricted` or `permanentlyDenied`.
```dart
```dart
enumPermissionGroup{
var status = await Permission.camera.status;
/// The unknown permission only used for return type, never requested
if (status.isUndetermined) {
unknown,
// We didn't ask for permission yet.
/// Android: Calendar
/// iOS: Calendar (Events)
calendar,
/// Android: Camera
/// iOS: Photos (Camera Roll and Camera)
camera,
/// Android: Contacts
/// iOS: AddressBook
contacts,
/// Android: Fine and Coarse Location
/// iOS: CoreLocation (Always and WhenInUse)
location,
/// Android: Microphone
/// iOS: Microphone
microphone,
/// Android: Phone
/// iOS: Nothing
phone,
/// Android: Nothing
/// iOS: Photos
photos,
/// Android: Nothing
/// iOS: Reminders
reminders,
/// Android: Body Sensors
/// iOS: CoreMotion
sensors,
/// Android: Sms
/// iOS: Nothing
sms,
/// Android: External Storage
/// iOS: Nothing
storage,
/// Android: Microphone
/// iOS: Speech
speech,
/// Android: Fine and Coarse Location
/// iOS: CoreLocation - Always
locationAlways,
/// Android: Fine and Coarse Location
/// iOS: CoreLocation - WhenInUse
locationWhenInUse,
/// Android: None
/// iOS: MPMediaLibrary
mediaLibrary,
/// Android: Check notification enable
/// iOS: Check and request notification permission
notification,
/// Android Q: Check and request permissions to read from the media location (ACCESS_MEDIA_LOCATION)
/// Android pre-Q: Nothing
/// iOS: Nothing
accessMediaLocation,
/// Android Q: Check and request permissions to access the Activity Recognition API
/// Android pre-Q: Nothing
/// iOS: Nothing (should implement access to CMMotionActivity, see issue #219)
activityRecognition,
}
}
```
### Status of the permission
// You can can also directly ask the permission about its status.
if (await Permission.location.isRestricted) {
// The OS restricts access, for example because of parental controls.
}
```
Defines the state of a permission group
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`.
```dart
```dart
enumPermissionStatus{
if (await Permission.contacts.request().isGranted) {
/// Permission to access the requested feature is denied by the user.
// Either the permission was granted before or the user just granted it.
denied,
}
/// Permission to access the requested feature is granted by the user.
granted,
/// The user granted restricted access to the requested feature (only on iOS).
// You can request multiple permissions at once.
restricted,
Map<Permission,PermissionStatus> statuses = [
Permission.location,
Permission.storage,
].request();
print(statuses[Permission.location]);
```
/// Permission is in an unknown state
All location permissions and the `Permission.sensor` have an associated service, which also has a status.
unknown
/// Permission to access the requested feature is denied by the user and never show selected (only on Android).
```dart
neverAskAgain
if (await Permission.location.serviceStatus.isEnabled) {
// Use location.
}
}
```
```
### Overview of possible service statuses
You can also open the app settings:
Defines the state of the backing service for the supplied permission group
```dart
```dart
/// Defines the state of a service related to the permission group
if (await Permission.speech.isPermanentlyDenied) {
enumServiceStatus{
openAppSettings();
/// The unknown service status indicates the state of the service could not be determined.
}
unknown,
```
/// There is no service for the supplied permission group.
notApplicable,
/// The service for the supplied permission group is disabled.
On Android, you can also show a rationale for using a permission:
disabled,
/// The service for the supplied permission group is enabled.