How do I make a separate folder for my app and store images there? Flutter - flutter

Hey guys so I wish to make a new folder for my app under Android and then store images there which will be retrieved for future use.
Here's what I have tried -
Future<bool> LocalImage(String url) async {
Directory directory;
var dio = Dio();
try {
if (Platform.isAndroid) {
if (await _requestPermission(Permission.storage) &&
// access media location needed for android 10/Q
await _requestPermission(Permission.accessMediaLocation) &&
// manage external storage needed for android 11/R
await _requestPermission(Permission.manageExternalStorage)) {
directory = (await getExternalStorageDirectory()) as Directory;
String newPath = "";
print(directory);
List<String> paths = directory.path.split("/");
for (int x = 1; x < paths.length; x++) {
String folder = paths[x];
if (folder != "Android") {
newPath += "/" + folder;
} else {
break;
}
}
newPath = newPath + "/Verif-ID";
if (await Directory(newPath).exists()){
;
}
else{ directory = Directory(newPath);
}
} else {
return false;
}
} else {
if (await _requestPermission(Permission.photos)) {
directory = await getTemporaryDirectory();
} else {
return false;
}
}
if (await directory.exists()) {
File saveFile = File(directory.path );
await dio.download(url, saveFile.path,);
return true;
}
} catch (e) {
print(e);
}
return false;
}
The issues I am currently facing are-
1.It does make a new folder by that name but no download is happening
2. I keep getting the following in my console
FileSystemException: Cannot create file, path = '/storage/emulated/0/Android/data/com.example.id_me/files' (OS Error: Is a directory, errno = 21)
I understand that this error must mean that a folder of the name already exists but I thought my if conditions were checking that but I guess not. My logics are not the best haha.
This is my first flutter app so I am very sorry if this was a silly doubt.
The URL will be from my firebase database.

Add a file name to a directory path.
savePath: The path to save the downloading file later. A path with String type, eg "xs.jpg"
await dio.download(url, saveFile.path + "/xs.jpg")
See download for details.

Related

ffmpeg kit flutter video compressor

