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:
Observations
What I've Tried
build gradle
/// .......
minSdkVersion 30
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
Flutter SDK : 3.19.3
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.