Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      Error’d: Pickup Sticklers

      September 27, 2025

      From Prompt To Partner: Designing Your Custom AI Assistant

      September 27, 2025

      Microsoft unveils reimagined Marketplace for cloud solutions, AI apps, and more

      September 27, 2025

      Design Dialects: Breaking the Rules, Not the System

      September 27, 2025

      Building personal apps with open source and AI

      September 12, 2025

      What Can We Actually Do With corner-shape?

      September 12, 2025

      Craft, Clarity, and Care: The Story and Work of Mengchu Yao

      September 12, 2025

      Cailabs secures €57M to accelerate growth and industrial scale-up

      September 12, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      Using phpinfo() to Debug Common and Not-so-Common PHP Errors and Warnings

      September 28, 2025
      Recent

      Using phpinfo() to Debug Common and Not-so-Common PHP Errors and Warnings

      September 28, 2025

      Mastering PHP File Uploads: A Guide to php.ini Settings and Code Examples

      September 28, 2025

      The first browser with JavaScript landed 30 years ago

      September 27, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured
      Recent
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»Development»How to Handle Permissions in Flutter: A Comprehensive Guide

    How to Handle Permissions in Flutter: A Comprehensive Guide

    August 28, 2025

    Permissions are crucial when building mobile applications that require access to device features such as location, camera, contacts, microphone, storage, and more. And handling permissions effectively ensures that your app provides a seamless user experience while respecting privacy and security requirements.

    In Flutter, one of the most popular packages to manage permissions is permission_handler. This article will guide you through how to:

    1. Install and set up permission_handler and fluttertoast

    2. Request and handle different permissions

    3. Understand what each permission does and its use cases

    4. Handling Android and iOS configurations

    5. Implement best practices

    6. Handle testing permissions

    7. Provide expected outcomes and conclusions

    Table of Contents:

    • Table of Contents:

    • 1. Prerequisites

    • 2. Installing Dependencies

    • 3. Understanding Permission States

    • 4. Reusable Permission Handling Function

    • 5. Permissions, Their Use Cases, and Examples

      • 5.1 Calendar Permissions

      • 5.2 Camera Permission

      • 5.3 Contacts Permission

      • 5.4 Location Permissions

      • 5.5 Media Library (iOS only)

      • 5.6 Microphone Permission

      • 5.7 Phone Permission

      • 5.8 Photos Permissions

      • 5.9 Reminders Permission

      • 5.10 Sensors Permissions

      • 5.11 SMS Permission

      • 5.12 Speech Recognition Permission

      • 5.13 Storage Permissions

      • 5.14 Ignore Battery Optimizations

      • 5.15 Notifications

      • 5.16 Bluetooth Permissions

      • 5.17 App Tracking Transparency (iOS only)

    • 6. Android Manifest Configuration

    • 7. iOS Info.plist Configuration

    • 8. Expected Outcomes

    • Best Practices for Handling Permissions in Flutter

      • 1. Request only necessary permissions

      • 2. Explain why permissions are needed

      • 3. Use runtime permission requests

      • 4. Handle denial gracefully

      • 5. Handle permanent denials

      • 6. Test on both platforms

      • 7. Follow platform guidelines

      • 8. Avoid over-permissioning

      • 9. Use a centralized permission manager

      • 10. Monitor permission changes

    • Conclusion

    • References

    1. Prerequisites

    Before starting, ensure you have the following:

    1. Flutter SDK installed (version 3.0.0 or higher recommended)

    2. A code editor such as Android Studio or VS Code

    3. Basic understanding of Flutter widgets, async/await in Dart, and state management

    4. A physical device (recommended) or emulator/simulator

    5. Internet connection to install dependencies

    2. Installing Dependencies

    To get started, add the following to your pubspec.yaml file:

    <span class="hljs-attr">dependencies:</span>
      <span class="hljs-attr">permission_handler:</span> <span class="hljs-string">^11.3.1</span>
      <span class="hljs-attr">fluttertoast:</span> <span class="hljs-string">^8.2.4</span>
    

    Then run:

    flutter pub get
    
    • permission_handler is used to request and check permissions on Android and iOS.

    • fluttertoast allows you to display messages to users when permissions are granted or denied.

    3. Understanding Permission States

    When requesting permissions with permission_handler, you can get the following states:

    1. isGranted – The permission is granted.

    2. isDenied – The permission is denied, but can be requested again.

    3. isPermanentlyDenied – The permission is permanently denied, meaning the user must enable it from app settings.

    4. isRestricted – The permission is restricted by the system (common on iOS).

    5. isLimited – Partial access granted (mainly iOS photo library).

    4. Reusable Permission Handling Function

    Instead of writing multiple functions for each permission, we’ll create a reusable function:

    <span class="hljs-keyword">import</span> <span class="hljs-string">'package:permission_handler/permission_handler.dart'</span>;
    <span class="hljs-keyword">import</span> <span class="hljs-string">'package:fluttertoast/fluttertoast.dart'</span>;
    
    Future<<span class="hljs-keyword">void</span>> handlePermission(Permission permission, <span class="hljs-built_in">String</span> name) <span class="hljs-keyword">async</span> {
      <span class="hljs-keyword">var</span> status = <span class="hljs-keyword">await</span> permission.request();
    
      <span class="hljs-keyword">if</span> (status.isGranted) {
        Fluttertoast.showToast(msg: <span class="hljs-string">'<span class="hljs-subst">$name</span> permission granted'</span>);
      } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (status.isPermanentlyDenied) {
        Fluttertoast.showToast(msg: <span class="hljs-string">'<span class="hljs-subst">$name</span> permission permanently denied. Enable it in settings.'</span>);
        openAppSettings();
      } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (status.isRestricted) {
        Fluttertoast.showToast(msg: <span class="hljs-string">'<span class="hljs-subst">$name</span> permission restricted by system.'</span>);
      } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (status.isLimited) {
        Fluttertoast.showToast(msg: <span class="hljs-string">'<span class="hljs-subst">$name</span> permission limited access granted.'</span>);
      } <span class="hljs-keyword">else</span> {
        Fluttertoast.showToast(msg: <span class="hljs-string">'<span class="hljs-subst">$name</span> permission denied'</span>);
      }
    }
    

    Usage example:

    <span class="hljs-keyword">await</span> handlePermission(Permission.camera, <span class="hljs-string">"Camera"</span>);
    <span class="hljs-keyword">await</span> handlePermission(Permission.location, <span class="hljs-string">"Location"</span>);
    

    5. Permissions, Their Use Cases, and Examples

    Let’s now look at a bunch of different types of permissions you might have to enable in your Flutter apps. I’ll explain what the permission does and its common use cases as well.

    5.1 Calendar Permissions

    • Permission: calendar, calendarReadOnly, calendarFullAccess

    • What it does: Accesses the user’s calendar to read or write events.

    • Use case: Event apps, scheduling apps.

    <span class="hljs-keyword">await</span> handlePermission(Permission.calendar, <span class="hljs-string">"Calendar"</span>);
    

    5.2 Camera Permission

    • Permission: camera

    • What it does: Access device camera for capturing photos/videos.

    • Use case: QR scanning, photo apps, video recording.

    <span class="hljs-keyword">await</span> handlePermission(Permission.camera, <span class="hljs-string">"Camera"</span>);
    

    5.3 Contacts Permission

    • Permission: contacts

    • What it does: Read or modify user contacts.

    • Use case: Messaging apps, social networking apps.

    <span class="hljs-keyword">await</span> handlePermission(Permission.contacts, <span class="hljs-string">"Contacts"</span>);
    

    5.4 Location Permissions

    • Permission: location, locationAlways, locationWhenInUse

    • What it does: Access user’s location.

    • Use case: Navigation apps, ride-hailing apps, geofencing.

    <span class="hljs-keyword">await</span> handlePermission(Permission.locationWhenInUse, <span class="hljs-string">"Location"</span>);
    

    5.5 Media Library (iOS only)

    • Permission: mediaLibrary

    • What it does: Access media files on iOS devices.

    • Use case: Photo sharing apps, media editors.

    <span class="hljs-keyword">await</span> handlePermission(Permission.mediaLibrary, <span class="hljs-string">"Media Library"</span>);
    

    5.6 Microphone Permission

    • Permission: microphone

    • What it does: Record audio.

    • Use case: Voice notes, video calls, voice commands.

    <span class="hljs-keyword">await</span> handlePermission(Permission.microphone, <span class="hljs-string">"Microphone"</span>);
    

    5.7 Phone Permission

    • Permission: phone

    • What it does: Access phone state, make calls, read call logs.

    • Use case: Telephony apps, call management apps.

    <span class="hljs-keyword">await</span> handlePermission(Permission.phone, <span class="hljs-string">"Phone"</span>);
    

    5.8 Photos Permissions

    • Permission: photos, photosAddOnly

    • What it does: Access or add photos to user library.

    • Use case: Media apps, social apps.

    <span class="hljs-keyword">await</span> handlePermission(Permission.photos, <span class="hljs-string">"Photos"</span>);
    

    5.9 Reminders Permission

    • Permission: reminders

    • What it does: Access and manage device reminders.

    • Use case: To-do apps, productivity apps.

    <span class="hljs-keyword">await</span> handlePermission(Permission.reminders, <span class="hljs-string">"Reminders"</span>);
    

    5.10 Sensors Permissions

    • Permission: sensors, sensorsAlways

    • What it does: Access device sensors like accelerometer or gyroscope.

    • Use case: Fitness apps, motion tracking apps.

    <span class="hljs-keyword">await</span> handlePermission(Permission.sensors, <span class="hljs-string">"Sensors"</span>);
    

    5.11 SMS Permission

    • Permission: sms

    • What it does: Read or send SMS messages.

    • Use case: OTP verification, messaging apps.

    <span class="hljs-keyword">await</span> handlePermission(Permission.sms, <span class="hljs-string">"SMS"</span>);
    

    5.12 Speech Recognition Permission

    • Permission: speech

    • What it does: Use speech-to-text features.

    • Use case: Voice commands, dictation apps.

    <span class="hljs-keyword">await</span> handlePermission(Permission.speech, <span class="hljs-string">"Speech Recognition"</span>);
    

    5.13 Storage Permissions

    • Permission: storage, manageExternalStorage

    • What it does: Access internal/external storage to read/write files.

    • Use case: File managers, download managers.

    <span class="hljs-keyword">await</span> handlePermission(Permission.storage, <span class="hljs-string">"Storage"</span>);
    

    5.14 Ignore Battery Optimizations

    • Permission: ignoreBatteryOptimizations

    • What it does: Request to exclude app from battery optimizations.

    • Use case: Alarm apps, background services.

    <span class="hljs-keyword">await</span> handlePermission(Permission.ignoreBatteryOptimizations, <span class="hljs-string">"Battery Optimizations"</span>);
    

    5.15 Notifications

    • Permission: notification

    • What it does: Allow sending notifications.

    • Use case: Messaging, reminders, alerts.

    <span class="hljs-keyword">await</span> handlePermission(Permission.notification, <span class="hljs-string">"Notifications"</span>);
    

    5.16 Bluetooth Permissions

    • Permission: bluetooth, bluetoothScan, bluetoothAdvertise, bluetoothConnect

    • What it does: Manage or connect to Bluetooth devices.

    • Use case: Wearables, IoT devices, headphones.

    <span class="hljs-keyword">await</span> handlePermission(Permission.bluetooth, <span class="hljs-string">"Bluetooth"</span>);
    

    5.17 App Tracking Transparency (iOS only)

    • Permission: appTrackingTransparency

    • What it does: Request tracking permission for personalized ads.

    • Use case: Analytics, advertising, user tracking.

    <span class="hljs-keyword">await</span> handlePermission(Permission.appTrackingTransparency, <span class="hljs-string">"App Tracking"</span>);
    

    6. Android Manifest Configuration

    On Android, all apps must declare the permissions they intend to use in the AndroidManifest.xml file. This acts as the app’s “contract” with the system, letting Android know what sensitive resources (like internet, location, camera) the app might request.

    Without declaring these in the manifest, runtime permission requests will fail, even if you’ve added the permission_handler package.

    For example, if you try to access the camera without first declaring the camera permission here, your app will crash or fail when requesting it at runtime.

    Below is a comprehensive list of common permissions:

    <span class="hljs-comment"><!-- Camera access for taking pictures or recording videos --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.CAMERA"</span> /></span>
    
    <span class="hljs-comment"><!-- Read user contacts (e.g., for social features, friend finder) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.READ_CONTACTS"</span> /></span>
    
    <span class="hljs-comment"><!-- Fine-grained location (GPS) for maps, navigation, geofencing --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.ACCESS_FINE_LOCATION"</span> /></span>
    
    <span class="hljs-comment"><!-- Coarse location (network-based, less accurate, uses WiFi/Cell) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.ACCESS_COARSE_LOCATION"</span> /></span>
    
    <span class="hljs-comment"><!-- Record audio from the microphone (e.g., voice notes, calls) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.RECORD_AUDIO"</span> /></span>
    
    <span class="hljs-comment"><!-- Read external storage (access user’s files like images, docs) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.READ_EXTERNAL_STORAGE"</span> /></span>
    
    <span class="hljs-comment"><!-- Write to external storage (save downloaded files, photos) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.WRITE_EXTERNAL_STORAGE"</span> /></span>
    
    <span class="hljs-comment"><!-- Send SMS directly from the app --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.SEND_SMS"</span> /></span>
    
    <span class="hljs-comment"><!-- Receive SMS (read OTP messages for login/verification) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.RECEIVE_SMS"</span> /></span>
    
    <span class="hljs-comment"><!-- Read SMS messages (OTP autofill, chat backup restore) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.READ_SMS"</span> /></span>
    
    <span class="hljs-comment"><!-- Bluetooth usage (connect to Bluetooth devices like headsets, printers) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.BLUETOOTH"</span> /></span>
    
    <span class="hljs-comment"><!-- Bluetooth Admin (manage paired devices, discover nearby devices) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.BLUETOOTH_ADMIN"</span> /></span>
    
    <span class="hljs-comment"><!-- Bluetooth Scan (needed from Android 12+) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.BLUETOOTH_SCAN"</span> /></span>
    
    <span class="hljs-comment"><!-- Bluetooth Connect (needed from Android 12+) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.BLUETOOTH_CONNECT"</span> /></span>
    
    <span class="hljs-comment"><!-- Bluetooth Advertise (for beacon-style apps, Android 12+) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.BLUETOOTH_ADVERTISE"</span> /></span>
    
    <span class="hljs-comment"><!-- Ignore battery optimizations (keep app alive in background tasks) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"</span> /></span>
    
    <span class="hljs-comment"><!-- Internet access (needed for network requests, APIs, file uploads) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.INTERNET"</span> /></span>
    
    <span class="hljs-comment"><!-- Check if a network connection exists (WiFi/Mobile data) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.ACCESS_NETWORK_STATE"</span> /></span>
    
    <span class="hljs-comment"><!-- Access WiFi state (check SSID, connection info, used for network control) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.ACCESS_WIFI_STATE"</span> /></span>
    
    <span class="hljs-comment"><!-- Change WiFi state (enable/disable WiFi programmatically) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.CHANGE_WIFI_STATE"</span> /></span>
    
    <span class="hljs-comment"><!-- Access phone state (read device ID, SIM details, call status) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.READ_PHONE_STATE"</span> /></span>
    
    <span class="hljs-comment"><!-- Make phone calls directly from the app --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.CALL_PHONE"</span> /></span>
    
    <span class="hljs-comment"><!-- Use fingerprint authentication (for biometric login) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.USE_FINGERPRINT"</span> /></span>
    
    <span class="hljs-comment"><!-- Use Biometric authentication (newer than fingerprint, includes face) --></span>
    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.USE_BIOMETRIC"</span> /></span>
    

    7. iOS Info.plist Configuration

    For iOS, you must provide descriptive keys in the Info.plist file to inform users why your app needs specific permissions. Below are the configurations for each permission example:

    1. Camera Permission

       <span class="hljs-tag"><<span class="hljs-name">key</span>></span>NSCameraUsageDescription<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
       <span class="hljs-tag"><<span class="hljs-name">string</span>></span>We need access to your camera for taking pictures.<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
      
    2. Contacts Permission

       <span class="hljs-tag"><<span class="hljs-name">key</span>></span>NSContactsUsageDescription<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
       <span class="hljs-tag"><<span class="hljs-name">string</span>></span>We need access to your contacts for better communication.<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
      
    3. Location Permissions

       <span class="hljs-tag"><<span class="hljs-name">key</span>></span>NSLocationWhenInUseUsageDescription<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
       <span class="hljs-tag"><<span class="hljs-name">string</span>></span>We need access to your location to provide location-based services.<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
       <span class="hljs-tag"><<span class="hljs-name">key</span>></span>NSLocationAlwaysUsageDescription<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
       <span class="hljs-tag"><<span class="hljs-name">string</span>></span>We need access to your location to track your movement even when the app is not active.<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
      
    4. Media Library/Storage Permission

       <span class="hljs-tag"><<span class="hljs-name">key</span>></span>NSPhotoLibraryUsageDescription<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
       <span class="hljs-tag"><<span class="hljs-name">string</span>></span>We need access to your photos for sharing or uploading media.<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
      
    5. Microphone Permission

       <span class="hljs-tag"><<span class="hljs-name">key</span>></span>NSMicrophoneUsageDescription<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
       <span class="hljs-tag"><<span class="hljs-name">string</span>></span>We need access to your microphone for voice recording.<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
      
    6. Phone Permission

       <span class="hljs-tag"><<span class="hljs-name">key</span>></span>NSPhoneUsageDescription<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
       <span class="hljs-tag"><<span class="hljs-name">string</span>></span>We need access to phone services to enable calls.<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
      
    7. Photos Permission

       <span class="hljs-tag"><<span class="hljs-name">key</span>></span>NSPhotoLibraryAddUsageDescription<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
       <span class="hljs-tag"><<span class="hljs-name">string</span>></span>We need permission to add photos to your library.<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
      
    8. Reminders Permission

       <span class="hljs-tag"><<span class="hljs-name">key</span>></span>NSRemindersUsageDescription<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
       <span class="hljs-tag"><<span class="hljs-name">string</span>></span>We need access to your reminders for task management.<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
      
    9. Sensors Permission

       <span class="hljs-tag"><<span class="hljs-name">key</span>></span>NSSensorsUsageDescription<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
       <span class="hljs-tag"><<span class="hljs-name">string</span>></span>We need access to your sensors for fitness tracking.<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
      
    10. SMS Permission (Handled automatically by iOS if SMS services are requested)

    11. Speech Recognition Permission

    <span class="hljs-tag"><<span class="hljs-name">key</span>></span>NSSpeechRecognitionUsageDescription<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
    <span class="hljs-tag"><<span class="hljs-name">string</span>></span>We need access to speech recognition for voice commands.<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
    
    1. Ignore Battery Optimizations (Not applicable on iOS)

    2. Notifications Permission

    <span class="hljs-tag"><<span class="hljs-name">key</span>></span>NSUserNotificationUsageDescription<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
    <span class="hljs-tag"><<span class="hljs-name">string</span>></span>We need permission to send notifications.<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
    
    1. Access Media Location Permission (Handled automatically on iOS)

    2. Activity Recognition Permission

    <span class="hljs-tag"><<span class="hljs-name">key</span>></span>NSMotionUsageDescription<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
    <span class="hljs-tag"><<span class="hljs-name">string</span>></span>We need access to motion data for fitness tracking.<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
    
    1. Bluetooth Permissions
    <span class="hljs-tag"><<span class="hljs-name">key</span>></span>NSBluetoothPeripheralUsageDescription<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
    <span class="hljs-tag"><<span class="hljs-name">string</span>></span>We need access to Bluetooth for device connectivity.<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
    
    1. App Tracking Transparency
    <span class="hljs-tag"><<span class="hljs-name">key</span>></span>NSUserTrackingUsageDescription<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
    <span class="hljs-tag"><<span class="hljs-name">string</span>></span>We need permission to track your activity across apps and websites for personalized ads.<span class="hljs-tag"></<span class="hljs-name">st</span></span>
    

    8. Expected Outcomes

    By implementing permissions and connectivity checks this way, your Flutter app will:

    1. Request permissions dynamically at runtime in a user-friendly way.

    2. Handle all possible states gracefully, including granted, denied, permanently denied, restricted, and limited.

    3. Provide users with meaningful feedback, guiding them to settings if necessary.

    4. Maintain compliance with Android and iOS permission policies while ensuring security and transparency.

    5. Listen continuously to network connectivity changes via the global BLoC listener.

    6. Notify users instantly with a toast/snackbar whenever internet status changes (connected/disconnected).

    7. Reduce redundant API calls and improve UX by avoiding “fake” offline or cached-only states.

    Best Practices for Handling Permissions in Flutter

    There are some common best practices you should follow when handling permissions in Flutter.

    1. Request only necessary permissions

    Ask only for the permissions your app truly needs. For example, if your app just uploads images, you probably only need storage/photos access, not location, contacts, or SMS.

    <span class="hljs-keyword">final</span> status = <span class="hljs-keyword">await</span> Permission.photos.request();
    <span class="hljs-keyword">if</span> (status.isGranted) {
      <span class="hljs-comment">// Proceed with photo upload</span>
    }
    

    2. Explain why permissions are needed

    Always tell the user why you’re asking for a sensitive permission before the system dialog appears. This helps build trust.

    Example of a custom dialog before requesting:

    Future<<span class="hljs-keyword">void</span>> _showPermissionRationale(BuildContext context) <span class="hljs-keyword">async</span> {
      showDialog(
        context: context,
        builder: (context) => AlertDialog(
          title: Text(<span class="hljs-string">"Camera Access Needed"</span>),
          content: Text(<span class="hljs-string">"We need access to your camera so you can take profile photos."</span>),
          actions: [
            TextButton(
              onPressed: () {
                Navigator.pop(context);
                Permission.camera.request();
              },
              child: Text(<span class="hljs-string">"Allow"</span>),
            ),
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: Text(<span class="hljs-string">"Cancel"</span>),
            ),
          ],
        ),
      );
    }
    

    3. Use runtime permission requests

    On Android 6.0+ and iOS, permissions must be requested at runtime (not just declared in AndroidManifest.xml or Info.plist).

    <span class="hljs-keyword">final</span> status = <span class="hljs-keyword">await</span> Permission.location.request();
    <span class="hljs-keyword">if</span> (status.isGranted) {
      <span class="hljs-comment">// Use location</span>
    }
    

    4. Handle denial gracefully

    Don’t block the entire app when permissions are denied. Provide alternative flows.

    For example, instead of forcing camera access:

    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">await</span> Permission.camera.isDenied) {
      <span class="hljs-comment">// Offer file upload as fallback</span>
      _pickImageFromGallery();
    }
    

    This way, users can still use your app without being forced.

    5. Handle permanent denials

    When a user selects “Don’t ask again” (Android) or disables a permission in Settings (iOS), you should guide them to Settings.

    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">await</span> Permission.camera.isPermanentlyDenied) {
      openAppSettings(); <span class="hljs-comment">// Takes user to app settings</span>
    }
    

    UX Example:

    • Show a snackbar: “Camera access is required. Enable it in Settings.” with a Go to Settings button.

    6. Test on both platforms

    Permissions behave differently across Android and iOS. Example:

    • iOS may return limited photo library access.

    • Android 13+ has new granular media permissions (READ_MEDIA_IMAGES, READ_MEDIA_VIDEO).

    Always test all scenarios:

    • Granted

    • Denied once

    • Denied permanently

    • Limited (iOS only)

    7. Follow platform guidelines

    Make sure your manifest and Info.plist contain clear explanations.

    Info.plist example (iOS):

    <span class="hljs-tag"><<span class="hljs-name">key</span>></span>NSCameraUsageDescription<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
    <span class="hljs-tag"><<span class="hljs-name">string</span>></span>This app requires camera access to let you take profile pictures.<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
    

    This is required for App Store approval.

    8. Avoid over-permissioning

    Example: Don’t request SMS if you only need phone number autofill. Users will abandon your app if they see irrelevant requests.

    Bad:

    <span class="hljs-tag"><<span class="hljs-name">uses-permission</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.permission.SEND_SMS"</span> /></span>
    

    Just use READ_PHONE_NUMBERS if that’s the actual need.

    9. Use a centralized permission manager

    Instead of scattering requests across the app, create a PermissionService that handles all requests consistently.

    <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PermissionService</span> </span>{
      Future<<span class="hljs-built_in">bool</span>> requestCamera() <span class="hljs-keyword">async</span> {
        <span class="hljs-keyword">final</span> status = <span class="hljs-keyword">await</span> Permission.camera.request();
        <span class="hljs-keyword">return</span> status.isGranted;
      }
    
      Future<<span class="hljs-built_in">bool</span>> requestLocation() <span class="hljs-keyword">async</span> {
        <span class="hljs-keyword">final</span> status = <span class="hljs-keyword">await</span> Permission.location.request();
        <span class="hljs-keyword">return</span> status.isGranted;
      }
    }
    

    This keeps permission handling uniform.

    10. Monitor permission changes

    Permissions can change while the app is open (user goes to Settings and disables it). Always check before use.

    <span class="hljs-meta">@override</span>
    <span class="hljs-keyword">void</span> initState() {
      <span class="hljs-keyword">super</span>.initState();
      Timer.periodic(<span class="hljs-built_in">Duration</span>(seconds: <span class="hljs-number">5</span>), (timer) <span class="hljs-keyword">async</span> {
        <span class="hljs-keyword">final</span> cameraStatus = <span class="hljs-keyword">await</span> Permission.camera.status;
        <span class="hljs-keyword">if</span> (!cameraStatus.isGranted) {
          <span class="hljs-comment">// Disable camera UI</span>
        }
      });
    }
    

    Conclusion

    Permissions are fundamental for building fully functional and secure mobile applications. Using permission_handler in Flutter allows you to manage permissions across Android and iOS efficiently.

    And just remember: always request only necessary permissions, provide clear explanations, and handle all possible states to maintain trust with users.

    By combining correct permission logic with proper AndroidManifest and Info.plist setup, you ensure a seamless user experience while staying compliant with platform guidelines.

    References

    1. permission_handler Flutter Package Documentation

    2. Flutter Official Documentation: Handling Permissions

    3. Android Developer Guide: Permissions

    4. iOS Developer Guide: App Permissions

    5. Fluttertoast Package Documentation

    Source: freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More 

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleCaching a Next.js API using Redis and Sevalla
    Next Article Prepare for the Google Professional Cloud Architect Certification Exam – And Pass!

    Related Posts

    Development

    Using phpinfo() to Debug Common and Not-so-Common PHP Errors and Warnings

    September 28, 2025
    Development

    Mastering PHP File Uploads: A Guide to php.ini Settings and Code Examples

    September 28, 2025
    Leave A Reply Cancel Reply

    For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

    Continue Reading

    Use Arduinos for Computer Vision

    Development

    Cisco waarschuwt voor kritiek Erlang/OTP SSH-lek in eigen producten

    Security

    Everything You Need to Know About CVE-2025–3248: Langflow RCE Vulnerability Explained

    Security

    Meet AlphaEarth Foundations: Google DeepMind’s So Called ‘ Virtual Satellite’ in AI-Driven Planetary Mapping

    Machine Learning

    Highlights

    Sick of AI in your search results? Try these 7 Google alternatives with old-school, AI-free charm

    July 29, 2025

    These search engines that do not put AI front and center – or, better yet,…

    Tenable Agent for Windows Vulnerability Let Attackers Login as Admin to Delete The System Files

    June 14, 2025

    GitHub’s AI-powered Spark lets you build apps using natural language – here’s how to access it

    July 24, 2025

    Microsoft waarschuwt voor actief aangevallen RCE-lek in WebDAV

    June 11, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.