Flutter - How to save audio as a file? - android

I am using :
flutter_sound_lite to record some audio.
and path_provider to get path of my phone.
permission_handler
I am creating directories and a file with a specified path to put my recorded audio.
I wonder if i am not finding it or it doesn't get created.
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter_sound_lite/flutter_sound.dart';
import 'package:flutter_sound_lite/public/flutter_sound_recorder.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
class SoundRecorder {
FlutterSoundRecorder? _audioRecorder;
ModelApiShazam? modelApiShazam;
bool _isRecorderInitialised = false;
bool get isRecording => _audioRecorder!.isRecording;
Future init() async {
_audioRecorder = FlutterSoundRecorder();
final statusMic = await Permission.microphone.request();
if(statusMic != PermissionStatus.granted){
throw RecordingPermissionException('microphone permission');
}
final statusStorage = await Permission.storage.status;
if (!statusStorage.isGranted) {
await Permission.storage.request();
}
await _audioRecorder!.openAudioSession();
directoryPath = await _directoryPath();
completePath = await _completePath(directoryPath);
_createDirectory();
_createFile();
_isRecorderInitialised = true;
}
void dispose(){
if(!_isRecorderInitialised) return;
_audioRecorder!.closeAudioSession();
_audioRecorder = null;
_isRecorderInitialised = false;
}
Future _record() async{
if(!_isRecorderInitialised) return;
print("Path where the file will be : "+completePath);
await _audioRecorder!.startRecorder(
toFile: completePath,
numChannels : 1,
sampleRate: 44100,
);
}
Future _stop() async{
if(!_isRecorderInitialised) return;
var s = await _audioRecorder!.stopRecorder();
File f = File(completePath);
print("The created file : $f");
}
Future toggleRecording() async{
if(_audioRecorder!.isStopped){
await _record();
}else{
await _stop();
}
}
String completePath = "";
String directoryPath = "";
Future<String> _completePath(String directory) async {
var fileName = _fileName();
return "$directory$fileName";
}
Future<String> _directoryPath() async {
var directory = await getApplicationDocumentsDirectory();
var directoryPath = directory.path;
return "$directoryPath/records/";
}
String _fileName() {
return "record.wav";
}
Future _createFile() async {
File(completePath)
.create(recursive: true)
.then((File file) async {
//write to file
Uint8List bytes = await file.readAsBytes();
file.writeAsBytes(bytes);
print("FILE CREATED AT : "+file.path);
});
}
void _createDirectory() async {
bool isDirectoryCreated = await Directory(directoryPath).exists();
if (!isDirectoryCreated) {
Directory(directoryPath).create()
.then((Directory directory) {
print("DIRECTORY CREATED AT : " +directory.path);
});
}
}
}
output excluding flutter_sound :
I/flutter (20652): DIRECTORY CREATED AT : /data/user/0/com.example.shazam/app_flutter/records/
I/flutter (20652): FILE CREATED AT : /data/user/0/com.example.shazam/app_flutter/records/record.wav
I press the button to start the record...
I/flutter (20652): Path where the file will be : /data/user/0/com.example.shazam/app_flutter/records/record.wav
I press the button to end the record...
I/flutter (20652): The created file : File: '/data/user/0/com.example.shazam/app_flutter/records/record.wav'
I don't find where this file is located even if i am following the path

I founs the solution !
Just replace
var directory = await getApplicationDocumentsDirectory();
var directoryPath = directory.path;
by
var directory = await getExternalStorageDirectory();
var directoryPath = directory!.path;

Related

How to create and share the contact in flutter?

How to create the contact in locally with Name and phone number and share the created contact to other apps like whatsapp, social media's etc...
By using vcard_maintained library https://pub.dev/packages/vcard_maintained, we are able to create the contact, But not able to share through the apps.
I tried this,
import 'package:share_plus/share_plus.dart';
import 'package:vcard_maintained/vcard_maintained.dart';
var vCard = VCard();
vCard.firstName = 'FirstName';
vCard.middleName = 'MiddleName';
vCard.workPhone = '312-555-1212';
final path = await _localPath;
vCard.saveToFile('$path/contact.vcf');
Share.shareFiles(['$path/contact.vcf'], text: 'Great picture');
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
But getting format of this vcard is not support error.
This is the working example.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:path_provider/path_provider.dart';
import 'package:share_plus/share_plus.dart';
import 'package:vcard_maintained/vcard_maintained.dart';
void shareAllVCFCard(BuildContext context, {required List<VCard> vCard}) async {
try {
List<String> vcsCardPath = <String>[];
int index = 0;
for (final card in vCard) {
index++;
var vCardAsString = card.getFormattedString();
final directory = await getApplicationDocumentsDirectory();
final path = directory.path;
var pathAsText = "$path/$index.txt";
var contactAsFile = File(await getFilePath(index.toString()));
contactAsFile.writeAsString(vCardAsString);
var vcf = contactAsFile
.renameSync(contactAsFile.path.replaceAll(".txt", ".vcf"));
vcsCardPath.add(vcf.path);
}
Share.shareFiles(vcsCardPath, text: 'Great picture');
} catch (e) {
print("Error Creating VCF File $e");
return null;
}
}
Future<String> getFilePath(String fileName) async {
Directory appDocumentsDirectory =
await getApplicationDocumentsDirectory(); // 1
String appDocumentsPath = appDocumentsDirectory.path; // 2
String filePath = '$appDocumentsPath/$fileName.txt'; // 3
return filePath;
}

