Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cordova/PhoneGap Open Downloaded File (InAppBrowser)

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:

  • Cordova Release info on New Plugin Versions
  • The readme for the FileTransfer plugin
  • The readme for the InAppBrowser plugin
  • How to open local file with InAppBrowser with recent changes to URL scheme in File plugin - Similar question

Out of date examples I found:

  • File-transfer download file issue on Cordova 3.1 - This user downgraded to an earlier version because they couldn't figure it out
  • https://gist.github.com/devgeeks/4982983 - This example uses 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"
like image 418
chadiusvt Avatar asked Feb 21 '14 17:02

chadiusvt


4 Answers

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).

like image 164
EeKay Avatar answered Oct 14 '22 12:10

EeKay


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.

like image 33
nihlton Avatar answered Oct 14 '22 13:10

nihlton


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())

like image 45
QuickFix Avatar answered Oct 14 '22 12:10

QuickFix


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

like image 36
xudre Avatar answered Oct 14 '22 14:10

xudre