How to create folder in device storage to save files?
This is the code to download file into device :
import 'package:flutter_downloader/flutter_downloader.dart';
onTap: () async { //ListTile attribute
Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path;
final taskId = await FlutterDownloader.enqueue(
url: 'http://myapp/${attach[index]}',
savedDir: '/sdcard/myapp',
showNotification: true, // show download progress in status bar (for Android)
clickToOpenDownloadedFile: true, // click on notification to open downloaded file (for Android)
);
},
You can create directory when app is launched.
In the initState() method of your first screen do the logic.
Ex.
createDir() async {
Directory baseDir = await getExternalStorageDirectory(); //only for Android
// Directory baseDir = await getApplicationDocumentsDirectory(); //works for both iOS and Android
String dirToBeCreated = "<your_dir_name>";
String finalDir = join(baseDir, dirToBeCreated);
var dir = Directory(finalDir);
bool dirExists = await dir.exists();
if(!dirExists){
dir.create(/*recursive=true*/); //pass recursive as true if directory is recursive
}
//Now you can use this directory for saving file, etc.
//In case you are using external storage, make sure you have storage permissions.
}
#override
initState(){
createDir(); //call your method here
super.initState();
}
You need to import these libraries:
import 'dart:io';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
From what I saw is, you are not using appDocDir and appDocPath anywhere, cause you are saving files in /sdcard/myapp.
Please check if you are asking and granting the storage permission and also there is no way to store files in sdcard like you are doing. Either make use of predefined directories like (Document, Pictures etc.) or use device root directory that starts with storage/emulated/0
//add in pubspec.yaml
path_provider:
//import this
import 'dart:io' as io;
import 'package:path_provider/path_provider.dart';
//create Variable
String directory = (await getApplicationDocumentsDirectory()).path;
//initstate to create directory at launch time
#override
void initState() {
// TODO: implement initState
super.initState();
createFolder();
}
//call this method from init state to create folder if the folder is not exists
void createFolder() async {
if (await io.Directory(directory + "/yourDirectoryName").exists() != true) {
print("Directory not exist");
new io.Directory(directory + "/your DirectoryName").createSync(recursive: true);
//do your work
} else {
print("Directoryexist");
//do your work
}
}
Here is the Sample Codefor Creating a folder in Users internal storage Hope it Helps You
import 'dart:io' as Io;
Future _downloadImage() async {
try {
// request runtime permission
final permissionHandler = PermissionHandler();
final status = await permissionHandler
.checkPermissionStatus(PermissionGroup.storage);
if (status != PermissionStatus.granted) {
final requestRes = await permissionHandler
.requestPermissions([PermissionGroup.storage]);
if (requestRes[PermissionGroup.storage] != PermissionStatus.granted) {
_showSnackBar('Permission denined. Go to setting to granted!');
return _done();
}
}
}
var testdir =
await new Io.Directory('/storage/emulated/0/MyApp').create(recursive: true);
final filePath =
path.join(testdir.path, Filename + '.png');
print(filePath);
final file = File(filePath);
if (file.existsSync()) {
file.deleteSync();
}
//save image to storage
var request = await HttpClient().getUrl(Uri.parse(imageUrl));
var response = await request.close();
final Uint8List bytes = await consolidateHttpClientResponseBytes(response);
final saveFileResult =
saveImage({'filePath': filePath, 'bytes': bytes});
_showSnackBar(
saveFileResult
? 'Image downloaded successfully'
: 'Failed to download image',
);
} on PlatformException catch (e) {
_showSnackBar(e.message);
} catch (e, s) {
_showSnackBar('An error occurred');
debugPrint('Download image: $e, $s');
}
return _done();
}
First you need to import
1) import 'dart:io';
Second you need to create directory for the specified path in your async/await function
2) For example:
await new Directory('/storage/emulated/0/yourFolder').create(recursive: true);
Related
I'm trying to save the video in the phone gallery (downloaded using dio package) To get the path, I'm using path provider package but unable to save it in the phone gallery
Here is my code
void downloadVideo() async {
var dir = await getExternalStorageDirectory();
final dio = Dio();
dio.download(
'video_url',
'${dir!.path}/video.mp4', // saving path, I'm trying to save it in phone gallery
onReceiveProgress: (actualBytes, totalBytes){
var percentage = actualBytes/totalBytes*100;
}
);
}
Note:- I'm aware of gallery_saver package but I need to achieve this using dio and path provider
So you already have the saving directory. You can use plugins like image_gallery_saver and gallery_saver to save your downloaded video to the gallery.
If you use image_gallery_saver, the saving code would be similar to this:
await ImageGallerySaver.saveFile(finalVideoPath);
And don't forget to delete the video in the download path after saving the video successfully to the gallery.
Final code:
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/widgets.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
Future<void> downloadVideo() async {
final appDocDirectory = await getAppDocDirectory();
final finalVideoPath = join(
appDocDirectory.path,
'Video-${DateTime.now().millisecondsSinceEpoch}.mp4',
);
final dio = Dio();
await dio.download(
'video_url',
finalVideoPath,
onReceiveProgress: (actualBytes, totalBytes) {
final percentage = actualBytes / totalBytes * 100;
},
);
await saveDownloadedVideoToGallery(videoPath: finalVideoPath);
await removeDownloadedVideo(videoPath: finalVideoPath);
}
Future<Directory> getAppDocDirectory() async {
if (Platform.isIOS) {
return getApplicationDocumentsDirectory();
}
return (await getExternalStorageDirectory())!;
}
Future<void> saveDownloadedVideoToGallery({required String videoPath}) async {
await ImageGallerySaver.saveFile(videoPath);
}
Future<void> removeDownloadedVideo({required String videoPath}) async {
try {
Directory(videoPath).deleteSync(recursive: true);
} catch (error) {
debugPrint('$error');
}
}
I have tried this code below but an empty folder i have found and still cannot create a file, but no errors found in the terminal.
here is the packages i have used :
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';
this is the codes to create the file, is there something wrong:
Future<String> getFilePath() async {
Directory? appExtDirectory = await getExternalStorageDirectory();
String appExtPath = appExtDirectory.toString();
print('$appExtPath');
return appExtPath;
}
Future<File> get _localFile async {
final path = await getFilePath();
return File('$path/counter.txt');
}
Future<File> writeCounter() async {
final file = await _localFile;
// Write the file
return file.writeAsString("This is my demo text that will be saved to : counter.txt");
}
void saveFile() {
writeCounter();
}
Regards..
Try String appExtPath = appExtDirectory.path;
I'm trying to export a txt file as srt (which is written in plain text) in my app and it is working in the sense that I see srt's with the correct name in the specified folder but these files are 0B and I'm not sure where what is not fully working?
void add() async {
fileName = _fileNameCon.text.toString();
print("filename ---------> " + fileName);
newSubFile(fileName);
setState(() {
_fileNameCon.clear();
srt = "";
subnumber = 1;
stopWatch.reset();
});
}
void newSubFile(String title) async {
try {
// this is an android specific directory
Directory directory = await getExternalStorageDirectory();
final path = directory.path;
File newSrt = await File('$path/' + title + ".srt").create();
var writer = newSrt.openWrite();
print("----attempting to write to $path/$title----");
writer.write(srt);
writer.close();
print("----closing----");
} catch (e) {
print(e);
}
}
Imports
import 'dart:io'
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
Example:
Directory dir = await getExternalStorageDirectory();
final file = File(join('${dir.parent}/sub folder',"Output.srt"));
await file.writeAsString(subtitles)
I am working on a Flutter project to syntehsise an string to an audio file. For this reason, I have added flutter_tts as a dependency and implemented the following method with different approaches in order to check the existence of the generated file:
/// Synthesises the current audio cue into an audio file
static Future<void> synthesiseStringToAudioFile() async {
Future<String> finalPath;
Future<File> finalFile;
Uri uriToFile;
String absolutePath;
bool existsPath;
bool existsManually;
bool exists3;
await flutterTts
.synthesizeToFile("This is my first audio synthesizer in Flutter",
audioFileName)
.then((value) => {
// File has been successfully created
if (value == 1)
{
// Gets the path to the generated audio file
finalPath = pathToFile,
finalPath.then((path) async => {
print('AFile :Path to audio file: $path'),
// Check if exists
existsPath = FileSystemEntity.typeSync(path) != FileSystemEntityType.notFound,
print("AFile : Exists? $existsPath"),
existsManually = await File('/storage/emulated/0/Android/data/mypath/files/temp_audio_cue.wav').exists(), // Requieres async function
print("AFile : Exists2? $existsManually"), // RETURNS TRUE
exists3 = await File(path).exists(),
print("AFile : Exists3? $exists3")
}),
// Gets the generated file
finalFile = localFile,
finalFile.then((file) => {
// Absolute path
absolutePath = file.absolute.path,
print('AFile : AbsolutePath: $absolutePath'),
// Check the URI
uriToFile = file.uri,
print('AFile : URI to audio file: $uriToFile'),
}),
}
else
{print('There was an error during the synthezisation')}
});
}
static void setAudioFileName() {
audioFileName = Platform.isAndroid ? "temp_audio_cue.wav" : "temp_audio_cue.caf";
}
/// Gets the path to the file to be accessed
static Future<String> get pathToFile async {
final path = await localPath;
return '$path/$audioFileName';
}
/// Gets the path to the local directory
static Future<String> get localPath async {
final dir = await getApplicationDocumentsDirectory();
return dir.path;
}
Once the synthesisation is completed, flutterTts.synthesizeToFile() logs in console the following message:
D/TTS (10335): Successfully created file :
/storage/emulated/0/Android/data/mypath/files/temp_audio_cue.wav
so if I check the existence of the file manually (as I do with existManually) will get a true value, but I am not able to do it trying to get dynamically the path as in the other examples I am trying but the ones I am getting are:
/data/user/0/mypath/app_flutter/temp_audio_cue.wav
so it is missing the beginning
/storage/emulated/0/Android/
I was wondering what is the correct way to get the path to the file (missing)?
With path_provider in Android save in getExternalStorageDirectory and in iOS save in getApplicationDocumentsDirectory..
If you want to get this path : /storage/emulated/0
Use path_provider_ex package, which provides root and app files directory for both "external storage" (internal flash) and SD card (if present), as well as available space for each storage.
you can use path_provider package of flutter
Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path;
https://pub.dev/packages/path_provider
I am using filesystem_picker to return absolute paths from storage and then using File('path_string') or Directory('path_string') to get the actual file.
Using manageExternalStorage permissions allows this work, but keep in mind:
"The Google Play store has a policy that limits usage of MANAGE_EXTERNAL_STORAGE".
This also may not work depending on the SDK you are using and/or conflicts from other packages.
import 'package:filesystem_picker/filesystem_picker.dart';
import 'package:permission_handler/permission_handler.dart';
Directory? rootDir;
late String tempDir;
_getFile(){
await _pickFile();
String path = tempDir;
var file = File(path);
// Do stuff with file
}
// Call this before _pickFile(), ideally inside initState()
Future<void> _prepareStorage() async {
rootDir = Directory('/storage/emulated/0/');
var storageExternal = await Permission.manageExternalStorage.status;
if (storageExternal != PermissionStatus.granted) {
await Permission.manageExternalStorage.request();
}
bool b = storageExternal == PermissionStatus.granted;
//mPrint("STORAGE ACCESS IS : $b");
}
Future<void> _pickFile(BuildContext context) async {
await FilesystemPicker.open(
title: 'Select file',
context: context,
rootDirectory: rootDir!,
fsType: FilesystemType.file,
pickText: 'Select file to add',
folderIconColor: Colors.teal,
requestPermission: () async => await Permission.manageExternalStorage.request().isGranted,
).then((value){
if (value != null){
tempDir = value.toString();
}
else{
tempDir = "";
}
//mPrint(tempDir);
});
}
Add the following to AndroidManifest.xml:
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:minSdkVersion="30" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:label="test_flutter"
android:name="${applicationName}"
android:icon="#mipmap/ic_launcher"
android:requestLegacyExternalStorage="true"
>
I tried and it worked
import 'package:path_provider/path_provider.dart';
Future<File> getImageFileFromAssets(Asset asset) async {
final byteData = await asset.getByteData();
final tempFile =
File("${(await getTemporaryDirectory()).path}/${asset.name}");
final file = await tempFile.writeAsBytes(
byteData.buffer
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes),
);
return file;
}
I want to download images and save it to storage in a unique directory name using dio and path_provider.but i have an error:
I/flutter (15977): FileSystemException: Cannot open file,
path = '/data/user/0/com.manga.indonesia.manga.suka/app_flutter/sensei-wa-koi-o-oshie-rarenai-chapter-7-bahasa-indonesia/0.jpg'
How can i make this sensei-wa-koi-o-oshie-rarenai-chapter-7-bahasa-indonesia directory?
My code :
downloadChapter(chapter) async {
Response res;
Dio dio = new Dio();
var dir = await getApplicationDocumentsDirectory();
try {
res = await dio
.get('http://0.0.0.0:8080/api/MangaSuka/kchapters/' + chapter);
var contentChapter = res.data['content'].where((a) {
return a != null;
}).toList();
for (var i = 0; i < contentChapter.length; i++) {
await dio.download(contentChapter[i], "${dir.path}/${chapter}/$i.jpg",
onProgress: (rec, total) {
print("Rec: $rec , Total: $total");
});
};
return print(contentChapter);
} catch (e) {
return print(e);
}
}
It is well explained in flutter documentation:
import 'dart:io';
void main() {
new Directory('sensei-wa-koi-o-oshie-rarenai-chapter-7-bahasa-indonesia').create()
// The created directory is returned as a Future.
.then((Directory directory) {
print(directory.path);
});
}
However, in many situations, like creating one directory, perhaps the async (default) version of Directory.create will not be time saving and could perhaps result in race condition. In that case, using the sync version of the command would be more appropriate:
new Directory('sensei-wa-koi-o-oshie-rarenai-chapter-7-bahasa-indonesia').createSync()
// ... following sequential code
Of note, many dart::io methods have *Sync versions.
import 'package:path_provider_ex/path_provider_ex.dart';
import 'dart:io';
import 'package:simple_permissions/simple_permissions.dart';
//packages
// simple_permissions: ^0.1.9
// path_provider_ex:
//Android mainfest
// <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
// <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
main(){
List<StorageInfo> _storageInfo = [];
#override
void initState() {
super.initState();
initPlatformState();
Timer(Duration(seconds: 2), () {
createFolder();
});
}
createFolder() async {
PermissionStatus permissionResult =
await SimplePermissions.requestPermission(
Permission.WriteExternalStorage);
if (permissionResult == PermissionStatus.authorized) {
// Directory _appFile = Directory(_storageInfo[0].rootDir + '/MyTestFOlder');
// _appFile.create();
new Directory(_storageInfo[0].rootDir + '/MyCreatedFolder').create()
// The created directory is returned as a Future.
.then((Directory directory) {
print(directory.path);
});
// File ourTempFile = File(_appFile.path);
// print(ourTempFile.path);
// ourTempFile.create();
// code of read or write file in external storage (SD card)
}
}
}
Create several directories using recursive: true
import 'dart:io';
...
var directory = await Directory('dir/subdir').create(recursive: true);
Check out the official information.