list of selected files with file_picker in flutter web - flutter

Question from a newbie in Flutter and Dart:
With this code I let a user to pick mulitple mp4/avi files in flutter web:
`FilePickerResult? picked = await FilePicker.platform
.pickFiles(
allowMultiple: true,
type: FileType.custom,
allowedExtensions: ['mp4', 'avi']);`
Now I would need an exression to extrcat the file name (not the path) of the selected files. I was hoping in something like this:
List<File> file_names = picked.files.name.toList();
But this is wrong.
Any suggestion?

You should try map function to extract the name property of each File object in the files list:
List<String> file_names = picked.files.map((file) => file.name).toList();

You can try like this to get List<File>
List<File> files = picked.paths.map((path) => File(path)).toList();
Also,FilePicker supports picking files from the web so it should not be issue.
And if you're planning to upload files to firebase then make sure you upload in Uint8List format.

Related

How to create a Button that allow user to download a specific file Flutter

I create a flutter app and I have this one CSV file that used as a template for user. I want to provide a Button that allow user to download this CSV file, so they can use it to have CSV file that already have our template.
The problem is I don't know if the best way is to first store the file online and get the url and use it on the flutter downloader URL or keep it in the local code asset and refer to that file when user tap the download template button. Currently I'm applying the second option and it doesn't work (I don't know if this option is possible or not), the download always fail. I'm using flutter_downloader package.
How to fix this ?
Here's my code, Is something wrong with my code ?
/// Check if the file exist or not
if (await File(externalDir!.path + "/" + fileName).exists()) {
OpenFilex.open(externalDir!.path + "/" + fileName);
} else {
/// Download the file if it doesn't exist in the user's device
final String localPath = (await getApplicationDocumentsDirectory()).path;
/// Dummy file name I want use (it exist in my asset dir"
const String fileName = 'add.png';
final data = await rootBundle.load('assets/logo/add.png');
final bytes = data.buffer.asUint8List();
final File file = File('$localPath/$fileName');
await file.writeAsBytes(bytes);
/// Download the file
final taskId = await FlutterDownloader.enqueue(
url: '',
savedDir: localPath,
fileName: fileName,
showNotification: true,
openFileFromNotification: true,
);
}
To load a file from the AppBundle and then save it to the users phone, do the following:
Put the file in assets/filename.csv and declare it in your pubspec like this:
flutter:
assets:
- assets/filename.csv
Load the file in your code:
import 'package:flutter/services.dart' show ByteData, rootBundle;
(...)
var data = (await rootBundle.load('assets/filename.csv)).buffer.asInt8List();
Save the data to a file (you need the path-provider package if you want to copy the exact code):
import 'package:path_provider/path_provider.dart' as pp;
(...)
var path = (await pp.getApplicationDocumentsDirectory()).path;
var file = File('$path/filename.csv');
await file.writeAsBytes(data, flush: true);
Edit: As Stephan correctly pointed out, if you want to store the file in the downloads folder, you will find additional information about that here. Thank you Stephan!

Flutter How to pick an image and convert BASE64 string in web

Actually I'm very new in Flutter-Dart.
And I'm writing an web app. So I should pick images from file path in web. And I should convert the image to base64 code. because I will add the image to my PHP server with my php codes. PHP code is ready. but I don't know a lot of information about pick images and convert base64. Can anybody help me.
Add file_picker: ^4.3.0 to pubspec.yaml and try this:
void pickFile(){
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
);
if (result != null) {
Uint8List? file = result.files.first.bytes!;
final x = base64Encode(file);
//do what you want with x.
}
}

How to save File in Downloads folder in flutter?

In my flutter application I can create a pdf file, then I want to save it in Download folder.
I'm trying to achieve this goal with path_provider package, but I can't.
This is the sample code from flutter's cookbook, If I use it I don't get any error, but I don't find the file either.
final directory = await getApplicationDocumentsDirectory();
File file2 = File("${directory.path}/test.txt");
await file2.writeAsString('TEST ONE');
What's the correct way to do it?
To find the correct path please use ext_storage.
You will need this permission
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
on Android 10 you need this in your manifest
<application
android:requestLegacyExternalStorage="true"
on Android 11 use this instead
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
Remember to ask for them using permission_handler
I leave you my code:
static Future saveInStorage(
String fileName, File file, String extension) async {
await _checkPermission();
String _localPath = (await ExtStorage.getExternalStoragePublicDirectory(
ExtStorage.DIRECTORY_DOWNLOADS))!;
String filePath =
_localPath + "/" + fileName.trim() + "_" + Uuid().v4() + extension;
File fileDef = File(filePath);
await fileDef.create(recursive: true);
Uint8List bytes = await file.readAsBytes();
await fileDef.writeAsBytes(bytes);
}
Android 11 changed a lot of things with its emphasis on scoped storage. Although /storage/emulated/0/Android/data/com.my.app/files is one of the directory paths given by the path_provider pkg, you won't be able to see files saved in /storage/emulated/0/Android/data/com.my.app/files just using any run-of-the-mill file application (Google Files, Samsung My Files, etc.).
A way to get around this (although it only works on Android) is to specify the "general" downloads folder as shown below.
Directory generalDownloadDir = Directory('/storage/emulated/0/Download');
if you write whatever file you are trying to save to that directory, it will show up in the Downloads folder in any standard file manager application, rather than just the application-specific directory that the path_provider pkg provides.
Below is some test code from an app I'm building where I save a user-generated QR code to the user's device. Just for more clarity.
//this code "wraps" the qr widget into an image format
RenderRepaintBoundary boundary = key.currentContext!
.findRenderObject() as RenderRepaintBoundary;
//captures qr image
var image = await boundary.toImage();
String qrName = qrTextController.text;
ByteData? byteData =
await image.toByteData(format: ImageByteFormat.png);
Uint8List pngBytes = byteData!.buffer.asUint8List();
//general downloads folder (accessible by files app) ANDROID ONLY
Directory generalDownloadDir = Directory('/storage/emulated/0/Download'); //! THIS WORKS for android only !!!!!!
//qr image file saved to general downloads folder
File qrJpg = await File('${generalDownloadDir.path}/$qrName.jpg').create();
await qrJpg.writeAsBytes(pngBytes);
Fluttertoast.showToast(msg: ' $qrName QR code was downloaded to ' + generalDownloadDir.path.toString(), gravity: ToastGravity.TOP);
You want getExternalStorageDirectories. You can pass a parameter to specify the downloads specifically:
final directory = (await getExternalStorageDirectories(type: StorageDirectory.downloads)).first!;
File file2 = File("${directory.path}/test.txt");
await file2.writeAsString('TEST ONE');
If you're using null safety you don't need the bang operator:
final directory = (await getExternalStorageDirectories(type: StorageDirectory.downloads)).first;
File file2 = File("${directory.path}/test.txt");
await file2.writeAsString('TEST ONE');
For downloading file in Downloads folder, here are examples:
// Save multiple files
DocumentFileSave.saveMultipleFiles([textBytes, textBytes2], ["text1.txt", "text2.txt"], ["text/plain", "text/plain"]);
//Save single text file
DocumentFileSave.saveFile(textBytes, "my_sample_file.txt", "text/plain");
//Save single pdf file
DocumentFileSave.saveFile(pdfBytes, "my_sample_file.pdf", "appliation/pdf");
//Save single image file
DocumentFileSave.saveFile(imageJPGBytes, "my_sample_file.jpg", "image/jpeg");
More details of library here:
https://pub.dev/packages/document_file_save_plus

Get file path from system directory using Flutter web (chrome) to read file content Eg: CSV or Text file

Package tried: https://pub.dev/packages/file_picker
Tried the example code implementation shared via GitHub. But the file path is returned as null for
web platform. Where same implementation in mobile platform return the path as expected.
https://github.com/miguelpruivo/flutter_file_picker/blob/master/example/lib/src/file_picker_demo.dart
Things aware of:
Path_Provider - Not supported for web
dart-io-library - Not supported for web
Open issue in Flutter Repo
Goal is to read the file from the path and not to upload. Any workaround to achieve this will be helpful.
Flutter channel: beta
As mentioned in the file_picker FAQ:
Paths aren't inaccessible from browsers since those provide fake paths. If you want to create a File instance to upload it somewhere, like FireStorage, you can do so with the bytes directly.
final result = await FilePicker.platform.pickFiles(type: FileType.any, allowMultiple: false);
if (result.files.first != null){
var fileBytes = result.files.first.bytes;
var fileName = result.files.first.name;
print(String.fromCharCodes(fileBytes));
}
I have a function for picking image from computer. Might work for you.
import 'dart:html';
void uploadImage({#required Function(File file) onSelected}) {
InputElement uploadInput = FileUploadInputElement()..accept = 'image/*';
uploadInput.click();
uploadInput.onChange.listen((event) {
final file = uploadInput.files.first;
final reader = FileReader();
reader.readAsDataUrl(file);
reader.onLoadEnd.listen((event) {
onSelected(file);
});
});
}

Flutter: Custom name for screenshot image

I am following the following flutter package to take a screenshot of my one app page:
https://pub.dev/packages/screenshot
I have successfully implemented the example and I can see my screenshots in the gallery.
My issue is that I would like to be able to NAME those images when they are stored in the gallery using some sort of numbering system. e.g. INV_0001, INV_0002.
Is there a way to do this in code? I have the following code that successfully takes the screenshot, but does not rename the file.
CODE
_imageGallerySaver() async {
final directory = (await getApplicationDocumentsDirectory()).path; //from path_provide package
String fileName = "Bob";
String pathName = '$directory/$fileName.png';
//print(path);
screenshotController
.capture(
path: pathName,
).then((File image) async {
print("image: $image");
setState(() {
_imageFile = image;
});
print(pathName);
final result =
await ImageGallerySaver.saveImage(image.readAsBytesSync());
print("File Saved to Gallery. result: $result");
//print("path: $path");
}).catchError((onError) {
print(onError);
});
}
SNIPPET
print("File Saved to Gallery. result: $result");
results in the following output:
File Saved to Gallery. result: file:///storage/emulated/0/app_name/1581602261670.png
I would like to rename the "1581602261670" part, if possible. Thank you
In your code, you are passing that file name to construct the path, then why not change the name there itself.
Anyway, you can rename an existing file using
await file.rename (newPath
):
Can't rename files using this method. Need to use a package called Gallery Saver:
https://pub.dev/packages/gallery_saver
This package allows you to set your own file name and save to the gallery.