Handling Permissions in Flutter with Delegation pattern

Hello There!
In this short tutorial, we will implement realistic permission management in Flutter with the delegation pattern.
Mixins
allow us to add functionality to Dart classes and reuse their code in different class hierarchies.
Step 1:
Add permission_handler to your project. Run this command:
$ flutter pub add permission_handler
Do follow the steps to add the permissions you need for android and ios listed here
Step 2:
Create a permission manager mixin
mixin PermissionManagerMixin {
void onPermissionGranted(Permission permission);
void onPermissionDenied(Permission permission);
void onPermissionPermanentlyDenied(Permission permission);
void updateStatus(permission, PermissionStatus status,{required bool checkDenied}) {}
void requestPermission(Permission permission) async {}
}
Step 3:
Add implementation for requestPermission
and updateStatus
functions.
void updateStatus(permission, PermissionStatus status, {required bool checkDenied}) {
if (status.isPermanentlyDenied || status.isRestricted) {
onPermissionPermanentlyDenied(permission);
}
if (status.isGranted || status.isLimited) {
onPermissionGranted(permission);
}
if (checkDenied && status.isDenied) {
onPermissionDenied(permission);
}
}void requestPermission(Permission permission) async {
final status = await permission.status;
updateStatus(permission, status, checkDenied: false);
if (status == PermissionStatus.denied) {
final newStatus = await permission.request();
updateStatus(permission, newStatus, checkDenied: true);
}
}
Note: For the purpose of this tutorial, we treat permanently denied and restricted the same way, you may need to treat them differently. The same goes for granted and limited cases.
Step 4:
Simply use it in your widgets.
import 'package:flutter/material.dart';
import '../../utils/permission_manager_mixin.dart';
import '../../utils/snackbar_utils.dart';
class PermissionTab extends StatefulWidget {
const PermissionTab({Key? key}) : super(key: key);
@override
State<PermissionTab> createState() => _PermissionTabState();
}
class _PermissionTabState extends State<PermissionTab>
with PermissionManagerMixin {
@override
Widget build(BuildContext context) {
return Column(
children: [
ElevatedButton(
onPressed: () {
requestPermission(Permission.camera);
},
child: const Text("Request camera permission"),
),
ElevatedButton(
onPressed: () {
requestPermission(Permission.sms);
},
child: const Text("Request SMS permission"),
),
],
);
}
@override
void onPermissionDenied(Permission permission) {
print("$permission Permission Denied");
}
@override
void onPermissionGranted(Permission permission) {
print("$permission Permission Granted");
}
@override
void onPermissionPermanentlyDenied(Permission permission) {
print("$permission Permission Permanently Denied");
}
}
And you’re done!
Can I get a few claps, please?
Love clean code? Please have a look at my other articles: