flutter_permission_handler_plus 0.0.2 copy "flutter_permission_handler_plus: ^0.0.2" to clipboard
flutter_permission_handler_plus: ^0.0.2 copied to clipboard

An improved permission handler with better UX and automatic permission requests for iOS, Android, Windows, macOS, Linux, and Web.

flutter_permission_handler_plus #

Pub Version Pub Points Popularity License: MIT

An improved permission handler with better UX and automatic permission requests for Flutter applications.

๐ŸŒŸ Features #

  • Enhanced UX: Automatic rationale dialogs with customizable messages
  • Smart Retry Logic: Intelligent handling of permission denials with contextual guidance
  • Settings Integration: Seamless navigation to app settings for manual permission management
  • Batch Requests: Efficient multiple permission requests with improved user experience
  • Type Safety: Full Dart type safety with comprehensive error handling
  • Performance Optimized: Minimal overhead with efficient permission state caching
  • Platform Support: iOS 12.0+ and Android API 21+ (Android 5.0+)

๐Ÿš€ Key Improvements Over Standard Permission Handling #

Feature Standard Approach flutter_permission_handler_plus
Rationale Dialogs Manual implementation required โœ… Automatic with custom messages
Retry Logic Handle manually โœ… Smart retry with configurable attempts
Settings Navigation Complex setup โœ… One-click settings integration
User Guidance Basic status only โœ… Contextual guidance and explanations
Batch Requests Sequential requests โœ… Optimized parallel processing
Error Handling Generic exceptions โœ… Detailed, actionable error types

๐Ÿ“ฑ Supported Permissions #

Permission iOS Android Description
Camera โœ… โœ… Camera access for photos/videos
Microphone โœ… โœ… Microphone access for audio recording
Location (When in Use) โœ… โœ… Location access while app is active
Location (Always) โœ… โœ… Background location access
Photo Library โœ… โœ… Access to device photo gallery
Contacts โœ… โœ… Access to device contacts
Calendar โœ… โœ… Access to device calendar
Storage โœ… โœ… File system access
Notifications โœ… โœ… Push notification permissions

๐Ÿ“ฆ Installation #

Add this to your package's pubspec.yaml file:

dependencies:
  flutter_permission_handler_plus: ^0.0.2

Then run:

flutter pub get

๐Ÿ› ๏ธ Platform Setup #

Android #

Add the following permissions to your android/app/src/main/AndroidManifest.xml:

<!-- Required permissions -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />

<!-- For Android 13+ (API 33+) -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

iOS #

Add the following to your ios/Runner/Info.plist:

<dict>
    <!-- Camera Permission -->
    <key>NSCameraUsageDescription</key>
    <string>This app needs camera access to take photos and videos.</string>
    
    <!-- Microphone Permission -->
    <key>NSMicrophoneUsageDescription</key>
    <string>This app needs microphone access to record audio.</string>
    
    <!-- Location Permissions -->
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>This app needs location access to provide location-based features.</string>
    <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
    <string>This app needs location access to provide location-based features.</string>
    
    <!-- Photo Library Permission -->
    <key>NSPhotoLibraryUsageDescription</key>
    <string>This app needs access to photo library to select images.</string>
    
    <!-- Contacts Permission -->
    <key>NSContactsUsageDescription</key>
    <string>This app needs access to contacts to help you connect with friends.</string>
    
    <!-- Calendar Permission -->
    <key>NSCalendarsUsageDescription</key>
    <string>This app needs access to calendar to manage events.</string>
</dict>

๐ŸŽฏ Usage #

Basic Permission Request #

import 'package:flutter_permission_handler_plus/flutter_permission_handler_plus.dart';

// Simple permission request with automatic UX handling
final status = await PermissionHandlerPlus.instance.requestPermission(
  PermissionType.camera,
);

if (status.isGranted) {
  // Permission granted - proceed with camera functionality
  print('Camera permission granted!');
} else if (status.isPermanentlyDenied) {
  // User needs to enable permission in settings
  print('Please enable camera permission in settings');
}

Custom Configuration #

// Request permission with custom rationale and settings
final config = PermissionConfig(
  rationale: 'We need camera access to let you take profile photos.',
  rationaleTitle: 'Camera Permission Required',
  enableAutoRationale: true,
  enableSettingsRedirect: true,
  retryCount: 2,
  showPermissionIcon: true,
);

final status = await PermissionHandlerPlus.instance.requestPermission(
  PermissionType.camera,
  config: config,
);

Multiple Permissions #

// Request multiple permissions efficiently
final permissions = {
  PermissionType.camera: PermissionConfig(
    rationale: 'Camera access for taking photos',
  ),
  PermissionType.microphone: PermissionConfig(
    rationale: 'Microphone access for recording audio',
  ),
  PermissionType.photos: PermissionConfig(
    rationale: 'Photo library access for selecting images',
  ),
};

final statuses = await PermissionHandlerPlus.instance.requestPermissions(permissions);

// Check results
statuses.forEach((permission, status) {
  print('${permission.displayName}: ${status.description}');
});

Permission Status Checking #

// Check single permission status
final status = await PermissionHandlerPlus.instance.checkPermissionStatus(
  PermissionType.camera,
);

// Check multiple permission statuses
final statuses = await PermissionHandlerPlus.instance.checkPermissionStatuses([
  PermissionType.camera,
  PermissionType.microphone,
  PermissionType.photos,
]);

Settings Integration #

// Open app settings for manual permission management
final opened = await PermissionHandlerPlus.instance.openAppSettings();
if (opened) {
  print('Settings opened successfully');
}