Flutter : I save data to a file in flutter, but how do I prevent data onwritten?

I'm printing the data to a file but this data is overwritten. How can I collect all data in one file
Future<String?> get _localPathBLE async {
final directory = await getExternalStorageDirectory();
return directory?.path;
}
Future<File> get _localFile async {
final path = await _localPathBLE;
var date =
DateUtil.instance.dateParseToString(DateEnum.FULL, DateTime.now());
return File('$path/DATA.csv');
}
Future<void> writeBLE(List<List<double>> acc3d) async {
final file = await _localFile;
String csv = const ListToCsvConverter().convert(acc3d);
// Write the file
return file.writeAsStringSync(csv);
}
In order to append the bytes to an existing file, pass FileMode.append as the optional mode parameter.
See writeAsStringSync for details.
Future<void> writeBLE(List<List<double>> acc3d) async {
final file = await _localFile;
String csv = const ListToCsvConverter().convert(acc3d);
// Write the file
return file.writeAsStringSync(csv + '\n',
mode: FileMode.append, flush: true);
}

Flutter Android 11 errno 1

im downloading a pdf file in this address :
/storage/emulated/0/documents/download folder/2021-08-30-16:37:55.544095iH46x.pdf
it works fine in android 10 and below.
but on android 11 i get this error :
FileSystemException: Cannot open file, path = '/storage/emulated/0/documents/download folder/2021-08-30-16:37:55.544095iH46x.pdf' (OS Error: Operation not permitted, errno = 1)
these are my permissions on manifest :
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
these are my permissions on permission handler :
Map<Permission, PermissionStatus> result = await [
Permission.storage,
Permission.manageExternalStorage,
Permission.mediaLibrary].request();
full code :
String fullPath;
try {
Map<Permission, PermissionStatus> result = await [
Permission.storage,
Permission.manageExternalStorage,
Permission.mediaLibrary].request();
if (result[Permission.storage].isGranted && result[Permission.manageExternalStorage].isGranted && result[Permission.mediaLibrary].isGranted ) {
// a custom method for getting path
String dir = await Utility.makeAndGetDownloadFolder();
// preparing access token
final storage = Storage.FlutterSecureStorage();
String accessToken = await storage.read(key: "accessToken");
// generating random string for the pdf file name
String dateNow = DateTime.now().toString();
dateNow = dateNow.replaceAll(' ', '');
String randomName = dateNow + Utility.getRandomString(5);
fullPath = "$dir/$randomName.pdf";
// preparing dio request
String url;
Dio dio = Dio();
Response response;
url = "https://www.example.com/api/downloadFile";
FormData formData = FormData.fromMap({
"idAdvertise": idAdvertise,
});
response = await dio.post(url,
data: formData,
options: Options(
headers: {
HttpHeaders.authorizationHeader: 'Bearer $accessToken',
},
responseType: ResponseType.bytes,
followRedirects: false,
validateStatus: (status) {
return status < 500;
}), onReceiveProgress: (int received, int total) {
if (total != -1) {
setState(() {
_progress = received / total * 100;
});
}
});
if (response.statusCode == 200) {
File file = File(fullPath);
// code reach untill here and then it jumps in catch
var raf = file.openSync(mode: FileMode.write);
raf.writeFromSync(response.data);
await raf.close();
// show notification on success
await showNotification(fullPath);
}else if(response.statusCode == 404){
// status code 404 do something
print("status 404");
}else{
print("status code download is ${response.statusCode}");
Components.customSnackBar(context,AppStr.errDownloadFailed403);
}
setState(() {
});
}
} catch (e) {
print("catch is $e");
}
please dont suggest me using path_provider cause its not what i need
For anyone who still wonders how i fixed the issue,
i used path provider to save the file in the cache and then after saving the file then i moved the file to downloads folder with the flutter_file_dialog package
source code :
//getting the cache directory from path_provider
Directory dir = await getApplicationDocumentsDirectory();
final storage = Storage.FlutterSecureStorage();
String accessToken = await storage.read(key: "accessToken");
var fileName = Utility.generateRandomFileName();
fullPath = "${dir.path}/$fileName.pdf";
bool checkFileExist = true;
while (checkFileExist) {// if file already exists with this name then we generate different name
if (await File(fullPath).exists()) {
fileName = Utility.generateRandomFileName();
fullPath = "${dir.path}/$fileName.pdf";
} else {
checkFileExist = false;
}
}
Dio dio = Dio();
Response response;
FormData formData;
formData = FormData.fromMap({
"id": widget.id,
});
response = await dio.post('https://example.com/downloadfile',
data: formData,
options: Options(
headers: {
HttpHeaders.authorizationHeader: 'Bearer $accessToken',
},
responseType: ResponseType.bytes,
followRedirects: false,
validateStatus: (status) {
return status < 500;
}),
onReceiveProgress: (int received, int total) {
if (total != -1) {
setState(() {
_progressDownloading = received / total * 100;
});
}
});
if (response.statusCode == 200) {
File file = File(fullPath);
var raf = file.openSync(mode: FileMode.write);
raf.writeFromSync(response.data);
await raf.close();
// moving the file from cache to anywhere you want
final params = SaveFileDialogParams(sourceFilePath: fullPath);
await FlutterFileDialog.saveFile(params: params).then((value) async {
if(value != null){//if the file saved successfully
await showNotification();
}else{
print('error couldnt move the pdf file');
}
});
file.delete();//deleting the pdf from cache
}else{
print('something went wrong');
}

