Storage Permission Not Working in Flutter App

I am developing a Flutter app that requires storage permissions. I am using the permission_handler package to request these permissions. However, when I try to request the storage permissions, the app directs me to the settings page with “No Permission Required” displayed, even though I have declared the permissions in the AndroidManifest.xml file.

Code: Here’s my main Dart code:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            PermissionStatus storagePermission =
                await Permission.storage.request();
            if (storagePermission == PermissionStatus.granted) {
              print("granted");
            }
            if (storagePermission == PermissionStatus.denied) {
              print("permission denied");
            }
            if (storagePermission == PermissionStatus.permanentlyDenied) {
              openAppSettings();
            }
          },
          child: Text('Ask Permission'),
        ),
      ),
    );
  }
}

And here are the permissions I have declared in my AndroidManifest.xml:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

What I’ve Tried:

I have ensured that I imported the permission_handler package correctly. I have run flutter clean and flutter pub get multiple times. I followed several YouTube tutorials, but none resolved the issue. I even created a new project from scratch to see if the problem persisted. Expected Behavior: I expect that when I click the “Ask Permission” button, the app should request storage permissions.

Actual Behavior: Instead of requesting permissions, the app redirects me to the settings page where it displays “No Permission Required”

settings page

The issue you’re experiencing is likely related to changes in Android’s permission model starting from Android 10 (API level 29) and the deprecation of WRITE_EXTERNAL_STORAGE for scoped storage. Also, newer Android versions manage permissions differently, especially around storage access.

Here’s how to resolve this issue and correctly request storage permissions in your Flutter app:

Step 1: Modify AndroidManifest.xml

Starting from Android 11 (API level 30), Android introduced scoped storage. To request legacy storage access, you need to include the following in your AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.app">

    <application
        android:requestLegacyExternalStorage="true"
        android:label="My App"
        android:icon="@mipmap/ic_launcher">
        ...
    </application>

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    
    <!-- This permission is required for Android 10 (API level 29) and above -->
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" />

</manifest>

Note:

  • android:requestLegacyExternalStorage="true" ensures that your app continues to have access to external storage in the legacy way (without scoped storage) on devices running Android 10 (API level 29).
  • android.permission.MANAGE_EXTERNAL_STORAGE is needed on Android 11+ for full access to external storage. However, this permission only works if you redirect users to the settings page where they manually grant the permission.

Step 2: Update Your permission_handler Request

You’ll need to handle storage permissions depending on the Android version.

In Android 10 (API level 29) and below, you can use READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE. For Android 11+, use MANAGE_EXTERNAL_STORAGE.

You can update your button’s onPressed function as follows:

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Storage Permission')),
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              if (Platform.isAndroid) {
                // For Android 11 and above
                if (await _requestStoragePermission()) {
                  print("Storage permission granted.");
                } else {
                  print("Storage permission denied.");
                }
              }
            },
            child: Text('Ask Permission'),
          ),
        ),
      ),
    );
  }

  Future<bool> _requestStoragePermission() async {
    if (Platform.isAndroid && await _isAndroid11OrAbove()) {
      // Check if the app has manage external storage permission
      PermissionStatus status = await Permission.manageExternalStorage.status;
      if (status != PermissionStatus.granted) {
        // Request the manage external storage permission for Android 11+
        return await Permission.manageExternalStorage.request().isGranted;
      }
    } else {
      // For Android 10 and below
      PermissionStatus status = await Permission.storage.request();
      if (status == PermissionStatus.granted) {
        return true;
      }
    }
    return false;
  }

  // Check if the device is Android 11 or higher
  Future<bool> _isAndroid11OrAbove() async {
    final version = await Permission.storage.status;
    return version.isGranted && Platform.isAndroid && Platform.version >= 30;
  }
}

Step 3: Handle Android 11+ Scoped Storage

Starting from Android 11, apps cannot request WRITE_EXTERNAL_STORAGE the same way they did in previous versions. Instead, Android encourages apps to use the Scoped Storage model, which limits how apps can access shared storage.

If your app needs full access to the device’s storage (for example, reading/writing files anywhere on external storage), you need to request MANAGE_EXTERNAL_STORAGE permission as shown in the code above. This will redirect the user to the settings page where they have to manually grant this permission.

However, for most apps, it’s better to use Scoped Storage, which provides more granular and privacy-friendly access to files.

Step 4: Test on Devices

Ensure you test your app on multiple devices, including:

  • Android 10 (API level 29) or lower for legacy storage access.
  • Android 11 (API level 30) or higher for scoped storage behavior.

Step 5: Flutter Clean

After making these changes, don’t forget to run the following commands to ensure everything is properly reset:

flutter clean
flutter pub get

Finally

Android’s storage permission model has changed significantly over recent versions, and it’s important to ensure that you’re requesting the correct permissions for the API level your app is targeting. By adding the MANAGE_EXTERNAL_STORAGE permission for Android 11+ and using requestLegacyExternalStorage="true" for Android 10, you should be able to resolve the issue with the “No Permission Required” settings page.