Search code examples
androidflutterandroid-permissionsmobile-applicationfilepicker.io

Flutter App Crashes When Saving Text File Using File Picker and Permission Handler


I am developing a Flutter app where I need to save a text file to the device's storage. I am using the file_picker package to select the save location and the permission_handler package to request necessary permissions. However, my app crashes when trying to save the file. Interestingly, a file gets created but with 0 bytes. Here are the details:

My Flutter Function

Future<void> saveTextFile() async {
    var storageStatus = await Permission.storage.status;
    var manageStorageStatus = await Permission.manageExternalStorage.status;

if (kDebugMode) {
 print('::::::::::::: Storage status: $storageStatus');
 print('::::::::::::: Manage storage status: $manageStorageStatus');
}

if (!storageStatus.isGranted) {
storageStatus = await Permission.storage.request();
} 

if (storageStatus.isDenied || storageStatus.isPermanentlyDenied) {
  manageStorageStatus = await Permission.manageExternalStorage.request();
}

if (storageStatus.isGranted || manageStorageStatus.isGranted) {
  try {
    // Create some lorem ipsum text
    String loremText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
    // Convert the text to bytes
  final bytes = utf8.encode(loremText);
  String fileName = 'LoremIpsum.txt';

  // Open the file picker for the user to choose the save location
  String? outputFile = await FilePicker.platform.saveFile(
    dialogTitle: 'Save your text file',
    fileName: fileName,
    type: FileType.custom,
    allowedExtensions: ['txt'],
  );

  if (outputFile != null) {
    final file = File(outputFile);
    await file.writeAsBytes(bytes, flush: true);

    // Show a message indicating the file has been saved.
    Get.snackbar('Success', 'Lorem ipsum text has been saved as a text file.');
  } else {
    // User canceled the file save dialog
    Get.snackbar('Cancelled', 'File save operation was cancelled.');
  }
} catch (e) {
  // Catch any errors during the file writing process
  Get.snackbar('Error', 'An error occurred while saving the file: $e');
  debugPrint('Error saving file: $e');
 }
} else {
// Handle permission denial
Get.snackbar('Permission Denied', 'Storage permission is required to save the file.');
}

}

AndroidManifest.xml

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

<application
    android:label="SJIC Admin"
    android:name="${applicationName}"
    android:icon="@mipmap/launcher_icon"
    android:requestLegacyExternalStorage="true">
    
    <activity
        android:name=".MainActivity"
        android:exported="true"
        android:launchMode="singleTop"
        android:theme="@style/LaunchTheme"
        android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
        android:hardwareAccelerated="true"
        android:windowSoftInputMode="adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

Problem Description

When I attempt to save a text file using the provided Flutter function, the app crashes. However, upon checking the files, a file is created but it is 0 bytes in size. Here is the detailed flow and what I have tried so far:

  1. Request Permissions: I request storage permissions using the permission_handler package.
  2. Generate Text Content: I generate some lorem ipsum text and convert it to bytes.
  3. File Picker: I use the file_picker package to allow the user to select the save location.
  4. Save File: I attempt to save the file to the chosen location.

Observations

  • The file is created but is 0 bytes.
  • The app crashes without detailed error logs.

What I've Tried

build gradle

       /// .......
       minSdkVersion 30
       targetSdkVersion flutter.targetSdkVersion
       versionCode flutterVersionCode.toInteger()
       versionName flutterVersionName
   }

Flutter SDK : 3.19.3

  • path_provider: ^2.1.3
  • permission_handler: ^11.3.1
  • file_picker: ^8.0.3

Solution

  • I found the solution to the issue where my Flutter app was crashing when trying to save a text file. The root cause was related to the FilePicker package and the way the file bytes were being handled. Here's the corrected approach:

    Problem: When attempting to save a text file, the app crashes, and although a file gets created, it has 0 bytes. This was due to not passing the bytes parameter correctly within the FilePicker function.

    Solution: The bytes parameter needs to be included directly within the FilePicker.platform.saveFile method to ensure the file data is passed correctly.

    enter image description here