Advanced Features #

// Check if rationale should be shown (Android)
final shouldShow = await PermissionHandlerPlus.instance
    .shouldShowRequestPermissionRationale(PermissionType.camera);

// Clear permission cache
PermissionHandlerPlus.instance.clearCache();

๐ŸŽจ Custom UI Integration #

class PermissionButton extends StatefulWidget {
  final PermissionType permission;
  final VoidCallback? onGranted;
  
  const PermissionButton({
    super.key,
    required this.permission,
    this.onGranted,
  });

  @override
  State<PermissionButton> createState() => _PermissionButtonState();
}

class _PermissionButtonState extends State<PermissionButton> {
  PermissionStatus _status = PermissionStatus.undetermined;
  bool _isLoading = false;

  @override
  void initState() {
    super.initState();
    _checkStatus();
  }

  Future<void> _checkStatus() async {
    final status = await PermissionHandlerPlus.instance
        .checkPermissionStatus(widget.permission);
    setState(() {
      _status = status;
    });
  }

  Future<void> _requestPermission() async {
    setState(() {
      _isLoading = true;
    });

    try {
      final status = await PermissionHandlerPlus.instance.requestPermission(
        widget.permission,
        config: PermissionConfig(
          rationale: 'This feature requires ${widget.permission.displayName} access.',
        ),
      );

      setState(() {
        _status = status;
      });

      if (status.isGranted) {
        widget.onGranted?.call();
      }
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton.icon(
      onPressed: _isLoading || _status.isGranted ? null : _requestPermission,
      icon: _isLoading 
          ? const SizedBox(
              width: 16,
              height: 16,
              child: CircularProgressIndicator(strokeWidth: 2),
            )
          : Icon(_getStatusIcon()),
      label: Text(_getButtonText()),
      style: ElevatedButton.styleFrom(
        backgroundColor: _getButtonColor(),
      ),
    );
  }

  IconData _getStatusIcon() {
    if (_status.isGranted) return Icons.check;
    if (_status.isPermanentlyDenied) return Icons.settings;
    return Icons.security;
  }

  String _getButtonText() {
    if (_status.isGranted) return 'Granted';
    if (_status.isPermanentlyDenied) return 'Open Settings';
    return 'Grant ${widget.permission.displayName}';
  }

  Color _getButtonColor() {
    if (_status.isGranted) return Colors.green;
    if (_status.isPermanentlyDenied) return Colors.orange;
    return Colors.blue;
  }
}

๐Ÿ—๏ธ Architecture #

The plugin follows a clean architecture pattern:

lib/
โ”œโ”€โ”€ flutter_permission_handler_plus.dart     # Main export file
โ””โ”€โ”€ src/
    โ”œโ”€โ”€ permission_handler_plus.dart         # Core permission handler
    โ”œโ”€โ”€ permission_type.dart                 # Permission enumeration
    โ”œโ”€โ”€ permission_status.dart               # Status enumeration  
    โ”œโ”€โ”€ permission_config.dart               # Configuration class
    โ””โ”€โ”€ exceptions.dart                      # Custom exceptions

๐Ÿ”ง Configuration Options #

PermissionConfig #

Property Type Default Description
rationale String? null Custom rationale message
rationaleTitle String? null Custom rationale dialog title
enableAutoRationale bool true Auto-show rationale dialogs
enableSettingsRedirect bool true Enable settings navigation
settingsRedirectMessage String? null Custom settings dialog message
settingsRedirectTitle String? null Custom settings dialog title
retryCount int 2 Maximum retry attempts
showPermissionIcon bool true Show permission icons in dialogs

๐Ÿงช Testing #

import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_permission_handler_plus/flutter_permission_handler_plus.dart';

void main() {
  group('PermissionHandlerPlus', () {
    test('should return granted status for granted permission', () async {
      // Mock test implementation
      final handler = PermissionHandlerPlus.instance;
      
      // Test permission request
      final status = await handler.requestPermission(PermissionType.camera);
      
      expect(status, isA<PermissionStatus>());
    });
  });
}

๐Ÿค Contributing #

Contributions are welcome! Please read our Contributing Guide for details on our code of conduct and the process for submitting pull requests.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

๐Ÿ“„ License #

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ™ Acknowledgments #

  • Flutter team for the excellent framework
  • Contributors to permission_handler for inspiration
  • The Flutter community for feedback and suggestions

๐Ÿ“ž Support #

๐Ÿ”„ Migration Guide #

From permission_handler #

// Old way (permission_handler)
import 'package:permission_handler/permission_handler.dart';

var status = await Permission.camera.request();

// New way (flutter_permission_handler_plus)
import 'package:flutter_permission_handler_plus/flutter_permission_handler_plus.dart';

final status = await PermissionHandlerPlus.instance.requestPermission(
  PermissionType.camera,
  config: PermissionConfig(
    rationale: 'We need camera access for photos',
    enableAutoRationale: true,
  ),
);

Made with โค๏ธ by Dhia Bechattaoui

1
likes
160
points
146
downloads

Publisher

verified publisherbechattaoui.dev

Weekly Downloads

An improved permission handler with better UX and automatic permission requests for iOS, Android, Windows, macOS, Linux, and Web.

Repository (GitHub)
View/report issues
Contributing

Topics

#permissions #flutter #plugin #android #ios

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

flutter, flutter_web_plugins, plugin_platform_interface

More

Packages that depend on flutter_permission_handler_plus

Packages that implement flutter_permission_handler_plus