Permission Master Flutter Plugin
Overview
Permission Master is a comprehensive Flutter plugin designed to simplify permission management across iOS and Android platforms. It provides an intuitive and easy-to-use interface for requesting and checking various system permissions while ensuring a smooth user experience.
Key Features
- Simplified permission request methods
- Granular permission control
- Context-aware permission dialogs
- Platform-agnostic API
- Built-in storage for permission states
- No manual
AndroidManifest.xml
configuration required
iOS platform requirement (iOS 12.0 and above) Supported platform Android (5.0 to 15)
Installation
Add to your pubspec.yaml
:
dependencies:
permission_master: ^0.0.5
Or install directly from GitHub:
dependencies:
permission_master:
git:
url: https://github.com/SwanFlutter/permission_master.git
Setup and Initialization
1. Import the Package
import 'package:permission_master/permission_master.dart';
2. Set BuildContext (Important for Dialogs)
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
// Set context for dialog support
PermissionMaster.setContext(context);
}
}
Comprehensive Permission Methods
1. Camera Permission
Future<void> requestCameraAccess() async {
final permissionMaster = PermissionMaster();
final status = await permissionMaster.requestCameraPermission();
if (status == PermissionStatus.granted) {
// Camera access allowed
// Proceed with camera-related functionality
} else if (status == PermissionStatus.openSettings) {
// Permanent denial, suggest opening app settings
await permissionMaster.openAppSettings();
} else {
// Handle camera permission denial
}
}
2. Location Permission
Future<void> requestLocationAccess() async {
final permissionMaster = PermissionMaster();
final status = await permissionMaster.requestLocationPermission();
switch (status) {
case PermissionStatus.granted:
// Location access allowed
// Start location services
break;
case PermissionStatus.denied:
// User rejected location permission
break;
case PermissionStatus.openSettings:
// Permanent denial, suggest opening app settings
await permissionMaster.openAppSettings();
break;
default:
// Handle error requesting location permission
}
}
3. Storage Permission
Future<void> requestStorageAccess() async {
final permissionMaster = PermissionMaster();
final status = await permissionMaster.requestStoragePermission();
if (status == PermissionStatus.granted) {
// Read/write files allowed
} else if (status == PermissionStatus.openSettings) {
// Permanent denial, suggest opening app settings
await permissionMaster.openAppSettings();
} else {
// Handle storage permission denial
}
}
4. Microphone Permission
Future<void> requestMicrophoneAccess() async {
final permissionMaster = PermissionMaster();
final status = await permissionMaster.requestMicrophonePermission();
if (status == PermissionStatus.granted) {
// Start audio recording
} else if (status == PermissionStatus.openSettings) {
// Permanent denial, suggest opening app settings
await permissionMaster.openAppSettings();
} else {
// Handle microphone access denial
}
}
5. Bluetooth Permission
Future<void> requestBluetoothAccess() async {
final permissionMaster = PermissionMaster();
final status = await permissionMaster.requestBluetoothPermission();
if (status == PermissionStatus.granted) {
// Enable Bluetooth functionality
} else if (status == PermissionStatus.openSettings) {
// Permanent denial, suggest opening app settings
await permissionMaster.openAppSettings();
} else {
print('Bluetooth permission denied');
}
}
6. Contacts Permission
Future<void> requestContactsAccess() async {
final permissionMaster = PermissionMaster();
final status = await permissionMaster.requestContactsPermission();
if (status == PermissionStatus.granted) {
// Access contacts
} else if (status == PermissionStatus.openSettings) {
// Permanent denial, suggest opening app settings
await permissionMaster.openAppSettings();
} else {
print('Contacts permission denied');
}
}
7. Notifications Permission
Future<void> requestNotificationsAccess() async {
final permissionMaster = PermissionMaster();
final status = await permissionMaster.requestNotificationPermission();
if (status == PermissionStatus.granted) {
// Send notifications
} else if (status == PermissionStatus.openSettings) {
// Permanent denial, suggest opening app settings
await permissionMaster.openAppSettings();
} else {
print('Notifications permission denied');
}
}
8. SMS Permission
Future<void> requestSmsAccess() async {
final permissionMaster = PermissionMaster();
final status = await permissionMaster.requestSmsPermission();
if (status == PermissionStatus.granted) {
// Access SMS
} else if (status == PermissionStatus.openSettings) {
// Permanent denial, suggest opening app settings
await permissionMaster.openAppSettings();
} else {
print('SMS permission denied');
}
}
9. Calendar Permission
Future<void> requestCalendarAccess() async {
final permissionMaster = PermissionMaster();
final status = await permissionMaster.requestCalendarPermission();
if (status == PermissionStatus.granted) {
// Access calendar
} else if (status == PermissionStatus.openSettings) {
// Permanent denial, suggest opening app settings
await permissionMaster.openAppSettings();
} else {
print('Calendar permission denied');
}
}
10. Phone Permission
Future<void> requestPhoneAccess() async {
final permissionMaster = PermissionMaster();
final status = await permissionMaster.requestPhonePermission();
if (status == PermissionStatus.granted) {
// Access phone features
} else if (status == PermissionStatus.openSettings) {
// Permanent denial, suggest opening app settings
await permissionMaster.openAppSettings();
} else {
print('Phone permission denied');
}
}
11. Activity Recognition Permission
Future<void> requestActivityRecognitionAccess() async {
final permissionMaster = PermissionMaster();
final status = await permissionMaster.requestActivityRecognitionPermission();
if (status == PermissionStatus.granted) {
// Access activity recognition
} else if (status == PermissionStatus.openSettings) {
// Permanent denial, suggest opening app settings
await permissionMaster.openAppSettings();
} else {
print('Activity recognition permission denied');
}
}
12. Nearby Devices Permission
Future<void> requestNearbyDevicesAccess() async {
final permissionMaster = PermissionMaster();
final status = await permissionMaster.requestNearbyDevicesPermission();
if (status == PermissionStatus.granted) {
// Access nearby devices
} else if (status == PermissionStatus.openSettings) {
// Permanent denial, suggest opening app settings
await permissionMaster.openAppSettings();
} else {
print('Nearby devices permission denied');
}
}
13. Multiple Permission Checking
Future<void> checkMultiplePermissions() async {
final permissionMaster = PermissionMaster();
final statuses = await permissionMaster.checkMultiplePermissions([
PermissionType.camera,
PermissionType.location,
PermissionType.microphone
]);
statuses.forEach((permission, status) {
print('$permission status: $status');
if (status == PermissionStatus.openSettings) {
// Suggest opening app settings for permanently denied permissions
permissionMaster.openAppSettings();
}
});
}
14. Open App Settings
Future<void> openAppPermissionSettings() async {
final permissionMaster = PermissionMaster();
await permissionMaster.openAppSettings();
}
Custom Permission For Use UI
ElevatedButton(
onPressed: () async {
await permissionMaster.grantedRequestPermission(PermissionType.camera);
},
child: Text('Request Camera Permission'),
)
ElevatedButton(
onPressed: () async {
await permissionMaster.denyRequestPermission(permission: PermissionType.camera);
Navigator.pop(context);
},
child: Text('Deny Camera Permission'),
)
ElevatedButton(
onPressed: () async {
await permissionMaster.openAppSettingsDirectly();
},
child: Text("Open App Settings"),
)
Get Platform Version
- Example
String? platformVersion;
Text("$platformVersion", style: TextStyle(fontSize: 24.0)),
// Android 13
ElevatedButton(
onPressed: () async {
String version = (await permissionMaster.getPlatformVersion())!;
setState(() {
platformVersion = version;
});
},
child: Text("Get platform version"),
)
Supported Permissions
Permission Type | Android | iOS |
---|---|---|
Camera | ✅ | ✅ |
Location | ✅ | ✅ |
Storage | ✅ | ✅ |
Microphone | ✅ | ✅ |
Bluetooth | ✅ | ✅ |
Contacts | ✅ | ✅ |
Notifications | ✅ | ✅ |
SMS | ✅ | ❌ |
Calendar | ✅ | ✅ |
Phone | ✅ | ❌ |
Activity Recognition | ✅ | ✅ |
Nearby Devices | ✅ | ✅ |
Best Practices
- Always check permission status before performing sensitive operations.
- Provide clear rationales for why permissions are needed.
- Gracefully handle permission denials.
- Use
openAppSettings()
for permanent denials. - Use
checkMultiplePermissions()
to handle multiple permissions at once.
Error Handling
The plugin returns different status enums:
PermissionStatus.granted
: Permission successfully obtained.PermissionStatus.denied
: Permission rejected by the user.PermissionStatus.openSettings
: Permanent denial, suggest manual settings.PermissionStatus.error
: An error occurred during the permission request.
Built-in Storage
Permission Master comes with a built-in storage system (GetStorageBridge
) that allows you to persist permission states and other data across app sessions. This is particularly useful for tracking permission request history and user preferences.
Basic Storage Operations
// Import the storage bridge
import 'package:permission_master/src/get_storage_bridge.dart';
// Create a storage instance
final storage = GetStorageBridge();
// Write a value
await storage.write('myKey', 'myValue');
// Read a value with a default fallback
final value = await storage.read('myKey', 'defaultValue');
// Check if a key exists
final exists = await storage.contains('myKey');
// Remove a key
await storage.remove('myKey');
// Clear all stored data
await storage.clear();
Storing Permission Data
Future<void> trackPermissionRequest(PermissionType permission, PermissionStatus status) async {
final storage = GetStorageBridge();
// Store the permission status
await storage.write('permission_${permission.value}_status', status.toString());
// Store the timestamp of the request
await storage.write(
'permission_${permission.value}_last_request_time',
DateTime.now().millisecondsSinceEpoch,
);
// Increment the request count
int requestCount = await storage.read(
'permission_${permission.value}_request_count',
0,
);
await storage.write(
'permission_${permission.value}_request_count',
requestCount + 1,
);
// Store additional data if needed
if (status == PermissionStatus.denied) {
await storage.write(
'permission_${permission.value}_denied_count',
(await storage.read('permission_${permission.value}_denied_count', 0)) + 1,
);
}
}
Additional information
If you have any issues, questions, or suggestions related to this package, please feel free to contact us at swan.dev1993@gmail.com. We welcome your feedback and will do our best to address any problems or provide assistance. For more information about this package, you can also visit our GitHub repository where you can find additional resources, contribute to the package's development, and file issues or bug reports. We appreciate your contributions and feedback, and we aim to make this package as useful as possible for our users. Thank you for using our package, and we look forward to hearing from you!