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

An improved permission handler with better UX and automatic permission requests. Provides a simplified API for handling permissions across iOS and Android platforms.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_permission_handler_plus/flutter_permission_handler_plus.dart';

void main() {
  runApp(const PermissionHandlerPlusExampleApp());
}

/// Example app demonstrating flutter_permission_handler_plus features.
class PermissionHandlerPlusExampleApp extends StatelessWidget {
  /// Creates the example app.
  const PermissionHandlerPlusExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Permission Handler Plus Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const PermissionDemoPage(),
    );
  }
}

/// Main page demonstrating permission requests with enhanced UX.
class PermissionDemoPage extends StatefulWidget {
  /// Creates the permission demo page.
  const PermissionDemoPage({super.key});

  @override
  State<PermissionDemoPage> createState() => _PermissionDemoPageState();
}

class _PermissionDemoPageState extends State<PermissionDemoPage> {
  final Map<PermissionType, PermissionStatus> _permissionStatuses = {};
  final PermissionHandlerPlus _permissionHandler =
      PermissionHandlerPlus.instance;
  bool _isLoading = false;

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

  /// Checks the status of all supported permissions.
  Future<void> _checkAllPermissions() async {
    setState(() {
      _isLoading = true;
    });

    try {
      final statuses = await _permissionHandler.checkPermissionStatuses(
        PermissionType.values,
      );

      setState(() {
        _permissionStatuses.addAll(statuses);
      });
    } catch (e) {
      _showErrorSnackBar('Failed to check permissions: $e');
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  /// Requests a single permission with custom configuration.
  Future<void> _requestPermission(PermissionType permission) async {
    setState(() {
      _isLoading = true;
    });

    try {
      final config = PermissionConfig(
        rationale: _getCustomRationale(permission),
      );

      final status = await _permissionHandler.requestPermission(
        permission,
        config: config,
      );

      setState(() {
        _permissionStatuses[permission] = status;
      });

      _showStatusSnackBar(permission, status);
    } catch (e) {
      _showErrorSnackBar('Failed to request ${permission.displayName}: $e');
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  /// Requests multiple permissions simultaneously.
  Future<void> _requestMultiplePermissions() async {
    setState(() {
      _isLoading = true;
    });

    try {
      final permissions = {
        PermissionType.camera: const PermissionConfig(
          rationale: 'We need camera access to take photos for your profile.',
        ),
        PermissionType.microphone: const PermissionConfig(
          rationale: 'We need microphone access to record voice messages.',
        ),
        PermissionType.photos: const PermissionConfig(
          rationale: 'We need photo access to select images from your gallery.',
        ),
      };

      final statuses = await _permissionHandler.requestPermissions(permissions);

      setState(() {
        _permissionStatuses.addAll(statuses);
      });

      _showMultipleStatusSnackBar(statuses);
    } catch (e) {
      _showErrorSnackBar('Failed to request multiple permissions: $e');
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  /// Opens app settings for manual permission management.
  Future<void> _openAppSettings() async {
    final opened = await _permissionHandler.openAppSettings();
    if (opened) {
      _showSuccessSnackBar('Settings opened successfully');
      // Refresh permissions after user returns from settings
      await Future<void>.delayed(const Duration(seconds: 1));
      await _checkAllPermissions();
    } else {
      _showErrorSnackBar('Failed to open app settings');
    }
  }

  /// Gets custom rationale message for a permission.
  String _getCustomRationale(PermissionType permission) {
    switch (permission) {
      case PermissionType.camera:
        return 'This example app demonstrates camera permission with enhanced UX. '
            'Camera access allows you to take photos directly within the app.';
      case PermissionType.microphone:
        return 'This example shows how microphone permission requests work with '
            'automatic rationale dialogs and smart retry logic.';
      case PermissionType.locationWhenInUse:
        return 'Location permission demo with improved user experience. '
            'This allows the app to access your location while in use.';
      case PermissionType.locationAlways:
        return 'Background location access demo with clear explanation of why '
            'this sensitive permission is needed.';
      case PermissionType.photos:
        return 'Photo library access demonstration with better UX flow. '
            'This allows selecting images from your gallery.';
      case PermissionType.contacts:
        return 'Contacts permission example showing how to request access '
            'to your contact list with clear rationale.';
      case PermissionType.calendar:
        return 'Calendar permission demo with enhanced user experience. '
            'This allows the app to read and write calendar events.';
      case PermissionType.storage:
        return 'Storage permission demonstration showing file access '
            'with improved permission flow.';
      case PermissionType.notification:
        return 'Notification permission example with better UX. '
            'This allows the app to send you important updates.';
    }
  }

  /// Shows success message in snack bar.
  void _showSuccessSnackBar(String message) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(message),
        backgroundColor: Colors.green,
        duration: const Duration(seconds: 3),
      ),
    );
  }

  /// Shows error message in snack bar.
  void _showErrorSnackBar(String message) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(message),
        backgroundColor: Colors.red,
        duration: const Duration(seconds: 3),
      ),
    );
  }