I am not experienced with ffmpeg. So I'm sorry if I'm asking the wrong question in the wrong place.
i am trying to make a video compressor, i add the dependency exactly like : ffmpeg_kit_flutter_full_gpl: ^4.5.1
and The code I wrote is like:
compress(path) {
FFmpegKit.executeAsync("-i $path -c:a copy -c:v libx264 -s 848x360 output.mp4", (session) async {
final returnCode = await session.getReturnCode();
if (ReturnCode.isSuccess(returnCode)){
print("işlem başarılı");
// SUCCESS
} else if (ReturnCode.isCancel(returnCode)) {
print("iptal edildi");
// CANCEL
} else {
print("hata oluştu");
print(await session.getFailStackTrace());
// ERROR
}
});
}
and im calling this method like:
asset.originFile.then((fle) {
var path = fle!.path;
compress(path);
}
);
it always returns error condition for some reason. and session.getFailStackTrace() is null.
My first question is what do you think is wrong here?
And secondly how can I detect what the error is in such cases?
thanks in advance :)
At the end, with advice of #kesh , i used this code for see the error;
FFmpegKitConfig.enableLogCallback((log) {
final message = log.getMessage();
print(message);
});
And as i figure out, if your videos name contains space or special character, FFmpeg kit gives error. So, i generate random names for input file and output file and rename them..
And if any body needs a ffmpeg video compressor, i'm leaving the code:
my depency at pubspec.yaml ;
ffmpeg_kit_flutter_full_gpl: ^4.5.1
and im generating new name like:
asset.originFile.then((fle) {
const _chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890';
Random _rnd = Random();
String getRandomString(int length) => String.fromCharCodes(Iterable.generate(
length, (_) => _chars.codeUnitAt(_rnd.nextInt(_chars.length))));
String newName = getRandomString(15);
String newInput = getRandomString(16);
var outputPath = fle!.path.toString().split('/');
outputPath.remove(outputPath[(outputPath.length)-1]);
var out = outputPath.join('/');
String output = out + "/" + newName + ".mp4";
String inputPath = out + "/" + newInput + ".mp4";
fle.rename(inputPath);
compress(inputPath, output);
}
and my compress function is:
compress(path, output) {
FFmpegKit.executeAsync("-y -i $path -vcodec libx264 -crf 22 $output", (Session session) async {
final returnCode = await session.getReturnCode();
if (ReturnCode.isSuccess(returnCode)){
print("işlem başarılı");
File lastVid = File(output);
//SUCCESS
} else if (ReturnCode.isCancel(returnCode)) {
print("iptal edildi");
// CANCEL
} else {
print("hata oluştu");
FFmpegKitConfig.enableLogCallback((log) {
final message = log.getMessage();
print(message);
});
// ERROR
}
});
}

Not able to upload image to server using flutter API integration

I am trying to send Form data to the backend using Flutter.
As a result, all the text type data is sent easily but my image file is not shared.
Help me Guys
uploadImage(
filepath,url) async {
EasyLoading.show(status: 'Uploading Data...');
try {
final result = await InternetAddress.lookup('example.com');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
var request = http.MultipartRequest('POST', Uri.parse(url));
print(filepath); *// this filepath is not empty*
request.files.add(await http.MultipartFile.fromPath('image', filepath));
request.headers.addAll(headers);
request.fields['name'] = _pName.text;
request.fields['store_id'] = store_id;
request.fields['seller_name'] = seller_name;
request.fields['seller_id'] = seller_id;
request.fields['product_id'] = 35.toString();
request.fields['stock_status_id'] = 6.toString();
request.fields['price'] = _pPrice.text;
request.fields['model'] = _pModel.text;
request.fields['sku'] = _pSKU.text;
request.fields['status'] = 1.toString();
request.fields['product_name'] = "Shoes Sport";
request.fields['is_approved'] = 1.toString();
request.fields['special'] = false.toString();
request.fields['quantity'] = _pQuantity.text;
var res = await request.send();
if(res.statusCode==200)
{
EasyLoading.showSuccess('Data is Uploaded!\n Waiting For Approval');
EasyLoading.dismiss();
print(res.reasonPhrase);
Navigator.pop(context);
}
print(request.fields);
// print(filepath);
}
}
on SocketException catch (_) {
EasyLoading.showError("Internet Connection is not available");
}
}
all the data is uploaded except image, i have also crosschecked the parameter its correct.
chek the spelling of "image" it should be same mention in your api doc and the one you are using, your code seems correct i was stuck at the same issue i was using the image key but the key was "profile " please do a recheck , let me know if this works

Error: Cannot run with sound null safety, because the following dependencies (flutter_absolute_path)

Does the flutter_absolute_path v1.0.6 dependency not support null safety? Is there any other solution to get absolute path of a file?
for (int i = 0; i < resultList.length; i++) {
var path = await
FlutterAbsolutePath.getAbsolutePath(resultList[i].identifier);
print(path + '**path**');
f.add(File(path));
}
Try this plugin file_picker file_picker: ^3.0.3
//use this line to pick files
FilePickerResult? result = await FilePicker.platform.pickFiles();
//use this to process what file is returned
if(result != null) {
File file = File(result.files.single.path);
} else {
// User canceled the picker
}
You can read about extra features here:
https://pub.dev/packages/file_picker

Flutter/Dart: Saving an image file to "/storage/emulated/0/Picture/AppFolder/"