Flutter Error: _TypeError (type 'Null' is not a subtype of type 'FutureOr<Database>')

Opening the sqlite database in assets folder. but I get this error.
I tried ' return _db ?? = await initDb(); ' but it's not work.
i don't understand why i got this error..
please help me..
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:bankingapp/models/histories.dart';
import 'package:flutter/services.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
class DbHelper {
static Database? _db;
Future<Database> get db async {
return _db = await initDb(); // <-- error is here
}
initDb() async {
var dbDir = await getDatabasesPath();
var dbPath = join(dbDir, "app.db");
// Delete any existing database:
await deleteDatabase(dbPath);
// Create the writable database file from the bundled demo database file:
ByteData data = await rootBundle.load("assets/database/bankingapp.db");
List<int> bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await File(dbPath).writeAsBytes(bytes);
var db = await openDatabase(dbPath);
/*
var dbFolder = await getDatabasesPath();
String path = join(dbFolder, 'app.db');
return await openDatabase(path);*/
}
Future<List<Histories>> getHistories() async {
var dbClient = await db;
var result = await dbClient.rawQuery("SELECT * FROM Histories");
return result.map((data) => Histories.fromMap(data)).toList();
}
}
This code will help you.
Future<Database> initDb() async {
var dbFolder = await getDatabasesPath();
String path = join(dbFolder, 'app.db');
// Delete any existing database:
await deleteDatabase(path);
// Create the writable database file from the bundled demo database file:
try {
await Directory(dirname(path)).create(recursive: true);
} catch (_) {}
ByteData data =
await rootBundle.load(join("assets/database", "bankingapp.db"));
List<int> bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await new File(path).writeAsBytes(bytes, flush: true);
//open the database
return await openDatabase(path);
}

How i check existence of file and directory in ApplicationDocumentsDirectory before write it?

I have the following code,
Am I trying to check if a path exists?
If the path already exists, write to the file.
I'm having trouble. please help me. tks all.
Future<String> get _logcalPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path; // home/directory/
}
Future<File> get _localFile async {
final path = await _logcalPath;
return File('$path/LOG.txt'); // home/directory/log.txt
}
Future<File> writeLog(String pdfData) async {
final file = await _localFile;
//write to file
var sink = file.openWrite(mode: FileMode.append);
file.writeAsString( "OPERATION" + pdfData.toString());
await sink.flush();
await sink.close();
return file;
}
File has a method exists() which returns a Future<bool>. Use that to check whether the file/path exists.
Future<File> writeLog(String pdfData) async {
final file = await _localFile;
final fileExists = await file.exists();
if(!fileExists) await file.create(); // Create your file if it does not exists.
//write to file
var sink = file.openWrite(mode: FileMode.append);
file.writeAsString("OPERATION" + pdfData.toString());
await sink.flush();
await sink.close();
return file;
}

Categories

Resources