Flutter Android 11 errno 1 - android

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');
}

Related

Flutter - How to save audio as a file?

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;

Upload image to the server with the form data in flutter

i using the ImagePicker package in the dart when i pick the image i want to upload this to the server with the form data but when i try to send this i give this error
" Unhandled Exception: FileSystemException: Cannot retrieve length of file, path = 'File: '/storage/emulated/0/Android/data/com.example.aloteb/files/Pictures/scaled_image_picker3594752094355545880.jpg'' "
and this is my code for sending to the server
var request = http.MultipartRequest('POST', Uri.parse(url));
request.fields.addAll({
'data': '$map'
});
request.files.add(await http.MultipartFile.fromPath('image',picproviderformdate.getPAth.toString()));
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
}
else {
print(response.reasonPhrase);
}
and this is my ImagePickercode
picprovider pic = Provider.of<picprovider>(context,listen: false);
File image = await ImagePicker.pickImage(
source: ImageSource.gallery, imageQuality: 50);
setState(() {
_image = image;
});
print(_image);
pic.setpathe(_image);
can any one help me for solve this problem?
I had a similar problem a while ago, and i used the Dio dependency instead of the classical Http link.
The code is very similar, and i can gave you an example.
final File file = File("${documentDirectory.path}/picture.png");
final httpDio = dio.Dio();
final formData = dio.FormData.fromMap({
"data": "{}",
"files.image": await dio.MultipartFile.fromFile(
"${documentDirectory.path}/picture.png",
filename: "picture.png",
contentType: MediaType('image', 'png'))
});
try {
final dio.Response response = await httpDio.post(
"ApiEndpoint/avatars",
data: formData,
options: dio.Options(headers: {"Authorization": "Bearer yourTokenIfNeeded"}));
if (response.statusCode == 200) {
// Success
}
} on dio.DioError catch (e) {
if (e.response != null) {
// Error
print(e.response.data);
return;
}
}
Don't forgot to update the API endpoint and route as well as your auth authorization if you need one.

Uploading to Firebase Storage using uri from GIF [duplicate]

I'm wondering how to upload file onto Firebase's storage via URL instead of input (for example). I'm scrapping images from a website and retrieving their URLS. I want to pass those URLS through a foreach statement and upload them to Firebase's storage. Right now, I have the firebase upload-via-input working with this code:
var auth = firebase.auth();
var storageRef = firebase.storage().ref();
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();
var file = evt.target.files[0];
var metadata = {
'contentType': file.type
};
// Push to child path.
var uploadTask = storageRef.child('images/' + file.name).put(file, metadata);
// Listen for errors and completion of the upload.
// [START oncomplete]
uploadTask.on('state_changed', null, function(error) {
// [START onfailure]
console.error('Upload failed:', error);
// [END onfailure]
}, function() {
console.log('Uploaded',uploadTask.snapshot.totalBytes,'bytes.');
console.log(uploadTask.snapshot.metadata);
var url = uploadTask.snapshot.metadata.downloadURLs[0];
console.log('File available at', url);
// [START_EXCLUDE]
document.getElementById('linkbox').innerHTML = 'Click For File';}
Question what do I replace
var file = evt.target.files[0];
with to make it work with external URL instead of a manual upload process?
var file = "http://i.imgur.com/eECefMJ.jpg"; doesn't work!
There's no need to use Firebase Storage if all you're doing is saving a url path. Firebase Storage is for physical files, while the Firebase Realtime Database could be used for structured data.
Example . once you get the image url from the external site this is all you will need :
var externalImageUrl = 'https://foo.com/images/image.png';
then you would store this in your json structured database:
databaseReference.child('whatever').set(externalImageUrl);
OR
If you want to actually download the physical images straight from external site to storage then this will require making an http request and receiving a blob response or probably may require a server side language ..
Javascript Solution : How to save a file from a url with javascript
PHP Solution : Saving image from PHP URL
This answer is similar to #HalesEnchanted's answer but with less code. In this case it's done with a Cloud Function but I assume the same can be done from the front end. Notice too how createWriteStream() has an options parameter similar to bucket.upload().
const fetch = require("node-fetch");
const bucket = admin.storage().bucket('my-bucket');
const file = bucket.file('path/to/image.jpg');
fetch('https://example.com/image.jpg').then((res: any) => {
const contentType = res.headers.get('content-type');
const writeStream = file.createWriteStream({
metadata: {
contentType,
metadata: {
myValue: 123
}
}
});
res.body.pipe(writeStream);
});
Javascript solution to this using fetch command.
var remoteimageurl = "https://example.com/images/photo.jpg"
var filename = "images/photo.jpg"
fetch(remoteimageurl).then(res => {
return res.blob();
}).then(blob => {
//uploading blob to firebase storage
firebase.storage().ref().child(filename).put(blob).then(function(snapshot) {
return snapshot.ref.getDownloadURL()
}).then(url => {
console.log("Firebase storage image uploaded : ", url);
})
}).catch(error => {
console.error(error);
});
Hopefully this helps somebody else :)
// Download a file form a url.
function saveFile(url) {
// Get file name from url.
var filename = url.substring(url.lastIndexOf("/") + 1).split("?")[0];
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", transferComplete);
xhr.addEventListener("error", transferFailed);
xhr.addEventListener("abort", transferCanceled);
xhr.responseType = 'blob';
xhr.onload = function() {
var a = document.createElement('a');
a.href = window.URL.createObjectURL(xhr.response); // xhr.response is a blob
a.download = filename; // Set the file name.
a.style.display = 'none';
document.body.appendChild(a);
a.click();
delete a;
if (this.status === 200) {
// `blob` response
console.log(this.response);
var reader = new FileReader();
reader.onload = function(e) {
var auth = firebase.auth();
var storageRef = firebase.storage().ref();
var metadata = {
'contentType': 'image/jpeg'
};
var file = e.target.result;
var base64result = reader.result.split(',')[1];
var blob = b64toBlob(base64result);
console.log(blob);
var uploadTask = storageRef.child('images/' + filename).put(blob, metadata);
uploadTask.on('state_changed', null, function(error) {
// [START onfailure]
console.error('Upload failed:', error);
// [END onfailure]
}, function() {
console.log('Uploaded',uploadTask.snapshot.totalBytes,'bytes.');
console.log(uploadTask.snapshot.metadata);
var download = uploadTask.snapshot.metadata.downloadURLs[0];
console.log('File available at', download);
// [START_EXCLUDE]
document.getElementById('linkbox').innerHTML = 'Click For File';
// [END_EXCLUDE]
});
// `data-uri`
};
reader.readAsDataURL(this.response);
};
};
xhr.open('GET', url);
xhr.send();
}
function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, {type: contentType});
return blob;
}
function transferComplete(evt) {
window.onload = function() {
// Sign the user in anonymously since accessing Storage requires the user to be authorized.
auth.signInAnonymously().then(function(user) {
console.log('Anonymous Sign In Success', user);
document.getElementById('file').disabled = false;
}).catch(function(error) {
console.error('Anonymous Sign In Error', error);
});
}
}
function transferFailed(evt) {
console.log("An error occurred while transferring the file.");
}
function transferCanceled(evt) {
console.log("The transfer has been canceled by the user.");
}

