Search code examples
androidflutterandroid-permissions

Unable to create new file outside of Documents folder with Flutter


I'm trying to create a new JSON file generated by my Flutter application and I wanna let the user to choose where to store this file.

I'm currently using file_picker package to let the user to choose the path to store the generated file. If I select the Documents folder (/storage/emulated/0/Documents) I can create that file, but if I choose another path (like /storage/emulated/0/DCIM or a custom folder created by the user named Test for example) I get the following exception: FileSystemException: Cannot open file, path = '/storage/emulated/0/Test/backup.json' (OS Error: Operation not permitted, errno = 1)

Note that I'm running my app on an emulator that have Android 13. I also tried to add this permissions in the Manifest:

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

And tried to request storage permissions with the package permission_handler but nothing change.


Solution

  • Finally managed to solve it thanks to a great library. The library name is flutter_file_dialog and works perfectly fine. Here a snippet of how to use it:

    Future<OperationStatusCode> createLocalBackupFile() async {
        try {
        
          // ... 
    
          if (!await FlutterFileDialog.isPickDirectorySupported()) {
            throw Exception("Picking directory not supported");
          }
    
          // This will open file system manager
          final pickedDirectory = await FlutterFileDialog.pickDirectory();
    
          // Check if choosen directory is not null and proceed to save the file
          if (pickedDirectory != null) {
            await FlutterFileDialog.saveFileToDirectory(
              directory: pickedDirectory,
              data: YOUR_FILE_DATA,
              mimeType: "application/json",
              fileName: "backup_file_$formattedFileDate.json",
              replace: false,
            );
            return OperationStatusCode.success;
          }
          return OperationStatusCode.undefined;
        } catch (exc) {
          return OperationStatusCode.error;
        }
      }
    

    With this library the user will be able to choose where to store his file and also he can create new folders to store that file. You don't need to set any type of permission in the Manifest.xml or Info.plist :)