How to handle permissions in Flutter
Managing permissions is an important part of developing mobile applications. It ensures that applications can use necessary device features while also respecting user privacy. In this post, we will explore how to effectively manage permissions in Flutter using the permission_handler package. We will cover the installation process, configuration for Android and iOS platforms, and the implementation of permission requests. By the end of this post, you will have the knowledge and tools to handle permissions in your Flutter applications.
Installing
To get started, we need to install the permission_handler package into our project. The installation process is simple. Just execute the following command: flutter pub add permission_handler
.
Once the command is executed, make sure to check your pubspec.yaml
file for the added dependencies. You should see the permission_handler package included in the dependencies section, like this:
dependencies:
flutter:
sdk: flutter
permission_handler: ^10.4.3
Android
In Android, to access specific permissions, you need to add an entry in the AndroidManifest.xml
file. For example, to access the location, you would add the following code:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
You can find documentation for all the permissions in Android here.
Additionally, make sure to check your android/gradle.properties file and ensure it contains the following entries:
android.useAndroidX=true
android.enableJetifier=true
At last, set the compileSdkVersion
in your android/app/build.gradle
file to 33
:
android {
namespace "com.example.codeonwards_demo"
compileSdkVersion 33
...
}
iOS
In iOS, you need to add the location permission to the ios/Runner/info.plist
file. Here is an example of how to add permission for the location:
<plist version="1.0">
<dict>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This application needs access to the location</string>
...
</dict>
</plist>
Ensure that the key between the <key>
tags remains exactly the same. However, feel free to modify the description between the <string>
tags. This description will be displayed to the user when requesting location access.
Unfortunately, I do not have access to an iOS device for testing, so I recommend checking the package's documentation if you run into issues on iOS devices.
Asking location permissions
In the code snippet below we will create a simple Flutter application that demonstrates how to use the permission_handler package to request location permissions. It consists out of two classes: MyApp
and HomePage
.
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
void _requestLocationPermission(BuildContext context) async {
PermissionStatus status = await Permission.location.request();
switch (status) {
case PermissionStatus.granted:
_showSnackBar(context, 'Permission granted', Colors.green);
case PermissionStatus.denied:
_showSnackBar(context, 'Permission denied', Colors.amber);
case PermissionStatus.permanentlyDenied:
_showSnackBar(context, 'Permanently denied', Colors.redAccent);
default:
_showSnackBar(context, 'Something went wrong', Colors.red);
}
}
void _showSnackBar(BuildContext context, String text, Color color) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(text, textAlign: TextAlign.center),
backgroundColor: color,
));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Requesting Permission Example'),
),
body: Center(
child: ElevatedButton(
style: ElevatedButton.styleFrom(minimumSize: Size(200, 50)),
onPressed: () => _requestLocationPermission(context),
child: Text(
'Request Location Permission',
style: TextStyle(fontSize: 20),
),
),
),
);
}
}
In this code snippet, the MyApp
widget, returns a MaterialApp
which has the HomePage
set as the initial home page. The HomePage
class contains a Scaffold
widget and a centered ElevatedButton
with the text "Request Location Permission".
When the button is pressed, the _requestLocationPermission
function is called. This function is responsible for requesting location permissions using the permission_handler package. It uses the await
keyword to wait for the permission request to complete and stores the result in a variable called status
, which is of type PermissionStatus
.
Based on the permission status, the application shows a SnackBar
widget at the bottom of the screen using the _showSnackBar
function. The SnackBar provides feedback to the user with different colors and messages depending on the permission status. For example, if the location permission is granted, an informative green SnackBar
widget displays "Permission granted

User's device settings
To improve our application's functionality, we can use the openAppSettings
function, which allows users to access the application's permissions settings directly. This way, if a user for example, accidentally denies permission, clicking on the button will open the settings, providing them with the opportunity to review and modify their decision.
void _requestLocationPermission(BuildContext context) async {
PermissionStatus status = await Permission.location.request();
switch (status) {
case PermissionStatus.granted:
_showSnackBar(context, 'Permission granted', Colors.green);
case PermissionStatus.denied:
_showSnackBar(context, 'Permission denied', Colors.amber);
openAppSettings();
case PermissionStatus.permanentlyDenied:
_showSnackBar(context, 'Permanently denied', Colors.redAccent);
openAppSettings();
default:
_showSnackBar(context, 'Something went wrong', Colors.red);
}
}
In the updated _requestLocationPermission
function, we have modified the denied cases to call the openAppSettings
function. Now, when the user denies permission, the app will automatically open the device's settings, offering users to adjust their permission preferences.

Conclusion
In this post, we have explored how to handle permissions in Flutter using the permission_handler package. We started by installing the package and configuring permissions for both Android and iOS platforms. The implementation of the permission request was demonstrated through a simple application that requests location permissions when a button is pressed. With this knowledge, you can now effectively manage permissions in your Flutter applications.