Ok you wanna know how to get that (PDF) file downloaded to your device and open it like a magician presents his assistant from a black hat?
Ofcourse you’ll need the file-transfer plugin to have any chance at retrieving a file from somewhere. Let me show you what’s changed and how to get back into downloading and showing files (like a PDF) in the InAppBrowser.
Let’s dive into this and get you going!
- Use entry.fullURL() instead of entry.fullPath in the download done callback from the filetransferobj.download.
- Open the file with the function from step 1 using the following:
1window.open(entry.toURL(), '_blank', 'location=no,closebuttoncaption=Close,enableViewportScale=yes');
- the enableViewportScale will make it zoomable and pan in iOS. Check the long answer for Android flavored suggestions
The full story
We all know that Apache bought Cordova / Phonegap and is active with the maintenance and expanding of Cordova CLI and Phonegap Build (with the accompanying CLI).
Although Apache is a big player it seems we cannot expect them to keep up 100% with the fast paced release schedule.Now and then features have changed, the structure of projects change and we need to update check and de- and reinstall stuff.
No sweat; it may take some time but when you’re working on a cool ‘hybrid’ mobile app project involving all sorts of sweet JS libraries (like DurandalJS, Hammer.JS, etc) wrapped into a Cordova (CLI generated) blanket* you’ll eventually get the hang on how to optimize stuff and check for tooling updates instead of trying to find the awkward behavior in your code.
*: i’ll write up a post on when to use Cordova CLI over Phonegap Build some time soon
But the problem I’m gonna handle in this post is:
[ad name=”Generic Large Mobile Banner 320 x 100″]
Why the h*ll doesn’t the example code for downloading a file to the native side work and let me show a PDF file?
- Include and load cordova.js
- request the filesystem for the native location
- create a FileTransfer object
- call the download function on the FileTransfer object to download the file from an URI
- get the location of your downloaded file and do with the file whatever you want (like showing the file in the InAppBrowser plugin window)
In code the documentation shows the following example:
// !! Assumes variable fileURL contains a valid URL to a path on the device,
// for example, cdvfile://localhost/persistent/path/to/downloads/
var fileTransfer = new FileTransfer();
var uri = encodeURI("http://some.server.com/download.php");
console.log("download complete: " + <strong>entry.fullPath</strong>);
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("upload error code" + error.code);
"Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
And there you’ll encounter the main issue: using the latest Cordova (> 3.4) this will just NOT work.
The entry.fullPath will show you something like “/thefile.ext” and that just isn’t the sandboxed environment that the file is actually saved in.
After spending some hours investigating how to get the correct path, this StackOverflow post led me into the right direction by pointing me to an overhaul of the file plugin, as explained the corresponding issue, CB-5403.
The issue states:
File is getting overhauled, to provide the following features:
1. Entry.toURL() should return a filesystem:// URL on platforms which support it. Platforms which cannot support custom URL protocols are free to return URLs which can be used to access the local file system.
And there you have it: instead of using entry.fullPath as used in the above code example you should now use entry.toURL(). This will give you a location of the file using the Cordova File url format (that starts with cdvfile://path/to/your/file.ext, as stated in this comment in the issue).
Although there are a lot of implementations and ways about how to show a file in a InAppBrowser view, it can be as easy as:
window.open(entry.toURL(), '_blank', 'location=no,closebuttoncaption=Close,enableViewportScale=yes');
So, coming back to downloading and showing an actual PDF; if the URI of the filetransfer.download pointed to a .PDF file this should let you open up the PDF in the InAppBrowser.
But I want to be able to zoom, pinch and move around on the PDF in my iOS app??? See that InAppBrowser option comma separated list in the window.open call I wrote above? It states “enableViewportScale=yes” which basically tells the view to be able to zoom, pan and all of that.
And how can I open this cewl freshly downloaded PDF on Android? Well, since Android has no standard native PDF viewer on board there are two options that could be used depending on your goal:
- Skip downloading entirely and show the pdf via the online view capabilities of Google Doc Viewer, as stated in this StackOverflow answer
- DO download the file and use the FileOpener plugin for Android Phonegap apps as explained in this StackOverflow answer. This will either open the file in the installed PDF reader or present the user with a choice.
Hope this will save you the hours invested..[ad name=”Generic Large Mobile Banner 320 x 100″]