using
final dir = await getExternalStorageDirectory();
Image get saved in
/storage/emulated/0/Android/data/com.example.flutter_app/files/
But I want to store it in ../0/Pictures/app_name/ so that it shows up in the gallery.
I looked up all over the www and couldn't figure out. Please advise.
You have to first extract the root Path from the returned location
rootPath = /storage/emulated/0/
than create the Pictures and app_name Directory (to avoid exception when the directory doesn't exist)
then save file in /storage/emulated/0/Pictures/app_name/
here's a simple example to help you understand:
...
Directory externalPath = (await getExternalStorageDirectory());
String picturesDirName = "Pictures";
String appNameDirName = "app_name";
// Splitting the externalPath
List<String> externalPathList = externalPath.path.split('/');
// getting Position of 'Android'
int posOfAndroidDir = externalPathList.indexOf('Android');
//Joining the List<Strings> to generate the rootPath with "/" at the end.
String rootPath = externalPathList.sublist(0, posOfAndroidDir).join('/');
rootPath+="/";
//Creating Pictures Directory (if not exist)
Directory picturesDir = Directory(rootPath+picturesDirName+"/");
if (!picturesDir.existsSync()) {
//Creating Directory
await picturesDir.create(recursive: true);
//Directory Created
} else {
//Directory Already Existed
}
//Creating "app_name" Directory (if not exist)
Directory appNameDir = Directory(rootPath+picturesDirName+"/"+appNameDirName+"/");
if (!appNameDir.existsSync()) {
//Creating Directory
await appNameDir.create(recursive: true);
//Directory Created
} else {
//Directory Already Existed
}
//Creating String varible to store the path where you want to save file.
String fileSaveLocation = rootPath+picturesDirName+"/"+appNameDirName+"/";
// Or you can also use templates like this
String fileSaveLocation2 = "$rootPath$picturesDirName/$appNameDirName/";
//Your File Path where you want to save you file.
String filePath = fileSaveLocation+"text.txt";
// Or you can also use templates like this
String filePath2 = "${fileSaveLocation2}test.txt";
...
You can optimize the above code as per your liking.
hope this is the solution you were looking.
Here, Is how you can acheive this,
final Directory extDir = await getExternalStorageDirectory();
String dirPath = '${extDir.path}/app_name/pictures';
dirPath = dirPath.replaceAll("Android/data/com.example.flutter_app/files/", "");
await Directory(dirPath).create(recursive: true);
// start File Operations Here with dirPath variable
Update:
Along with detailed answer below, I came across a couple of plugins which deals specially with media content.
From Flutter.dev docs:
The plugin currently supports access to two file system locations:
gallery_saver Plugin: See Full Example
GallerySaver.saveImage(path).then((bool success) {// code }
Image_gallery_saver: See Full Example
await ImageGallerySaver.saveImage(Uint8List.fromList(response.data), quality: 60, name: "hello");
Creating the path manually: Source
await Permission.storage.request();
if (await Permission.storage.isGranted) {
var dir = await getExternalStorageDirectory();
Dio dio = Dio();
var newPath = "";
List<String> paths = dir.path.split("/");
for (int x = 1; x < paths.length; x++) {
String folder = paths[x];
if (folder != "Android") {
newPath += "/" + folder;
}
else {
break;
}
}
var picfolder = "/Pictures/";
newPath = newPath + picfolder + AppStrings['AppName'];
Other Useful References:
Android Data Storage
MediaStore in Flutter

How to get the File Extension from a string Path

I've got file path saved in variable and I want to get the file type extension by using path package https://pub.dev/packages/path So far I managed to do it by splitting the string like this
final path = "/some/path/to/file/file.dart";
print(path.split(".").last); //prints dart
Is there any way to achieve this with path package?
You can use the extension function in the path package to get the extension from a file path:
import 'package:path/path.dart' as p;
final path = '/some/path/to/file/file.dart';
final extension = p.extension(path); // '.dart'
If your file has multiple extensions, like file.dart.js, you can specify the optional level parameter:
final extension = p.extension('file.dart.js', 2); // '.dart.js'
No need of any extension. You can try below code snippet.
String getFileExtension(String fileName) {
try {
return "." + fileName.split('.').last;
} catch(e){
return null;
}
}
This small function can parse filepath or url and find basename, extension and absolute path. It doesn't check file path exist and not check basename is folder or file.
Map parsePath(String filepath) {
Map p1 = new Map();
int ind1 = filepath.indexOf("://");
if (ind1 > 0) {
p1["fullpath"] = filepath;
} else {
p1["fullpath"] = File(filepath).absolute.path;
}
p1["path"] = filepath;
List<String> v = filepath.split("/");
if (v.length > 1) {
p1["basename"] = v.last;
} else if (filepath.split("\\").length > 1) {
p1["basename"] = filepath.split("\\").last;
} else {
p1["basename"] = v.last;
}
p1["extension"] = p1["basename"].split('.').last;
if (p1["basename"] == p1["extension"]) p1["extension"] = "";
return p1;
}