Cordova file plugin - save file in device
Solution 1
SOLVED:
after several attempts I solved in this way
in config.xml
:
<preference name="AndroidPersistentFileLocation" value="Compatibility" />
<preference name="AndroidExtraFilesystems" value="files,cache, sdcard, cache-external, files-external" />
and main function:
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {
//var absPath = "file:///storage/emulated/0/";
var absPath = cordova.file.externalRootDirectory;
var fileDir = cordova.file.externalDataDirectory.replace(cordova.file.externalRootDirectory, '');
var fileName = "somename.txt";
var filePath = fileDir + fileName;
fs.root.getFile(filePath, { create: true, exclusive: false }, function (fileEntry) {
writeFile(fileEntry, BINARY_ARR).then(function(){
//do something here
});
}, function(err) {});
}, function(err) {});
function writeFile(fileEntry, dataObj) {
return $q(function (resolve, reject) {
fileEntry.createWriter(function (fileWriter) {
fileWriter.onwriteend = function () {
resolve();
};
fileWriter.onerror = function (e) {
reject(e);
};
fileWriter.write(dataObj);
});
});
}
It seemed that:
<preference name="AndroidPersistentFileLocation" value="Internal" />
that is the default configuration, could not allow the app to write into the external disk (whether physical or emulated). Instead allowed the app only to write into /data/data/{myApp}/files
Solution 2
use this function to write and create new folder
function writeFile(path, filename, blob) {
return new Promise((resolve, reject) => {
window.resolveLocalFileSystemURL(cordova.file.externalRootDirectory, function (dirpar) {
dirpar.getDirectory(path, { create: true }, function (dir) {
dir.getFile(filename, { create: true, exclusive: false }, function (fileEntry) {
fileEntry.createWriter(function (fileWriter) {
fileWriter.onwriteend = resolve
fileWriter.onerror = reject
fileWriter.write(blob);
});
}, reject);
}, reject);
}, reject);
});
}
how to call function
writeFile("AppFolder", 'file.name', blob)
sample download an image and save in folder
var url = "image url"
fetch(url).then(res => res.blob()).then(blob => {
writeFile("pictures/myapp", url.substring(url.lastIndexOf("/") + 1), blob)
.then(function () { console.log("file donwloaded.") })
.catch(function (e) { console.error("error:", e) })
});
Solution 3
Ok so here is the whole explain of how to save the file. Using file plugin cordova:
Suppose you have to Save a file with text "Hello Mr. Vaibhav Mojidra" in a .txt inside internal storage.
so here it goes if you have button click in HTML like this: Now inside SaveFile function:
var textt=""; function SaveFile(text) { textt=text; /* initialize global variable with text to be written in file */ window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,onFileSystemSuccess, fail); /* This will check permission for storage read and write, and if got permission then function send parameter will be called else if not granted then third parameter ie fail function will be called */ } function onFileSystemSuccess(fileSystem) { fileSystem.root.getFile("Demo.txt",{create: true, exclusive: false},gotFileEntry,fail); /* This will create a file with name Demo.txt in internal storage . and similarly on sucessfully create it will call second parameter function i.e. gotFileEntry */ } function gotFileEntry(fileEntry) { fileEntry.createWriter(gotFileWriter, fail); /* This will get a file object with path call createWriter in which 1st parameter is use to write content in file and second parameter of fail to create writer */ } function gotFileWriter(writer) { writer.write(textt);/* passing parameter of the textt which is global and initialize at first called function*/ writer.onwriteend = function(evt) { alert("File Saved"); }; /*This function will be called once file is written with text and saved */ } function fail(error) { alert("Error","There was some problem\nError:"+error.code,"Ok"); }
davidetrapani
Updated on May 22, 2020Comments
-
davidetrapani almost 4 years
I'm having a lot of troubles saving files in Android.
The project is a hybrid application developed with Ionic with these plugins:com.phonegap.plugins.fileopener 1.0.0 "File Opener" com.telerik.plugins.nativepagetransitions 0.4.2 "Native Page Transitions" cordova-plugin-compat 1.0.0 "Compat" cordova-plugin-crosswalk-webview 2.0.0 "Crosswalk WebView Engine" cordova-plugin-file 4.2.0 "File" cordova-plugin-network-information 1.2.2-dev "Network Information" cordova-plugin-whitelist 1.2.3-dev "Whitelist" cordova-plugin-wkwebview-engine 1.0.4-dev "Cordova WKWebView Engine" ionic-plugin-keyboard 2.2.1 "Keyboard"
Android platform version is
5.2.1
The device I'm using is aSamsung A7
This is an abstract from
AndroidManifest.xml
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Case1
if I try with this snippet (actually working on another project)
var storagePath = "/storage/emulated/0"; var fileDir = cordova.file.externalDataDirectory.replace(cordova.file.externalRootDirectory, ''); var fileName = $scope.ngDocument.documentId + ".pdf" var filePath = storagePath + "/" + fileDir + fileName; $cordovaFile.writeFile(filePath, BINARY_ARR, {'append': false}).then(function(result) {}, function(err) {});
I get
{"code":5,"message":"ENCODING_ERR"}
as Callback from the$cordovaFile.writeFile
, no matter if I use absolute path, relative path, just the file name and no file is ever created.Case2
With this snippet
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) { console.log('file system open: ' + fs.name); fs.root.getFile(fileName, { create: true, exclusive: false }, function (fileEntry) { console.log("fileEntry:" + JSON.stringify(fileEntry)); writeFile(fileEntry, BINARY_ARR); }, function(data){}); }, function(data){});
happen two different things
Case 2.1
If no config options are specified in
config.xml
the app creates an empty folder into /storage/emulated/0/Android/media/{myAPP}Case 2.2
with these two preferences
<preference name="AndroidPersistentFileLocation" value="Compatibility" /> <preference name="AndroidExtraFilesystems" value="cache" />
a file in
/storage/emulated/0
(external SSD) is created and inlogcat
errors are:E/Vold ( 2280): Failed to find mounted volume for /storage/extSdCard/Android/data/{myApp}/files/ W/Vold ( 2280): Returning OperationFailed - no handler for errno 0 W/ContextImpl(13364): Failed to ensure directory: /storage/extSdCard/Android/data/{myApp}/files E/Vold ( 2280): Failed to find mounted volume for /storage/extSdCard/Android/data/{myApp}/files/ W/Vold ( 2280): Returning OperationFailed - no handler for errno 0 W/ContextImpl(13364): Failed to ensure directory: /storage/extSdCard/Android/data/{myApp}/files E/Vold ( 2280): Failed to find mounted volume for /storage/extSdCard/Android/data/{myApp}/cache/ W/Vold ( 2280): Returning OperationFailed - no handler for errno 0 W/ContextImpl(13364): Failed to ensure directory: /storage/extSdCard/Android/data/{myApp}/cache
The strange fact is that
/storage/extSdCard
(symbolic link for/mnt/extSdCard
) is not mounted while the external SSD is mounted on/mnt/sdcard
Please help: I'm headbanging.
The first snippet was working as a charm in another project. Could it be the version of ngCordova? -
davidetrapani almost 8 yearswhy should I use FileUpload when I just need to create a new file?
-
Ben Elghali Beyram almost 8 yearswhen you should use FileUpload ?
-
davidetrapani almost 8 yearsthanks for the answer and for the support. However it's OFFTOPIC. I will not downvote even though I should have to.
-
Piku over 7 yearsHi I am trying to save a xml file to device using your code but i am confusing with where to pass the data
-
davidetrapani over 7 yearsData is the BINARY_ARR variabile .. as the name suggests it must be a binary array
-
Vasanth over 5 yearsWhen I try your code, I'm getting an error named writefile.then is not a function.
-
Rvg.2ky over 3 yearsfile transfer plugin now deprecated and dose not support android 10+