DioError [DioErrorType.RESPONSE]: Http status error [400] Exception

I am developing a Flutter Restful web application and the web api backend as asp.net core. When i try to send the form data using post request it is throwing this error
DioError [DioErrorType.RESPONSE]: Http status error [400] Exception
Code
onPressed: () async {
String email_value = emailController.text;
String password_value = passController.text;
String fullname_value = fullnameController.text;
var repassword_value = repassController.text;
print("$email_value");
if (password_value == repassword_value) {
try{
Dio dio = Dio();
var body = jsonEncode(
{
'FullName': '$fullname_value',
'Email': '$email_value',
'Password': '$password_value'
}
);
print("Body" + body);
Response response = await dio.post("http://iamtv.chainuniverse.com/api/Accounts/Register",
data: body,
options: Options(
contentType: Headers.jsonContentType,
)
);
var jsonData = json.decode(response.data);
print(jsonData);
if (response.statusCode > 200 &&
response.statusCode < 250) {
print("Sucess");
await loginAction();
print("Registered");
}
else{
print(jsonData);
}
But when i send data manually without using textcontroller Text it works. Please help me to fix this
Working perfectly in POSTMAN
Late answer, may help you.
I was getting same error with Dio and form-data. It worked! after adding contentType
FormData formData = FormData.fromMap({
"image-param-name": await MultipartFile.fromFile(
imageFile.path,
filename: fileName,
contentType: new MediaType("image", "jpeg"), //add this
),
});
complete code
var dio = Dio();
String fileName = imageFile.path.split('/').last;
FormData formData = FormData.fromMap({
"image-param-name": await MultipartFile.fromFile(
imageFile.path,
filename: fileName,
contentType: new MediaType("image", "jpeg"), //add this
),
});
var response = await dio.post(
"url",
data: formData,
options: Options(
headers: {
"Authorization": auth-token
},
),
onSendProgress: (int sent, int total) {
debugPrint("sent${sent.toString()}" + " total${total.toString()}");
},
).whenComplete(() {
debugPrint("complete:");
}).catchError((onError) {
debugPrint("error:${onError.toString()}");
});

Uploading files to Firebase Storage from URL file [duplicate]

I'm wondering how to upload file onto Firebase's storage via URL instead of input (for example). I'm scrapping images from a website and retrieving their URLS. I want to pass those URLS through a foreach statement and upload them to Firebase's storage. Right now, I have the firebase upload-via-input working with this code:
var auth = firebase.auth();
var storageRef = firebase.storage().ref();
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();
var file = evt.target.files[0];
var metadata = {
'contentType': file.type
};
// Push to child path.
var uploadTask = storageRef.child('images/' + file.name).put(file, metadata);
// Listen for errors and completion of the upload.
// [START oncomplete]
uploadTask.on('state_changed', null, function(error) {
// [START onfailure]
console.error('Upload failed:', error);
// [END onfailure]
}, function() {
console.log('Uploaded',uploadTask.snapshot.totalBytes,'bytes.');
console.log(uploadTask.snapshot.metadata);
var url = uploadTask.snapshot.metadata.downloadURLs[0];
console.log('File available at', url);
// [START_EXCLUDE]
document.getElementById('linkbox').innerHTML = 'Click For File';}
Question what do I replace
var file = evt.target.files[0];
with to make it work with external URL instead of a manual upload process?
var file = "http://i.imgur.com/eECefMJ.jpg"; doesn't work!
There's no need to use Firebase Storage if all you're doing is saving a url path. Firebase Storage is for physical files, while the Firebase Realtime Database could be used for structured data.
Example . once you get the image url from the external site this is all you will need :
var externalImageUrl = 'https://foo.com/images/image.png';
then you would store this in your json structured database:
databaseReference.child('whatever').set(externalImageUrl);
OR
If you want to actually download the physical images straight from external site to storage then this will require making an http request and receiving a blob response or probably may require a server side language ..
Javascript Solution : How to save a file from a url with javascript
PHP Solution : Saving image from PHP URL
This answer is similar to #HalesEnchanted's answer but with less code. In this case it's done with a Cloud Function but I assume the same can be done from the front end. Notice too how createWriteStream() has an options parameter similar to bucket.upload().
const fetch = require("node-fetch");
const bucket = admin.storage().bucket('my-bucket');
const file = bucket.file('path/to/image.jpg');
fetch('https://example.com/image.jpg').then((res: any) => {
const contentType = res.headers.get('content-type');
const writeStream = file.createWriteStream({
metadata: {
contentType,
metadata: {
myValue: 123
}
}
});
res.body.pipe(writeStream);
});
Javascript solution to this using fetch command.
var remoteimageurl = "https://example.com/images/photo.jpg"
var filename = "images/photo.jpg"
fetch(remoteimageurl).then(res => {
return res.blob();
}).then(blob => {
//uploading blob to firebase storage
firebase.storage().ref().child(filename).put(blob).then(function(snapshot) {
return snapshot.ref.getDownloadURL()
}).then(url => {
console.log("Firebase storage image uploaded : ", url);
})
}).catch(error => {
console.error(error);
});
Hopefully this helps somebody else :)
// Download a file form a url.
function saveFile(url) {
// Get file name from url.
var filename = url.substring(url.lastIndexOf("/") + 1).split("?")[0];
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", transferComplete);
xhr.addEventListener("error", transferFailed);
xhr.addEventListener("abort", transferCanceled);
xhr.responseType = 'blob';
xhr.onload = function() {
var a = document.createElement('a');
a.href = window.URL.createObjectURL(xhr.response); // xhr.response is a blob
a.download = filename; // Set the file name.
a.style.display = 'none';
document.body.appendChild(a);
a.click();
delete a;
if (this.status === 200) {
// `blob` response
console.log(this.response);
var reader = new FileReader();
reader.onload = function(e) {
var auth = firebase.auth();
var storageRef = firebase.storage().ref();
var metadata = {
'contentType': 'image/jpeg'
};
var file = e.target.result;
var base64result = reader.result.split(',')[1];
var blob = b64toBlob(base64result);
console.log(blob);
var uploadTask = storageRef.child('images/' + filename).put(blob, metadata);
uploadTask.on('state_changed', null, function(error) {
// [START onfailure]
console.error('Upload failed:', error);
// [END onfailure]
}, function() {
console.log('Uploaded',uploadTask.snapshot.totalBytes,'bytes.');
console.log(uploadTask.snapshot.metadata);
var download = uploadTask.snapshot.metadata.downloadURLs[0];
console.log('File available at', download);
// [START_EXCLUDE]
document.getElementById('linkbox').innerHTML = 'Click For File';
// [END_EXCLUDE]
});
// `data-uri`
};
reader.readAsDataURL(this.response);
};
};
xhr.open('GET', url);
xhr.send();
}
function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, {type: contentType});
return blob;
}
function transferComplete(evt) {
window.onload = function() {
// Sign the user in anonymously since accessing Storage requires the user to be authorized.
auth.signInAnonymously().then(function(user) {
console.log('Anonymous Sign In Success', user);
document.getElementById('file').disabled = false;
}).catch(function(error) {
console.error('Anonymous Sign In Error', error);
});
}
}
function transferFailed(evt) {
console.log("An error occurred while transferring the file.");
}
function transferCanceled(evt) {
console.log("The transfer has been canceled by the user.");
}

Categories

Resources