Save images in a custom folder in the gallery - flutter

Im new at Flutter and im trying to add images taken in my app to a custom folder in the gallery. Its the same as on WhatsApp, if you take a picture in a chat the WhatsApp create a custom folder called WhatsApp Images.
For that, I tried this:
Future<bool> saveFile(String url, String fileName) async {
Directory directory;
try {
if (Platform.isAndroid) {
if (await _requestPermission(Permission.storage)) {
directory = (await getExternalStorageDirectory())!;
String newPath = '';
List<String> folders = directory.path.split('/');
for (int x = 1; x < folders.length; x++) {
String folder = folders[x];
if (folder != 'Android') {
newPath += '/$folder';
} else {
break;
}
}
newPath = '$newPath/OnlaineApp';
directory = Directory(newPath);
} else {
return false;
}
} else {
if (await _requestPermission(Permission.photos)) {
directory = await getTemporaryDirectory();
} else {
return false;
}
}
if (!await directory.exists()) {
await directory.create(recursive: true);
}
if (await directory.exists()) {
File saveFile = File('${directory.path}/$fileName');
await dio.download(url, saveFile.path,
onReceiveProgress: (downloaded, totalSize) {
setState(() {
progress = downloaded / totalSize;
});
});
if (Platform.isIOS) {
await ImageGallerySaver.saveFile(
saveFile.path,
isReturnPathOfIOS: true,
);
}
return true;
}
} catch (e) {
print(e);
}
return false;
}
Future<bool> _requestPermission(Permission permission) async {
if (await permission.isGranted) {
return true;
} else {
var result = await permission.request();
if (result == PermissionStatus.granted) {
return true;
} else {
return false;
}
}
}
downloadFile() async {
setState(() {
loading = true;
});
bool downloaded = await saveFile(
'lib/assets/images/fundo_interno.png',
'OnlaineApp Imagens',
);
if (downloaded) {
print('File downloaded');
} else {
print('Problem downloaded file');
}
setState(() {
loading = false;
});
}
I already add in Android>app>src>main> AndroidManifest.xml these lines of code (for permission):
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
...
android:requestLegacyExternalStorage="true"
The problem I got is: I/flutter ( 5424): FileSystemException: Creation failed, path = '/storage/emulated/0/OnlaineApp' (OS Error: Permission denied, errno = 13)

Related

Flutter: PlatformException (PlatformException(, cannot find the file, null, null)) on FlutterAudioRecorder2

class AudioRecorder {
static DateTime now = DateTime.now();
static String timestamp = now.toString();
var recorder = FlutterAudioRecorder2("./file_path",
audioFormat: AudioFormat.AAC);
// or var recorder = FlutterAudioRecorder2("file_path.mp3");
startRecording() async {
await recorder.initialized;
await recorder.start(); // <- error here
}
stopRecording() async {
var result = await recorder.stop();
}
}
I can't find a way to fix , mainly because I don't understand what does it means, why it says "cannot find the file" but the file needs to be created? (since it's a recording?)
Few points I noticed are
Please check if its initialised or not in the initstate
await recorder.initialized;
//after initialisation add this
var current = await recorder.current(channel: 0);
//you should get the current status as initialised if its done properly.
then on start recording use
await recorder.start()
Also make sure that the file path is right
Edit
This is the code to init the recorder
_init() async {
try {
bool hasPermission = await FlutterAudioRecorder2.hasPermissions ?? false;
if (hasPermission) {
String customPath = '/flutter_audio_recorder_';
io.Directory appDocDirectory;
// io.Directory appDocDirectory = await getApplicationDocumentsDirectory();
if (io.Platform.isIOS) {
appDocDirectory = await getApplicationDocumentsDirectory();
} else {
appDocDirectory = (await getExternalStorageDirectory())!;
}
// can add extension like ".mp4" ".wav" ".m4a" ".aac"
customPath = appDocDirectory.path + customPath + DateTime.now().millisecondsSinceEpoch.toString();
_recorder = FlutterAudioRecorder2(customPath, audioFormat: AudioFormat.AAC);
await _recorder!.initialized;
// after initialization
var current = await _recorder!.current(channel: 0);
print(current);
// should be "Initialized", if all working fine
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("You must accept permissions")));
}
} catch (e) {
print(e);
}
}

I try to write voice content to external file it work good but if I record for 1 minute or 20 seconds the size of file is 64 byte why

