I've begun work on trying to answer the questions I gathered concerning Cordova's FileSystem support. As I work through the questions I'm trying to build "real" samples to go along with the text. My first sample is a simple one, but I think it is pretty relevant for the types of things folks may do with Cordova and the file system - checking to see if a file exists locally and if not - fetching it.
I'll begin by sharing the code and then explaining the parts. Here is the entire JavaScript file for the application. (Earlier today, Andrew Grieve shared a way my code could be simplified by a good 1/3rd. The code below reflects his update and has been changed since my original writing of the blog post.)
document.addEventListener("deviceready", init, false);
//The directory to store data
var store;
//Used for status updates
var $status;
//URL of our asset
var assetURL = "https://raw.githubusercontent.com/cfjedimaster/Cordova-Examples/master/readme.md";
//File name of our important data file we didn't ship with the app
var fileName = "mydatafile.txt";
function init() {
$status = document.querySelector("#status");
$status.innerHTML = "Checking for data file.";
store = cordova.file.dataDirectory;
//Check for the file.
window.resolveLocalFileSystemURL(store + fileName, appStart, downloadAsset);
}
function downloadAsset() {
var fileTransfer = new FileTransfer();
console.log("About to start transfer");
fileTransfer.download(assetURL, store + fileName,
function(entry) {
console.log("Success!");
appStart();
},
function(err) {
console.log("Error");
console.dir(err);
});
}
//I'm only called when the file exists or has been downloaded.
function appStart() {
$status.innerHTML = "App ready!";
}
Ok, let's break it down. The first step is to check to see if our file exists already. The question is - where should we store the file? If you look at the docs for the FileSystem, you will see that the latest version of the plugin adds some useful aliases for common folders. Unfortunately, the docs are not exactly clear about how some of these aliases work. I asked for help (both on the PhoneGap Google group and the Cordova development list) and got some good responses from Kerri Shotts and Julio Sanchez.
The directory that I thought made sense, cordova.file.applicationStorageDirectory, is incorrectly documented as being writeable in iOS. A pull request has already been filed to fix this mistake. For my application, the most appropriate directory is the next one, cordova.file.dataDirectory. Once I have my directory alias, I can make use of resolveLocalFileSystem on the directory plus desired file name to see if it exists. The third argument, downloadAsset, will only be run on an error, in this case a file not existing.
If the file does not exist, we then have to download it. For this we use a second plugin, FileTransfer. This is where one more point of confusion comes in. We need to convert that earlier DirectoryEntry object, the one we used to get an API for files and directories, back to a URL so we can give a path to the Download API.
So to recap - we've got a few moving parts here. We've got a directory alias, built into the plugin for easily finding common folders for our application. Again, the docs here are currently a bit wrong but they should be corrected soon. From that we can quickly see if our desired file exists, and if not, use the FileTransfer plugin to download it.
Simple... but even a simple application caused me a bit of trouble, so hopefully this helps others. You can get the full source code here: https://github.com/cfjedimaster/Cordova-Examples/tree/master/checkanddownload
Archived Comments
I tried _cordova.file.dataDirectory_ as a way to store files in a cross platform way and it seems to be undefined. I installed the file and file-transfer plugins. From what version is this available in the file plugin?
1.2 and higher. Did you wait for deviceready to fire?
Yes the call was inside deviceready. The reason it probably didn't work was because I used Phonegap Build. I can now see in the plugins page (https://build.phonegap.com/... that the latest version is 1.0.1.
Will I get version 1.2 of the file plugin if I use cordova CLI?
Yep.
Thanks for this. I am testing your code to update a file regularly.
Using Network Link Conditioner, I simulated a 100% loss network.
Now the problem is, when the file transfer fails, the stored local life gets deleted. Any idea on how to prevent fileTransfer from deleting it?
Oh now that is interesting. I guess it would be expected as it needs to stream the data to the system and if the stream fails, it wipes the file, but I can see how this may be a surprise to people.
So I see two things:
a) We should document it in the FileTransfer download method.
b) For your specific use case, the logic should be modified to download to *another* location and on success, copy to the proper location.
Note - code updated.
Thanks for your reply.
I think FileTransfer should have a cache mechanism like the OS's. Start downloading to .tmp file; if successful move it to the final file name, if not, delete the .tmp.
Yes, I will have to implement this. Will use fileEntry.copyTo. When not update your code to do this also? :)
I'd suggest filing a request for this on the issue tracker: https://issues.apache.org/j...
Hi Raymond
Nice post, this is exactly what I was trying to do. However, I have a question about it: You don't seem to call _requestFileSystem()_ anywhere.
In every documentation or tutorial I've seen so far, _requestFileSystem()_ must be called in order to access any file in the file system. I presume that _resolveLocalFileSystemURL()_ has been introduced in version 1.2 and it's intended to be used when the full path for the file bein accessed is already known, while _requestFileSystem()_ allows navigating through the file system and look for it, but since I can't find any reason on the net why _resolveLocalFileSystemURL()_ was introduced, I'm not sure. Could you please confirm or refuse it?
Thanks!
My understanding is that requestFileSystem is mainly giving you an alias to the root of either the persistent or temp directory. The new aliases in the latest FS plugin makes this unnecessary (assuming you want to use one of those aliases of course).
This post was great and helped me to download a file to my app. How do I set the download location to be in my \www\data directory that I have in my app?
Thanks
I *believe* that may be read only. I think the docs say as much here:
cordova.file.applicationDirectory - Read-only directory where the application is installed. (iOS, Android)
Here's the actual goal. I ship a json file with my app. It is stored in the \www\data directory. I would like to be able to replace that file from time to time with new data. If that directory is read only then where can I store the file during development? I don't see any of the app storage directories when developing in cordova.
Thanks for all of the help, it is greatly appreciated.
I'd just store the new version in localStorage. Then your logic can be:
if I have it in localstorage, see if too old, and if so, update
otherwise if not too old, use it
otherwise if not there, default to one I ship with the app in file storage
This code worked great for Android devices. But when I ran the same code on a wp8 device, the cordova.file namespace appears to be undefined as I receive an error of 'unable to get property 'dataDirectory' of undefined or null reference'. When I reference the cordova-plugin-file at git://git.apache.org/cordov..., it seems the plugin is supported by wp8, but that is the only reference to it. None of the cordova.file.* have wp8 listed.
Do you know what I should be using instead for wp8? And where I can reference the 'where to store files' table for wp8 that is an excellent summary for each other platform?
The docs mention that dataDirectory is not supported in WP8.
Since these are just aliases to help simplify your code, in theory, it shouldn't stop you per se, you would just need to figure out the right folder by hand. I'd google around and see what the typical directory would be for that platform.
First thanks. This post helped me get up to speed quickly.
On IOS I can download and open the file in Adobe smoothly. But it never finds the downloaded file. It always downloads another copy(#). I have tried Documents, Library, Temp directories.
My console logs show the right directory all the way through.
Adobe will open those very files offline, but my code doesn't find it or at least cant open it.
resolveLocalFileSystemURL is never true, but it should be.
Is adobe moving my files?
Do i need to requestFileSystem before opening a file that doesn't need to be downloaded?
I will appreciate any help and regardless thank you again for your time. I am certainly downloading and opening files in the sandbox when I wasn't before and that is useful.
First off... what do you mean by Adobe? Adobe what?
I can download the file and open it in Adobe Reader. I use a different plugin to just read PDF offline no prob.
But Forms PDFs we need to open in reader so client can email print etc the form. Console shows adobe "copying" the file. Which is actually great for us.
And it seems to still show the file in the application sandbox listing in xcode.
But it always downloads another copy it never finds the file that is there and makes the copy.
I honestly can't tell what you are saying here. It sounds like you modified my code to work with PDFs, and you are trying to open the PDF, is that so? If so, it does not apply to this blog post, does it?
the pdf opens with the fileopener plugin just fine.
it is just one call line added to your code to open the file. I could have used inAppBrower too. Its not top of mind relevant because
resolveLocalFileSystemURL is never true with or without even trying to open the file, except if I am still connected to the mac and hit run again then
your code does work great to download and open pdf in adobe reader btw, when used with the fileopener plugin.
I just cant open the downloaded file online or offline.
resolveLocalFileSystemURL cant find it or it isnt still there.
I'm still not quite I understand you. That being said - I'm currently investigating a bug with this on Android. Please see: https://github.com/cfjedima...
ty already watching that. I am teamdenver
I have a bit more info. I watched my apps sandboxed directory from the xcode organiser window.
I can see the file in the Documents folder after successful transfer code.
Then console says it is "copy" file to Adobe Reader Sandbox.
But as soon as I choose "Open With" Adobe Reader, and refresh organiser window, it is gone.
It is a "move" not a "copy".
resolveLocalFileSystemURL isnt true because the file is no longer there.
Great article! Helped me a lot. Do you also know how to delete a file? Will I have to loop through the entire dir to get the filehandle, or is it possible to delete a file straight away if you know the filename? Thank you
Figured that out, the success routine will have the filehandle.
Hello,
I want to use your this file checking method in loop.
I have write this something like below.
window.resolveLocalFileSystemURL(DATADIR.toURL() +"/"+ filename, appStart, function(){
ft.download(uri, dlPath, function(e){
//renderPicture(e.toURL());
alert("Successful download of "+e.toURL());
}, onError, true);
});
But it seems like i am doing some mistake here. Can you please tell me the right way?
Remember that these calls are async, so if you have it in a loop, there is no guarantee for which order they will finish.
Hello, thank you for your reply.
No problem with the order. But the same image is keep downloading. And even though it dont download the file. It just shows that, it has been downloaded successfully.
I generated one query here at http://stackoverflow.com/qu....
Please if there is anyway i can resolve this problem let?
Posted an answer there.
Thank you, you are a life saver....This one worked perfectly fine.
But i dont understand. What the problem from my method?
Thank you! Thank you so much!
I explained - kinda - on SO. It has to do with the nature of callbacks. If it is any consolation, I make the same mistake myself all the time.
Your effort really appreciated Raymond. Everybody loves Raymond :)
Hi Raymond, thanks for the post.
i was trying the upload plugin for uploading a "zip" file to the server.
the zip file successfully uploads to the server but the web service does some operation based on the uploaded zip file before returning success. But on the device side i get an cordova error as below:
"File Transfer Error: The request timed out." code : 3
please let me know how to handle this or is there a way to increase the timeout for this plugin ?
I'm not seeing an option for that. I'd file a bug report.
@Raymond.
In my case, i will be download file depending on productid. So i dont know what will be the file name and its extension. So how can i download this file.?
For eg:
http://127.0.0.1/Download.php?id=10
Will give ABC.doc
http://127.0.0.1/Download.php?id=6
Will give Five.pdf
http://127.0.0.1/Download.php?id=3
Will give Five.xls
So how can i specify my filename?
You would need to modify your API to return the name. For example, I'd have an API that returns the file name and the "download.php" url. You would then make a second request to get the binary data.
Hello! Thanks for your post.
But I have a question. How to delete files?
In my app I have to download zip file to cordova.file.dataDirectory, and extract it to cordova.file.dataDirectory/folder.
But when file updates on the server, I need to download new zip file and delete old zip file and all files stored in cordova.file.dataDirectory/folder.
Please, tell me, how to delete these files.
Thank you!
It is discussed here, http://www.html5rocks.com/e...
is it possibile to make a loop for check more files?
Sure.
Hello! Raymond
Can we download the file to the downloads folder?
What should be the path for store, instead of
cordova.file.dataDirectory;
Thanks,
J
I don't know. I checked the File plugin (https://www.npmjs.com/packa... and there is no alias for it, but obviously if you know the full path to the downloads folder, and it is writeable by your app, then it is a simple matter.
I have used cordova.file.externalRootDirectory to create a folder. And I downloaded the photos in that folder. But now my problem is I want to check whether the file I am downloading already exist in that folder but I am unable to get the path of that folder.
I am using Ionic framewrok. To download the image in folder I used -
$scope.downloaad= function(photoUrl, photoId, folder){
var url = photoUrl;
var targetPath = cordova.file.externalRootDirectory+"/"+folder+"/"+options.photoId+".jpg";
var trustHosts = true;
var str = {};
$cordovaFileTransfer.download(url, targetPath, str, trustHosts)
.then(function(result) {
console.log("result->" + result);
}, function(err) {
console.log("error->" + err);
});
}
Are you saying you want to resolve the path to a DirectoryEntry object you can work with?
Hey, thanks for the great article. I've tried to implement your code in my app, which has to do this: check if video exists, if it does play it, else download it and play it. But it doesn't work, problem is both every time success and fail functions get called. So if video exists app plays it, but it also downloads it again. Here is relevant part of my code:
var store = cordova.file.dataDirectory;
var filePath = store + "videoTest.mp4";
//Check for the file.
window.resolveLocalFileSystemURL(filePath, playVideo(filePath, true), transferFile(uri, filePath));
Also here is my SO question with a bit different code, but same problem: http://stackoverflow.com/qu...
Please, if it is not too much trouble, could you tell me what am I doing wrong ?
Thanks in advance !
I posted an answer there.
Hey, thanks for the fast response :)
Thanks for the great post. But how do I open the file via a link?
Just link to it? :)
Many thanks. Using url = entry.toURL() gives me file:///path/to/file and it doesn't open in browser and not even in inAppBrowser. Both window.open(url, '_system') and window.open(url, '_blank') did not work.
What happens though? You said it didn't work- did it throw an error? What did remote debugging show you?
I get "Options expected to be an object", from inAppBrowser. I have no idea what that means...
Double check to ensure you are running this plugin - https://github.com/apache/c...
The problem is ngCordova's InAppBrowser implementation actually requires the options to be passed as object. Now the file opens with a PDF reader but it says "Document path is not valid." Please what can be the issue? Many thanks for your time.
Was the file downloaded to a temporary location?
The file was downloaded to cordova.file.dataDirectory directly, I am suspecting it may be that it is private. Could that be the case?
I changed the path to cordova.file.externalApplicationStorageDirectory and it worked well. How reliable is this path?
I'd check what the FIle plugin doc has to say about it.
Many thanks Raymond, I really appreciate.
Hello, I'm with the same problem.
Do you find some workaround for this issue?
Great tutorial !
resolveLocalFileSystemURL error fallback passes an argument of type FileError object. Here you can find the meaning of FileError.code: https://developer.mozilla.o...
Can we add file on external sdcard, if sdcard is inserted? i done code put file in internal storage in specific folder. But need to put in external sdcard. Is there any way to do it? Thank you in advance.
Check out externalDataDirectory, and the other external aliases in the docs here: https://www.npmjs.com/packa...
thank for you quick reply, But it didn't help me. It still showing internal storage path for app. I need external sdcard access.
You say, "it still showing internal storage path" - what is? If you mean my code, obviously you need to change it.
yes it showing me path "file:///storage/emulated/0/" but i need get path of "/sdcard/myfolder" here sdcard is what normally inserted in android phone externally.
yes what? If you are using my code, then you need to change it. If you've changed my code to use the external sd card, show (via a Gist) how you did it.
i used your code. But i didn't change it till now. i need your help for save my file on "external sdcard"
And I did help. :) Look at the docs on the File plugin and pay special attention to the external aliases.
Hi, thanks for a great tutorial! I've got a question for you, in case this has already been asked and answered before I beg your pardon.. hope you're up for it :)
Anyway, here we go:
I am downloading images to the device on the fly and my intention is to save them locally in my application. The app will then look for the images when they're requested and see if they're stored locally and then use them with the local path otherwise it will download them and save them for future use.
In many other examples I've seen the following:
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFileSystemSuccess, fail);
But in yours I don't. In your example, are the images saved until they're removed or are they just saved temporarily? If they're saved temporarily, what would I change to make them stick around forever?
When I try to add window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFileSystemSuccess, fail); to my application it will just stop. No callbacks are thrown at all.
requestFileSystem will give you a handle to the root of the file system. This would let me start digging into the file system from, basically, /. I don't need that as I'm checking to see if a specific file exists. Does that make sense?
Thank you so much for your reply. That makes sense. Just to clarify, when I use fileTransfer.download will the file then be saved permanently? My main worry here is that I want to make sure that images that are downloaded from a remote host can be used in offline mode days/weeks later.
When I connect, say my Android to my Mac and open up a program called "Android File Transfer" I was expecting to see the saved files within my adobe.phonegap folder. But it seems to be empty. Is this normal behaviour? I am using your exact example.
I really appriciate your time.
1) Check the docs on that. There are locations that are temp/perm.
2) Note the docs on dataDirectory: "Persistent and private data storage" - notice how it says 'private'? I'm guessing thats why you can't see it.
Holy smokes - sorry it took 16 days to reply.
Hi Raymond, woah! Took me another 20 days to reply! Sorry about that. Thank you so much for your help. Much appriciated. Great articles!
Thanks for the great article!!!! But I am not sure why this file downloads everytime i run the script even though the file exists it downloads again. how can i overcome this?
I fixed the issue you need to change the following line :
window.resolveLocalFileSystemURL('file:///'+store+fileName, appStart, downloadAsset);
below article was helpful to solve it :
http://ourcodeworld.com/art...
Thanks Again.
Looks to be a known bug - hopefully corrected soon. Thanks for sharing this.
How abt this code working on iOS. i mean what will be the path of cordova.file.dataDirectory
See the FileSystem plugin docs. It explains what that alias means for each supported platform.
Hello is there a way to download a mp3 FIle and then use it as a localNotification
I have already downloaded the file successfully but i am not being able to use it as a local notification
If you mean something that is used with a Push notification, then I'm not sure. I know when you send a Push, you can specify a audio file to play, and if you can specify a folder that matches where you save the file, then yes. So I'd look into that first.
If you mean just a random noise, then sure, you can use the Media plugin to play it.
Hi, could we download pdf file on ios device?
if then, how can we browse that downloaded pdf file?
I tried below code from https://github.com/apache/c....
I got "download complete", but can't find that pdf and no way to find out on my device.
var fileTransfer = new FileTransfer();
var uri = encodeURI("http://some.server.com/down...");
fileTransfer.download(
uri,
fileURL,
function(entry) {
console.log("download complete: " + entry.toURL());
},
function(error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("download error code" + error.code);
},
false,
{
headers: {
"Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
}
}
);
So first off - yes - you can download a PDF, or any file within reason. You know you can because you yourself said you saw the download complete message, right?
So - as for viewing it - theres a few options here. Let me get back to you on that. You may be able to simply window.location.href = entry.toURL().
Howsit Raymond, I'm trying to download a video file on the click of a button on both Android and iOS. I can get it to work fine on Android but not on iOS. As far as I can see it is the target directory that is the problem here.
After a lot of research I just can't seem to get the target path right and using the other solutions i.e. cordova.file.applicationDirectory, cordova.file.dataDirectory doesn't seem to work. Please help if you can, here is my code:
if (devicePlatform === 'Android') {
baseUrl = '/storage/emulated/0/Download/';
}
else if (devicePlatform === 'iOS') {
baseUrl = 'var/mobile/Applications/<application uuid="">/Documents/Download/';
}
It is this baseURL that is the problem. I don't know how to get that path dynamically?
$('#download6').on('click', function (e) {
e.preventDefault();
var fileTransfer = new FileTransfer();
var uri = encodeURI("URLOFVIDEO");
var fileURL = baseUrl + 'FILENAME';
$('#videoContainer6').html('<img alt="" src="images/loading.gif"/>
Downloading');
fileTransfer.download(
uri,
fileURL,
function (entry) {
alert('Your video has finished downloading to: Device Storage > Download > FILENAME');
console.log("download complete: " + entry.toURL());
$('#videoContainer6').html('Video Downloaded.');
},
function (error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("download error code" + error.code);
},
false,
{
headers: {
"Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
}
}
);
return false;
});
So when you tried cordova.file.dataDirectory, how did it fail?
It succeeds, but when I go to that folder there is no file. Tried the cache directory as well, get the succeed message from the File Transfer function but no actual file in directory...very strange.
How are you "going to the folder"? Are you using the File system APIs to get a directory listing?
Just using "My Files" on Android and when going to Android->Storage->Data->App->Files/Cache there is nothing there.
Well keep in mind - some of these folders are private to the app itself. Ie, only the *app* can see it - so that may be your issue. If you use the File API to get a file listing, see if *that* shows up.
Cool will have a look thank you
Hi Raymond,
I have tried your method with some modification, but I met with some issues.
Every time I tried to download something, whether there exists the file, the file will be created but not any data is downloaded, so the file is 0 byte. Every time, "already exists" prints. Do you have any idea?
window.resolveLocalFileSystemURL(dirname.nativeURL+"/"+path.dir+"/"+path.name, function(){
console.log("already exists");
}, function(){
var p = fe.toURL();
console.log("p====>"+p);
fe.remove();
ft = new FileTransfer();
ft.download(
encodeURI(url),
p,
function(entry) {
console.log("entry===>"+entry);
// $scope.imgFile = entry.toURL();
deferred.resolve();
},
function(error) {
deferred.reject();
},
false,
null
);
});
If you log the error in the error handler for download, what do you see?
Hi Raymond,
You mean the second parameter of window.resolveLocalFileSystemURL() is error handler for download??
window.requestFileSystem(LocalFileSystem.PERSISTENT, 1024*1024*100, function(fs) {
fs.root.getDirectory(
"EvnetsTiles",
{
create: true,
},
function(dirname) {
dirname.getDirectory(path.dir,
{
create: true,
},
function(dirEntry){
dirEntry.getFile(
path.name,
{
create: true,
exclusive: false
},
function gotFileEntry(fe) {
window.resolveLocalFileSystemURL(dirname.nativeURL+"/"+path.dir+"/"+path.name,
function(){
console.log("already exists");
}, function(){
var p = fe.toURL();
console.log("p====>"+p);
fe.remove();
ft = new FileTransfer();
ft.download(
encodeURI(url),
p,
function(entry) {
console.log("entry===>"+entry);
deferred.resolve();
},
function(error) {
deferred.reject();
}
);
});
},
function() {
deferred.reject();
}
);
});
}
);
});
You posted the code again - that's not what I want. When you do deferred.reject(), can console.log(error) to see what the error is?
Hi Raymond,
I am working with an ipad, but I have the issue that after the image is downloaded it don't show in the img tag, the thing is it works with cache folder :
var targetPath = cordova.file.cacheDirectory + "folio/assets/images/testImage0.jpg"; //work
var targetPath = cordova.file.dataDirectory + "testImage.jpg"; // don't work
"folio/assets/images" I take this path from other image that I don't download it is part of the content.
sorry for bad English, not native speaker.
Do you get a 404 error in the console - for the image I mean.
Not i don't get any error, it seems to be something with path, I can download image wherever I want : cordova.file.cacheDirectory, cordova.file.dataDirectory, cordova.file.documentsDirectory but I only can show the ones saved in cordova.file.cacheDirectory, I have trying with adiccional folder but i get same result :
cordova.file.dataDirectory + "/image/someimage.jpg"
cordova.file.dataDirectory + "/content/image/someimage.jpg" etc.
it only work with "cordova.file.cacheDirectory" my fear is that this directory can be cleared whenever the OS desires, that is why i want to use cordova.file.cacheDirectory or cordova.file.documentsDirectory
If the image didn't load, *something* went wrong. What do you see when you remote debug?
I am not doing remote debugging, I will do it and tell you what i get.
Hi Raymond,
I'm wondering how to specify a specific file to download as part of the download() call. So when we call upload(), can can include params that allow our server to make additional determinations regarding what to do with the uploaded file. When I call download (to download a picture for a person's profile for instance), the server needs to do which specific picture to download - I don't see how to tell it that as part of the download() call since there is no ability to add params onto the call. Any advice?
"So when we call upload(), can can include params "
Yes, look at the API docs for the plugin, this is supported.
"I don't see how to tell it that as part of the download() call since there is no ability to add params onto the call"
Since you are passing a URL, you can use URL params. Ie,
myserver.com/image.php?id=X
Hey i encountered the same problem. The error given in the console is 'Failed to load resource: The operation couldn’t be completed. Operation not permitted'. I used 'cordova.file.documentsDirectory'
It may be that you can read and write to the directory but can't use it as an image source. You should maybe consider another path.
I also was to mention that it works in the simulator but not on device
Not sure what else to suggest off the top of my head. At this point I'd need to get your code, run it, etc, which would be a paid engagement.
Hi Raymond,
I'm trying to download a file but the file using this plugin. On the success callback, I am triggering the FileOpener2 plugin. However, the fileOpener2 plugin throws an error that the file is not found. When I go check in the file directory on an android phone through the file manager, the file does not exist. I have posted the question with some code on SO, link is: http://stackoverflow.com/qu...
Please check this out.
I'm not using the fileOpener2 plugin in this blog post.
I am using the fileOpener2 plugin just to open the downloaded file. My concern is not with the fileOpener2 plugin but it is about downloading of the file itself. The file is not getting downloaded.
I found the issue to be with the new permissions in Android 6.0 and above. I've posted the answer on my question in SO and if anyone here has come across a similar issue, you can check my answer.
Cheers! :)
I am using the fileOpener2 plugin just to open the downloaded file in my cordova hybrid app(android version) .It works only once after logging.If we again click on the pdf image ,it's not working and didn't get any error.If we logout and login again it will work for the first time.
You say no error, so I assume you checked developer tools. Outside of that - no idea. I'd post a report on the GitHub repo for the plugin.
Where can files added be to an Android and iOS cordova project so files are preloaded into the dataDirectory?
For the longest time I have been using applicationDirectory which is read-only. In the project, add the files to be preloaded into (android) /platforms/android/assets and (iOS) simply add the files to the root of project in Xcode (I still don't know where it places the files in the Xcode project though, but it works.)
But now I need to write to these preloaded files which means I need to change the folder to a read-write folder...based on my reading, I think the best location for this is the dataDirectory (based on the assumption that both OS's do not clear this folder/data - please correct me if I am wrong). I need the data files to be persistent so long as the app is installed.
But for the life of me I can't find any documentation on what directory path to add these files to the project so they get properly preloaded into the dataDirectory during app install
Any other insights would be appreciated too.
My understanding is that files in this path are not a part of the www/dom resource structure. Thus an image placed in it is not accessible from a www page. The only other way would be to read the file and write the file on the fly to the page being rendered
Sorry you got me there. Obviously you could do a one time copy - that may be your only solution.
Glad again i found this. We had conversation before 2 years. But again stuck on this. SO for more clarification my question is:
i have some files at removable SdCard in location /storage/450-283/test
i need to grab from those files and copy inside internal storage of device.
But i can't able to fetch files from removable SdCard in location /storage/450-283/test.
Please more clarification i need to READ/WRITE file from external sdcard ( removable sdcard ).
Thanks again man.
I'd check the FIle plugin documentation and see what it says about external storage. The docs say what you have R/W access to.
Hi Raymond,
Thank you. But got working now.
below is my code for your reference:
function getExternalSdLocation(done){
cordova.plugins.diagnostic.getExternalSdCardDetails(function(details){
details.forEach(function(detail){
if(detail.type == "application"){
cordova.file.externalSdCardApplicationDirectory = detail.filePath;
}else if(detail.type == "root"){
cordova.file.externalSdCardRootDirectory = detail.filePath;
}
});
done();
}, function(error){
console.error(error);
done();
});
}
function requestExternalSdPermission(done){
cordova.plugins.diagnostic.requestRuntimePermission(function(status){
switch(status){
case cordova.plugins.diagnostic.permissionStatus.GRANTED:
console.log("Permission granted");
getExternalSdLocation(done);
break;
case cordova.plugins.diagnostic.permissionStatus.DENIED:
console.log("Permission denied");
askAgain(done);
break;
case cordova.plugins.diagnostic.permissionStatus.DENIED_ALWAYS:
console.log("Permission permanently denied");
reportError(done);
break;
}
}, function(error){
console.error("The following error occurred: "+error);
reportError(done);
}, cordova.plugins.diagnostic.permission.WRITE_EXTERNAL_STORAGE);
}
requestExternalSdPermission(function(res){
console.log("Permission done " , res);
})
function checkIfFileExists(path){
window.resolveLocalFileSystemURL(path,
function(fileSystem){
console.log("File System " ,fileSystem )
fileSystem.getFile('1.jpg', { create: false }, function(fileEntry){
console.log("File " + fileEntry.fullPath + " exists!");
}, function(){
console.log("file does not exist");
});
},function(){
console.log("Error Grab file system" );
}) //of requestFileSystem
}
setTimeout(function(){
checkIfFileExists(cordova.file.externalSdCardRootDirectory + '/test')
},5000);
That will check in removable sdcard and inside it "test" folder and search for file "1.jpg" and it's working great.
Thank you for your valuable time man.
Does ANYONE have a demo Phonegap or Cordova file download app template that works. I am trying to build an app that is able to download files to Android device. I am not sure how to download or include the plugin the the config.xml file and need a working guide. Please share if you have something. Thanks !