I'm trying to program an app that let users write their novels or notes with fun features like listening to piano and raining sounds while writing...etc. Everything works fine and great but the problem is how can i turn those novels to PDF? ... I store everything as a "String" data type...ofc the user want to save his work which obviously I can do (Local storage or firebase) however i don't know about exporting data as a specific extension. how can I export the data as a PDF file if the user wanted to do that? is there a general way to do it?
One possible solution can be pdf Flutter plugin. You can create and save a pdf file from strings. I tried this sample code and pdf is created:
//get the directory to save pdf file
late Directory? directory;
if (Platform.isIOS) {
directory = await getApplicationDocumentsDirectory();
} else {
directory = await getExternalStorageDirectory();
}
var path = directory?.path;
//create pdf file
final pdf = pw.Document();
pdf.addPage(
pw.Page(
build: (pw.Context context) => pw.Center(
child: pw.Text('Hello World!'),
),
),
);
//save pdf file
await File('$path/test.pdf').writeAsBytes(await pdf.save());
You can use path_provider Flutter plugin to get the directory location
Related
I'm trying to get a list of files in my app's documents directory using path_provider and getApplicationDocumentsDirectory() along with Directory(appFolder).listSync() from dart:io. While I can load the image files from this directory and view them using flutter's Image.file function, I cannot see any of the image/jpg files generated by my app in the directory listing. I've also tried loading the files using File(imagePath) with the same result.
I cannot understand why Image.File(imagePath) can find, load and display the image file successfully while running File(imagePath) gives an OS Error: No such file or directory . For additional context - these files are being generated using the camera package for flutter. I'm seeing this on Android so far (have not testing this on iOS yet).
Code previews
Code to get appFolder in both cases
import 'package:provider/provider.dart';
final dbFolder = await getApplicationDocumentsDirectory();
Code to display the images
import 'package:flutter/material.dart';
// just the relevant code to display the image
Center(
child: Image.file(Platform.isIOS
? File(appFolder + '/' + imagePath)
: File(appFolder + imagePath)),
),
Code to list the files in the folder
import 'dart:io';
void _getDirectoryList() async {
fileList = Directory(appFolder).listSync(followLinks: true);
final List<FileSystemEntity> entities =
await Directory(appFolder).list().toList();
entities.forEach(print);
}
I'm doing all this to create an archive of the app db and user generated image files, but have gotten stuck at not finding the user-generated image files in the ApplicationDocumentsDirectory.
Any help or pointers would be appreciated!
Look at what 'print' in entities.forEach does. If you are trying to print the names of the files you want to use debugPrint(item)
void _getDirectoryList() async {
fileList =
Directory(appFolder).listSync(followLinks: true);
final List<FileSystemEntity> entities =
await Directory(appFolder).list().toList();
entities.forEach((item) => debugPrint(item.toString());
}
Look into debugPrint and forEach to learn more about what is going wrong.
Been trying all day for the best way to create an app specific folder on anroid 11 devices.
I tried /storage/0/emulated/Android/data/com.talkmia.app/files from path_provider plugin as well as /storage/0/emulated/Android/data/com.talkmia.app/ but app data gets cleared after uninstall and i think android:hasFragileData is useless because it'd only prompt if the app was uinstalled the normal way and it also keeps flutter's own extra data.
I did try SAF too with the saf packages but turns out you can't request access to root-storage and it doesn't make sense to ask users to create the folder then grant permission for that folder.
My only option now is to do it just like WhatsApp does it own. Create it in the Android/Media which i'm finding it hard to do. I've read a number of SO posts as well as Github Issues some suggesting MediaStore API while another suggested using the Context::getExternalMediaDirs which would create the app directory in the Android/Media.
Sighs! My Question now is how can get this Context::getExternalMediaDirs done in dart/flutter. I'd really like not to write platform code 😩😩.
Using this package : path_provider
Step 1: Get the commonly used file path
Future<String> getFilePath() async {
Directory appDocumentsDirectory = await getApplicationDocumentsDirectory(); // 1
String appDocumentsPath = appDocumentsDirectory.path; // 2
String filePath = '$appDocumentsPath/demoTextFile.txt'; // 3
return filePath;
}
Step 2: Write content and save the file
void saveFile() async {
File file = File(await getFilePath()); // 1
file.writeAsString("demo file : demoTextFile.txt"); // 2
}
Step 3: Read the file
void readFile() async {
File file = File(await getFilePath()); // 1
String fileContent = await file.readAsString(); // 2
print('File Content: $fileContent');
}
I want to know how to get write access to a directory path in flutter on API 30 and above. Currently, I cannot find a working complete solution to it anywhere on the internet.
And it would be very grateful if anyone could answer this completely in a detailed way or provide a working sample project.
Note: I know this is not accurately an answer to my question that's why not marked as an answer but this could be useful for those who wanted the "write access" for saving a file in a user-defined location with the native save dialog.
Add flutter_file_dialog plugin in pubspec.yaml. (Version 2.3.0 used in this answer)
Create a function like this.
Future<String?> saveFileInUserDescribedLocation() async {
//Create parameters for save file dialog
//Saving a file through Uint8List data
final params = SaveFileDialogParams(
mimeTypesFilter: ["application/pdf"],
data: Uint8List.fromList(bytes),
fileName: 'Test.pdf');
//You can also use a source file path to save a file through its path like this
//final params = SaveFileDialogParams(
// sourceFilePath: tempPdfPath, mimeTypesFilter: ["application/pdf"]);
//Now provide parameters and save the file.
//It will return the file path chosen by the user to save the file after saving the file.
final filePath = await FlutterFileDialog.saveFile(params: params);
debugPrint("Save filePath: $filePath");
return filePath;
}
Then execute the saveFileInUserDescribedLocation() function. It will provide a native dialog to the user asking the user to choose a location to save and then saves the file.
ElevatedButton(
onPressed: () { await saveFileInUserDescribedLocation(); },
child: const Text("Save File")
)
Android Flutter app downloads an image from a server on another Android phone. After downloading, the file is unable to be opened or viewed by the phones gallery or file explorer. However, when examined by a hex editor, the downloaded file and the original file are exact copies, and when imported to windows, the "corrupt" downloaded file is view able by the Image Viewer. The only difference I could find between the files was the metadata examined by Windows. What could be the cause of this?
Original File on Android Server:
Downloaded File On Android Client:
Here's the code I'm using to create the file from a Uint8list:
Future<File> downloadFileAndroid(Uint8List fileBytes, String fileName) async{
var dir = await getExternalStorageDirectory();
File photoFile;
var photoDirectory = await Directory(dir.path + "/Downloader").create(recursive: true);
photoFile = await new File(photoDirectory.path + "/" + fileName).create();
if(await photoFile.exists()){
await photoFile.writeAsBytes(fileBytes);// also tried flush: true
print("Created file and it exists");
} else {
print("Error: tried to create file but it doesnt exist");
}
}
I faced this problem when downloading an image from the internet and setting a png extention to it. Using an extention on the file name usually causes this error. Consider using https://pub.dev/packages/image_downloader to download the image using the default function in the example code. With the default option, the extension is not determined by the coder but instead by itself.
I am making an app for android/ios using ionic 2. I want to download a JSON file from a specific url on the net and then use it inside my app. This code is how I download:
const imageLocation = `my url for .json file`;
if (this.platform.is('ios')) {
targetPath = cordova.file.applicationStorageDirectory + "data.json";
}
else if(this.platform.is('android')) {
targetPath = cordova.file.dataDirectory + "data.json";
console.log(cordova.file.dataDirectory + "data.json");
}
fileTransfer.download(imageLocation, targetPath).then((entry) => {
const alertSuccess = this.alertCtrl.create({
title: `Download Succeeded!`,
subTitle: `file was successfully downloaded to: ${entry.toURL()}`,
buttons: ['Ok']
});
alertSuccess.present();
}, (error) => {....
I want to use this downloaded file in my provider to fetch data from it. How can I do that?
If you want to save the file, you can choose among many options:
Save it in localStorage
Save it in a SQLite database
Use WebStorage
Use new technologies like CouchDB, etc.
Alternatively, if the file is not very large, feel free to simply store it in a local variable of the provider, i.e. just add a setter method in your provider and pass the JSON object to it, so that it stores it in your provider. Note that in this case the data will be lost when the app is restarted.