" i use flutte sound package "
"saveFile function get the path of file and the fileName and save it to external file "
Future<bool> saveFile(Uint8List url,String fileName) async {
Directory? directory;
directory = await getApplicationDocumentsDirectory();
/// print("direcory ===>"+directory.path.toString());
try {
if (Platform.isAndroid) {
directory = await getExternalStorageDirectory();
if (await _requstPermission(Permission.storage) &&
await _requstPermission(Permission.accessMediaLocation) &&
await _requstPermission(Permission.manageExternalStorage)) {
String newPath = "";
List<String> folders = directory!.path.split("/");
for (int i = 1; i < folders.length; i++) {
String folder = folders[i];
if (folder != "Android") {
newPath += "/" + folder;
} else {
break;
}
}
newPath = "/storage/emulated/0/Android/SpaChat2/";
directory = Directory(newPath);
//print(directory.path);
} else {
return false;
}
} else {
}
if (!await directory.exists()) {
await directory.create(recursive: true);
}
if (await directory.exists()) {
File audioFile = File(
directory.path +fileName.split("/").last);
print("//////////////////////////////////////////////");
// print(bytes);
print("url =============================================="+utf8.decode(url));
await audioFile.writeAsBytes(url);
return true;
}
} catch (e) {
print(e);
}
return false;
}
" _requstPermission get permission for access device resource "
Future<bool> _requstPermission(Permission permission) async {
if (await permission.isGranted) {
return true;
} else {
var res = await permission.request();
if (res == PermissionStatus.granted) {
return true;
} else {
return false;
}
}
}
" starting record voice"
void startRecord() async {
try {
_myRecorder.stopRecorder();
} catch (e) {}
currentDuration.value = Duration.zero;
try {
bool hasStorage = await _requstPermission(Permission.storage);
bool hasMic = await _requstPermission( Permission.microphone);
if (!hasStorage || !hasMic) {
if (!hasStorage) await _requstPermission(Permission.storage);
if (!hasMic) await _requstPermission( Permission.microphone);
print('[chat_composer] 🔴 Denied permissions');
return;
}
if (onRecordStart != null) onRecordStart!();
Directory dir = await getApplicationDocumentsDirectory();
String path = dir.path +
'/' +
DateTime.now().millisecondsSinceEpoch.toString() +
'.aac';
pathToSaveAudio=path;
await _myRecorder.startRecorder(
toFile: pathToSaveAudio,
//codec: Codec.aacADTS,
);
emit(RecordAudioStarted());
} catch (e) {
emit(RecordAudioReady());
}
}
" stopRecord functon stop recording after stop record voice it call saveFile function and add the path of voice to saveFile arguments "
void stopRecord() async {
// timer.cancel();
try {
String? result = await _myRecorder.stopRecorder();
if (result != null) {
// tempPath =result;
print('[chat_composer] 🟢 Audio path: "$result');
onRecordEnd(result);
Uint8List bytes = Utf8Encoder().convert(pathToSaveAudio);
saveFile(bytes,pathToSaveAudio);
}
} finally {
currentDuration.value = Duration.zero;
}
emit(RecordAudioReady());
}

FileSystemException: Cannot copy file ' (OS Error: Is a directory, errno = 21)

I am trying to copy a sqflite database file from this path (getDatabasesPath()) to external storage,but I got this exception:
FileSystemException: Cannot copy file to '/storage/emulated/0/databaseBackup', path = '/data/user/0/com.example.project/databases/roznamcha.db' (OS Error: Is a directory, errno = 21)
My code:
Future<bool> _requestPermission(Permission permission) async {
if (await permission.isGranted) {
return true;
} else {
var result = await permission.request();
if (result == PermissionStatus.granted) {
return true;
}
}
return false;
}
Future<bool> createDirectory() async {
Directory directory;
try {
if (Platform.isAndroid) {
if (await _requestPermission(Permission.storage)) {
directory = await getExternalStorageDirectory();
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 + "/databaseBackup";
directory = Directory(newPath);
} else {
return false;
}
} else {
if (await _requestPermission(Permission.photos)) {
directory = await getTemporaryDirectory();
} else {
return false;
}
}
if (!await directory.exists()) {
await directory.create(recursive: true);
}
if (await directory.exists()) {
final pathdb = await getDatabasesPath();
// join database name and database path
final path = join(pathdb, 'roznamcha.db');
print('path ra print ko: $path');
File f = File(path);
var cop = await f.copy(directory.path);
print(directory.path);
print('copy file $cop');
}
} catch (e) {
print(e);
}
return false;
}
I added permission_handler package and also permission configuration to AndroidManiFaes.xml but I still get this error.

