Accesing downloaded files from a Flutter app - flutter

I am working on an app that should manage downloaded files.
For now I am able to download a file on both platforms, but I would need to know how can I get the downloaded files from the device.
This is the code used to download a file from Internet.
Future<void> downloadFile() async {
bool downloading = false;
var progressString = "";
final imgUrl = "https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4";
Dio dio = Dio();
try {
var dir = await getApplicationDocumentsDirectory();
print("path ${dir.path}");
await dio.download(imgUrl, "${dir.path}/demo.mp4",
onReceiveProgress: (rec, total) {
print("Rec: $rec , Total: $total");
downloading = true;
progressString = ((rec / total) * 100).toStringAsFixed(0) + "%";
});
} catch (e) {
print(e);
}
downloading = false;
progressString = "Completed";
print("Download completed");
}
The path print output for Android is:
path /data/user/0/red.faro.labelconciergeflutter/app_flutter
The path print output for iOS is:
path /var/mobile/Containers/Data/Application/9CFDC9E3-D9A9-4594-901E-427D44E48EB9/Documents
What I need is to know how can an app user access the downloaded files when the app is closed or there is no internet connection to open the file from the original URL?

For getting files from the device you may use file_picker package.
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
File file = File(result.files.single.path);
} else {
// User canceled the picker
}
You also can use the File class from the dart:io library.
Future<File> get _localFile async {
final path = await _localPath;
return File('$path/counter.txt');
}
If your goal is to access commonly used locations on the device’s file system you can use the path_provider plugin.
Directory tempDir = await getTemporaryDirectory();
String tempPath = tempDir.path;
Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path

Related

Flutter get all files and folders from storage

I am working on the app and for that, I need to get all files from storage it can be mp3,img pdf or anything. I followed a tutorial and they worked on flutter_file_manager. and this package is discontinued
You can use file_picker package instead. Moreover, you may need to use the path_provider package along with the file_picker package. Complete documentation and examples can be found on the pub pages of the mentioned packages.
Here are some code samples:
To pick a single file:
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
File file = File(result.files.single.path);
} else {
// User canceled the picker
}
To pick multiple files:
FilePickerResult? result = await FilePicker.platform.pickFiles(allowMultiple: true);
if (result != null) {
List<File> files = result.paths.map((path) => File(path)).toList();
} else {
// User canceled the picker
}
To pick multiple files with Extensions filters:
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['jpg', 'pdf', 'doc'],
);
To pick a directory:
String? selectedDirectory = await FilePicker.platform.getDirectoryPath();
if (selectedDirectory == null) {
// User canceled the picker
}
The usage for path_provider package:
Directory tempDir = await getTemporaryDirectory();
String tempPath = tempDir.path;
Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path;

Get a list of files from the local storage and display it as a list in flutter web:

I've been building an ios app and in it, it'll download a bunch of pdf from an API and save it to the local storage using the path_provider package in flutter:
This is the code I use to fetch the path:
Future<String> get localPath async {
final directory = await getApplicationDocumentsDirectory();
currentDir.value = directory.path;
return directory.path;}
And this is how I save it to the device:
Future<void> saveFilesToLocal(String url, String fileName) async {
try {
final path = await localPath;
final file = File('$path/$fileName');
if (await file.exists() == false) {
final response = await Dio().get(url,
options: Options(
responseType: ResponseType.bytes,
followRedirects: false,
receiveTimeout: 0));
final raf = file.openSync(mode: FileMode.write);
raf.writeFromSync(response.data);
await raf.close();
} else {
print("file already exists");
}
} catch (e) {
print('error: $e');
}
}
After I download and save the files to the storage, it'll be displayed as a gridview in the home page. To fetch that list of files I use this:
List<FileSystemEntity> files = [];
Future<void> getFilesList() async {
files.clear();
final path = await localPath;
Directory dir = Directory('$path');
files =
dir.listSync(recursive: true, followLinks: false);
update();
}
And all of this works fine in the ios device. But the current issue I'm facing while trying to run it on web is:
The package path_provider is not available for flutter web. I've been asked to create it as a web app too and I can't find an alternative for it. While looking for one I saw a post saying flutter web won't allow access to a device's local storage like that so it's not possible. Is it true? Is there a workaround? If it's about security, the app will only be run on specific devices. It won't be given to the public.

Is there a way to download folder from firebase storage with flutter?

