'Flutter[Android]: Not able to release App with Manage External Storage Permission
We need to allow users to store files in the external storage and for the same, we use MANAGE_EXTERNAL_STORAGE permission in our application.
Ideally for the android SDK version 30 and above we are using Permission.manageExternalStorage and using Permission.storage for android SDK versions lower than 30 as shown in the below code
// This func is added to access scope storage to export csv files
static Future<bool> externalStoragePermission(BuildContext context) async {
final androidVersion = await DeviceInfoPlugin().androidInfo;
if ((androidVersion.version.sdkInt ?? 0) >= 30) {
return await checkManageStoragePermission(context);
} else {
return await checkStoragePermission(context);
}
}
static Future<bool> checkManageStoragePermission(BuildContext context) async {
return (await Permission.manageExternalStorage.isGranted ||
await Permission.manageExternalStorage.request().isGranted);
}
static Future<bool> checkStoragePermission(BuildContext context,
{String? storageTitle, String? storageSubMessage}) async {
if (await Permission.storage.isGranted ||
await Permission.storage.request().isGranted) {
return true;
} else {
openBottomSheet(
title: storageTitle ?? Str.of(context).storagePermissionRequired,
message: storageSubMessage ?? Str.of(context).storageSubMessage,
).show(context);
return false;
}
}
With the above implementation, everything worked fine while the development and internal release but the Google play console reject the application with the below rejections(Also we have submitted the reason as well for manage_storage permission).
Solution 1:[1]
I found and applied the below solution for the above issue in my project.
- We have to use SAF(Storage Access Framework) on behalf of the storage permission shared_storage which will allow us to grant the permission for the specific directory in the shared storage and we can store the files over there. I have also added the code sample for the same below.
Future<void> exportFile({
required String csvData,
required String fileName,
}) async {
Uri? selectedUriDir;
final pref = await SharedPreferences.getInstance();
final scopeStoragePersistUrl = pref.getString('scopeStoragePersistUrl');
// Check User has already grant permission to any directory or not
if (scopeStoragePersistUrl != null &&
await isPersistedUri(Uri.parse(scopeStoragePersistUrl)) &&
(await exists(Uri.parse(scopeStoragePersistUrl)) ?? false)) {
selectedUriDir = Uri.parse(scopeStoragePersistUrl);
} else {
selectedUriDir = await openDocumentTree();
await pref.setString('scopeStoragePersistUrl', selectedUriDir.toString());
}
if (selectedUriDir == null) {
return false;
}
try {
final existingFile = await findFile(selectedUriDir, fileName);
if (existingFile != null && existingFile.isFile) {
debugPrint("Found existing file ${existingFile.uri}");
await delete(existingFile.uri);
}
final newDocumentFile = await createFileAsString(
selectedUriDir,
mimeType: AppConstants.csvMimeTypeWhileExport,
content: csvData,
displayName: fileName,
);
return newDocumentFile != null;
} catch (e) {
debugPrint("Exception while create new file: ${e.toString()}");
return false;
}
}
Solution 2:[2]
We need to allow users to store files in the external storage and for the same, we use MANAGE_EXTERNAL_STORAGE permission in our application.
You do not need that permission to create your own subdirs in public directories like Download, Documents, DCIM, Pictures and so.
Also you do not need that permission to create files in those directories and subdirs.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Dhaval Kansara |
| Solution 2 | blackapps |

