Tuesday, July 15, 2014

Cordova - download and open file on Android (pdf, doc, etc.)

I've tried many ways to open downloaded files in Cordova (preferably using users default Android app). One of most popular you may find on Internet is:

 window.open(encodeURI(url), '_system', "location=yes");  

It didn't work for me. Sometimes images were open in new 'browser' tab, where user couldn't do anything with the pic (neither zooming nor rotating). PDFs didn't open at all. 





After a few other attempts, I end up using WebIntent with following solution:

1. add WebIntent to your project 

As described on project site

You also need to add some permissions to AndroidManifest.xml:

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>  
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  

2. download file via FileTransfer:

Js code:


 fileTransfer.download(  
      uri,  
      destination,  
      function(entry) {  
       //you can add any progress indicator here  
       window.webintent.startActivity({  
            action: "android.intent.action.VIEW",  
            url: encodeURI(entry.toNativeURL())  
       }, function () {}, function (error) {  
            //error handling  
       });  
       //window.open(encodeURI(url), '_system', "location=yes");  
      },  
      function(error) {  
       //error handling  
      },  
      true  
 );  

3. modify WebIntent.java

Default WebIntent.java needs some changes in order to properly recognize file type, otherwise it may fail trying to guess which activity to use to open file. WebIntent.java expects to get 'type' from the JS, but guessing file type on client side is not always best idea.

Changes are really easy:

A. Add import:


 import android.webkit.MimeTypeMap;  

B. modify code responsible for guessing type, by simply adding few lines:

(code around line 50) :

 JSONObject obj = args.getJSONObject(0);  
 String type = obj.has("type") ? obj.getString("type") : null;  
 // New code starts  
 Uri uri = obj.has("url") ? Uri.parse(obj.getString("url")) : null;  
 String extension = MimeTypeMap.getFileExtensionFromUrl(obj.getString("url"));  
 if(extension != null){  
      MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();  
      type = mimeTypeMap.getMimeTypeFromExtension(extension);  
 }  
 // New code ends  
 JSONObject extras = obj.has("extras") ? obj.getJSONObject("extras") : null;  

And that's it;)

Let me know if you find it helpful or maybe you found a better solution?

No comments:

Post a Comment