I want to download .epub files from firebase storage. I can download image file cause I know imageUrl but not .epub file url. How should I do? I store fileName, imageUrl in Firestore but I don't know epub file's url . So I can't store it.
downloadFile(fileName,imageUrl) async{
Dio dio=Dio();
final storageRef=FirebaseStorage.instance.ref();
final imageUrls =await storageRef.child("Featured").child('a clock orange/Anthony-Burgess-A-Clockwork-Orange-W.-W.-Norton-_-Company-_1986_.epub').getDownloadURL();
String savePath= await getPath(fileName);
dio.download(imageUrls, savePath,
onReceiveProgress: (rcv,total){
setState((){
progress=((rcv/total) *100).toStringAsFixed(0);
});
if (progress == '100') {
setState(() {
isDownloaded = true;
});
}
}).then((_){
if (progress=="100"){
setState(() {
isDownloaded=true;
});
}
});}
I tried this. But it didn't work.
.
Use Firebase's writeToFile instead of dio's download.
final fileRef = storageRef.child("<path here>");
final appDocDir = await getApplicationDocumentsDirectory();
final filePath = "${appDocDir.absolute}/<path here>";
final file = File(filePath);
final downloadTask = fileRef.writeToFile(file);
downloadTask.snapshotEvents.listen((taskSnapshot) {
...
}
See Download to a local file for details.

Download file to Device download folder in Flutter

I'm trying to download files in my flutter app using the dio plugin for which I have to specify a "savePath". But using path_provider I can only see ApplicationDocumentsDirectory, ExternalStorageDirectory etc. My idea is to simply show the file(pdf) in the device's Download Folder, so whenever the user wants to view the file, he just goes to the folder and clicks it.
Saving to ApplicationDocumentsDirectory (as I understood it) would require me to provide a link (of sorts) to the file in the app, meaning the user would have to open my app every time he wants to view files downloaded through my app.
I just want the files to be available in the DownLoads Folder, just like with so many files we download directly to the DownLoads Folder.
Am I missing something here? pls enlighten me!
Added this code on request from user in comments:
var dir;
Future < dynamic > downloadFile(url, filename) async {
Dio dio = Dio();
try {
// checkPermission();
//if(Externa)
dir = await getApplicationDocumentsDirectory();
if (dir.path != null)
print("url:$url");
print("path:${dir.path}/$filename");
if (await File("${dir.path}/$filename").exists()) {
setState(() {
filePath = "${dir.path}/$filename";
});
return;
}
await dio.download(url, "${dir.path}/$filename",
onReceiveProgress: (rec, total) {
print("Rec: $rec , Total: $total");
setState(() {
downloading = true;
progressString = ((rec / total) * 100).toStringAsFixed(0) + "%";
});
});
} catch (e) {
print("downloadErr:$e");
}
setState(() {
downloading = false;
progressString = "Concluido";
filePath = "${dir.path}/$filename";
});
}
You can use downloads_path_provider for it
https://pub.dev/packages/downloads_path_provider
import 'package:downloads_path_provider/downloads_path_provider.dart';
Future<Directory> downloadsDirectory = DownloadsPathProvider.downloadsDirectory;

Flutter save Image in Gallery folder

I am currently working on an alert box with the option to take a photo or select a picture from the gallery.
The status so far is:
I can get pictures from the gallery with the ImagePicker, this works perfectly.
Now I come to my problem:
Saving the captured images also works, but it is saved in the storage and therefore not displayed in the gallery. Please help me
Image AlertBox: https://imgur.com/a/IhZ5Sgh
Image Empty rencent folder
https://imgur.com/a/W3FvPtS
Made pictures: https://imgur.com/a/VIZOTBH
Here is the path where the image is stored:
File: '/storage/emulated/0/Android/data/com.example.supportanfrage/files/Pictures/1cd284f4-3632-4ed8-8c6a-14d7be83a8335698897692938961258.jpg'
Methode for saving images
Future getAndSaveImage() async {
final File image = await ImagePicker.pickImage(source: ImageSource.camera);
debugPrint(image.toString());
if (image == null) return;
final directory = await getExternalStorageDirectory();
final String path = directory.path;
this._fileName = path;
final File localImage = await image.copy(path);
}
I using the following dependencies / plugins:
file_picker: ^1.3.8
camera: ^0.5.2+2
image_picker: ^0.6.0+17
image_gallery_saver: ^1.1.0
path_provider: ^1.1.2
Thanks.
This is the sample source code provided for the flutter camera plugin. It will take timeStamp and then save your photo with the name of that timeStampValue.jpg in your phone storage.
Future<String> takePicture() async {
if (!controller.value.isInitialized) {
return null;
}
String timestamp() => DateTime.now().millisecondsSinceEpoch.toString();
final Directory extDir = await getApplicationDocumentsDirectory();
final String dirPath = '${extDir.path}/Pictures/flutter_test';
await Directory(dirPath).create(recursive: true);
final String filePath = '$dirPath/${timestamp()}.jpg';
if (controller.value.isTakingPicture) {
return null;
}
try {
await controller.takePicture(filePath);
} on CameraException catch (e) {
return null;
}
return filePath;
}