Using Cordova/PhoneGap 3.3.0, I am downloading a file using the FileTransfer plugin, and then trying to open it using the InAppBrowser plugin. I can download the file successfully, and place it in the temp directory. Since the File plugin now uses URL schema, I cannot figure out how to pass the correct url/path to the window.open
method of the InAppBrowser plugin. I cannot find any relevant documentation either. All of the "download and open" documentation I can find is out of date and pre-URL-schema.
Relevant links:
Out of date examples I found:
entry.fullPath
, which is now deprecated in favor of toURL()
Here is my code:
var uri = encodeURI("http://some.url/file.pdf");
window.requestFileSystem(LocalFileSystem.TEMPORARY, 0,
function (fileSystem) {
var fileTransfer = new FileTransfer();
var filename = fileSystem.root.toURL() + uri.substr(uri.lastIndexOf("/") + 1);
fileTransfer.download(uri, filename,
function(entry) { // download success
var path = entry.toURL(); //**THIS IS WHAT I NEED**
window.open(path, "_system");
},
function(error) {} // irrelevant download error
);
},
function(error) {} // irrelevant request fileSystem error
);
I am currently testing in Android on a Nexus 7 and Nexus 5. The InAppBrowser correctly opens the default pdf launcher (in my case Adobe Reader), but then I get a "The document path is not valid" error.
[Update: showing return values]
I have tried all of the following combinations for the file path:
var path = entry.toURL(); // "cdvfile://localhost/temporary/file.pdf"
var path = entry.fullPath; // "file.pdf"
var path = fileSystem.root.toURL() + filename; // "cdvfile://localhost/temporary/file.pdf"
var path = fileSystem.root.fullPath + filename; // "/file.pdf"
Since Cordova 3.4 the file protocol has changed and instead of using fullPath they now provide the toURL() that returns a cdvfile://path/to/your/file.ext path.
So when you download a file using the filesystem object's callback (with the entry argument) just call the entry.toURL() and open this using the following statement to open it - assuming you have InApBrowser installed and the _blank will open the InAppBrowser's window:
window.open(entry.toURL(), '_blank', 'location=no,closebuttoncaption=Close,enableViewportScale=yes');
I wrote about it in this post on my blog (if you want all the references and background info).
I THINK I have a solution to this, but it's kinda nasty.
I grepped through the cordova JAVA and looked for places it constructed a file entry JSON object. Specifically by looking for places where its adding fullPath
to the object.
I added an additional entry for "fullAbsolutePath" with the value [file].getAbsolutePath()
, where [file]
is whatever java.io.file instance is nearby. I did this in all the places I could find just to be safe and because it doesn't seem to hurt anything.
Then I modified FileEntry.js and File.js in the plugins\file folder to also populate that value to the file entry object.
Still trying to work out the kinks, but I believe I'm on the right track...
I think a better solution would be to modify the inAppBrowser plugin to recognize and resolve the cordovaFile:// protocol and im sure they obscured the absolute file system path on purpose - but that might be a bit beyond me.
EDIT - Yup! this works! I can now take a file entry, call the file method, then read fullSystemPath off the fileObject. Value is like "/storage/emulated/0/whatever/" on my android. Just need to prepend "file://" and window.open will accept it.
In the latest cordova docs they say
If you are upgrading to a new (1.0.0 or newer) version of File, and you have previously been using entry.fullPath as arguments to download() or upload(), then you will need to change your code to use filesystem URLs instead.
FileEntry.toURL() and DirectoryEntry.toURL() return a filesystem URL of the form
cdvfile://localhost/persistent/path/to/file which can be used in place of the absolute file path in both download() and upload() methods.
What you can try is remove cdvfile://localhost/persistent
to have a url that would work with your window.open. (maybe start with a alert or console.log of what you get with entry.toURL()
)
In current plugin dev branch there is a solution:
Entry.toNativeURL() - Returns the full path to the file in the device FileSystem.
https://github.com/apache/cordova-plugin-file/tree/dev
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With