  /// Shows permission status in snack bar.
  void _showStatusSnackBar(PermissionType permission, PermissionStatus status) {
    final color = status.isGranted ? Colors.green : Colors.orange;
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text('${permission.displayName}: ${status.description}'),
        backgroundColor: color,
        duration: const Duration(seconds: 3),
      ),
    );
  }

  /// Shows multiple permission statuses in snack bar.
  void _showMultipleStatusSnackBar(
      Map<PermissionType, PermissionStatus> statuses) {
    final granted = statuses.values.where((status) => status.isGranted).length;
    final total = statuses.length;

    final color = granted == total ? Colors.green : Colors.orange;
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text('Permissions granted: $granted/$total'),
        backgroundColor: color,
        duration: const Duration(seconds: 3),
      ),
    );
  }

  /// Gets color for permission status.
  Color _getStatusColor(PermissionStatus status) {
    switch (status) {
      case PermissionStatus.granted:
        return Colors.green;
      case PermissionStatus.denied:
        return Colors.orange;
      case PermissionStatus.permanentlyDenied:
        return Colors.red;
      case PermissionStatus.restricted:
        return Colors.purple;
      case PermissionStatus.notApplicable:
        return Colors.grey;
      case PermissionStatus.undetermined:
        return Colors.blue;
    }
  }

  /// Gets icon for permission type.
  IconData _getPermissionIcon(PermissionType permission) {
    switch (permission) {
      case PermissionType.camera:
        return Icons.camera_alt;
      case PermissionType.microphone:
        return Icons.mic;
      case PermissionType.locationWhenInUse:
      case PermissionType.locationAlways:
        return Icons.location_on;
      case PermissionType.photos:
        return Icons.photo_library;
      case PermissionType.contacts:
        return Icons.contacts;
      case PermissionType.calendar:
        return Icons.calendar_today;
      case PermissionType.storage:
        return Icons.folder;
      case PermissionType.notification:
        return Icons.notifications;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('Permission Handler Plus Demo'),
        actions: [
          IconButton(
            icon: const Icon(Icons.refresh),
            onPressed: _isLoading ? null : _checkAllPermissions,
            tooltip: 'Refresh permissions',
          ),
          IconButton(
            icon: const Icon(Icons.settings),
            onPressed: _openAppSettings,
            tooltip: 'Open app settings',
          ),
        ],
      ),
      body: _isLoading
          ? const Center(child: CircularProgressIndicator())
          : Column(
              children: [
                // Header section
                Container(
                  width: double.infinity,
                  padding: const EdgeInsets.all(16),
                  color: Theme.of(context).colorScheme.surfaceContainerHighest,
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        'Enhanced Permission Management',
                        style: Theme.of(context).textTheme.titleLarge,
                      ),
                      const SizedBox(height: 8),
                      Text(
                        'This example demonstrates improved UX with automatic '
                        'rationale dialogs, smart retry logic, and seamless '
                        'settings integration.',
                        style: Theme.of(context).textTheme.bodyMedium,
                      ),
                    ],
                  ),
                ),

                // Action buttons
                Padding(
                  padding: const EdgeInsets.all(16),
                  child: Row(
                    children: [
                      Expanded(
                        child: ElevatedButton.icon(
                          onPressed:
                              _isLoading ? null : _requestMultiplePermissions,
                          icon: const Icon(Icons.group_add),
                          label: const Text('Request Multiple'),
                        ),
                      ),
                      const SizedBox(width: 16),
                      Expanded(
                        child: OutlinedButton.icon(
                          onPressed: _isLoading ? null : _checkAllPermissions,
                          icon: const Icon(Icons.refresh),
                          label: const Text('Refresh All'),
                        ),
                      ),
                    ],
                  ),
                ),

                // Permissions list
                Expanded(
                  child: ListView.builder(
                    itemCount: PermissionType.values.length,
                    itemBuilder: (context, index) {
                      final permission = PermissionType.values[index];
                      final status = _permissionStatuses[permission] ??
                          PermissionStatus.undetermined;

                      return ListTile(
                        leading: CircleAvatar(
                          backgroundColor:
                              _getStatusColor(status).withValues(alpha: 0.2),
                          child: Icon(
                            _getPermissionIcon(permission),
                            color: _getStatusColor(status),
                          ),
                        ),
                        title: Text(permission.displayName),
                        subtitle: Text(status.description),
                        trailing: status.isGranted
                            ? const Icon(Icons.check_circle,
                                color: Colors.green)
                            : IconButton(
                                icon: const Icon(Icons.security),
                                onPressed: _isLoading
                                    ? null
                                    : () => _requestPermission(permission),
                                tooltip: 'Request permission',
                              ),
                        onTap: _isLoading
                            ? null
                            : () => _requestPermission(permission),
                      );
                    },
                  ),
                ),
              ],
            ),
      floatingActionButton: FloatingActionButton.extended(
        onPressed: _isLoading ? null : _openAppSettings,
        icon: const Icon(Icons.settings),
        label: const Text('Settings'),
        tooltip: 'Open app settings for manual permission management',
      ),
    );
  }
}
1
likes
160
points
81
downloads

Publisher

verified publisherbechattaoui.dev

Weekly Downloads

An improved permission handler with better UX and automatic permission requests. Provides a simplified API for handling permissions across iOS and Android platforms.

Repository (GitHub)
View/report issues
Contributing

Topics

#permissions #android #ios #flutter #plugin

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on flutter_permission_handler_plus

Packages that implement flutter_permission_handler_plus