Flutter download file in phone storage

I am not able to download file in the phone storage.. My code is..
Future<void> downloadFile() async {
Dio dio = Dio();
bool checkPermission1 =
await SimplePermissions.checkPermission(permission1);
print('checkPermission1');
print(checkPermission1);
if (checkPermission1 == false) {
await SimplePermissions.requestPermission(permission1);
checkPermission1 = await SimplePermissions.checkPermission(permission1);
}
if (checkPermission1 == true) {
String dirloc = "";
if (Platform.isAndroid) {
dirloc = "/sdcard/downloads/";
} else {
dirloc = (await getApplicationDocumentsDirectory()).path;
}
try {
FileUtils.mkdir([dirloc]);
await dio.download(url, dirloc + id + ".mp4",
onReceiveProgress: (receivedBytes, totalBytes) {
setState(() {
downloadingFlag = true;
progress =
((receivedBytes / totalBytes) * 100).toStringAsFixed(0) + "%";
});
});
} catch (e) {
print(e);
}
setState(() {
downloadingFlag = false;
downloadsFlag = false;
progress = "Download Completed.";
path = dirloc + id + ".mp4";
});
} else {
setState(() {
progress = "Permission Denied!";
});
}
}
I/flutter (23004): FileSystemException: Creation failed, path = '/sdcard/downloads' (OS Error: Permission denied, errno = 13)

readAsBytesSync is incomplete

Since I can't convert convert a file directly from url (e.g File(url)).
I am downloading the file and then use the temp file path.
I tried different files : images, pdfs and it's still incomplete.
Am I doing something wrong here?
Future<String> downloadFile() async {
print(imgUrl);
Dio dio = Dio();
try {
var dir = await getApplicationDocumentsDirectory();
await dio.download(imgUrl, "${dir.path}/${widget.name}.pdf",
onReceiveProgress: (rec, total) {});
path = "${dir.path}/${widget.name}.pdf";
setState(() {
downloading = false;
progressString = "Completed";
});
if (path != null) {
List<int> imageBytes = File(path).readAsBytesSync();
print("NEW BYTE : $imageBytes");
}
} catch (e) {
print(e);
}
return path;
}
Checkout this solution:-
https://gist.github.com/Nitingadhiya/3e029e2475eeffac311ecd76f273941f
Uint8List? _documentBytes;
getPdfBytes() async {
_documentBytes = await http.readBytes(Uri.parse('https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf'));
return _documentBytes;
}
Future<void> readPDf() async {
//Load the existing PDF document.
Uint8List documentInBytes = await getPdfBytes();
final PdfDocument document = PdfDocument(inputBytes: documentInBytes);
//Get the existing PDF page.
final PdfPage page = document.pages[0];
//Draw text in the PDF page.
page.graphics.drawString('Hello World!', PdfStandardFont(PdfFontFamily.helvetica, 12), brush: PdfSolidBrush(PdfColor(0, 0, 0)), bounds: const Rect.fromLTWH(0, 0, 150, 20));
//Save the document.
final List<int> bytes = await document.save(); //document.saveSync();
await saveAndLaunchFile(bytes, 'Invoice.pdf');
//Dispose the document.
document.dispose();
}
Future<void> saveAndLaunchFile(List<int> bytes, String fileName) async {
//Get the storage folder location using path_provider package.
String? path;
if (Platform.isAndroid || Platform.isIOS || Platform.isLinux || Platform.isWindows) {
final Directory directory = await path_provider.getApplicationSupportDirectory();
path = directory.path;
} else {
path = await PathProviderPlatform.instance.getApplicationSupportPath();
}
final File file = File(Platform.isWindows ? '$path\\$fileName' : '$path/$fileName');
await file.writeAsBytes(bytes, flush: true);
if (Platform.isAndroid || Platform.isIOS) {
//Launch the file (used open_file package)
// await open_file.OpenFile.open('$path/$fileName');
} else if (Platform.isWindows) {
await Process.run('start', <String>['$path\\$fileName'], runInShell: true);
} else if (Platform.isMacOS) {
await Process.run('open', <String>['$path/$fileName'], runInShell: true);
} else if (Platform.isLinux) {
await Process.run('xdg-open', <String>['$path/$fileName'], runInShell: true);
}
}