Titanium Community Questions & Answer Archive

We felt that 6+ years of knowledge should not die so this is the Titanium Community Questions & Answer Archive

Open PDF File on Android

Has anyone found a way to open or view a PDF file on Android? I understand that webview doesn't support PDF on android. I have PDF viewers on the handset, but how can I open the PDF from the app?

— asked October 21st 2010 by Mike Hopkins
  • android
  • pdf
0 Comments

9 Answers

  • Accepted Answer

    With some of the new APIs that have been exposed, this is now a lot easier. You don't need to hack anything in to the source code. Take a look at the following:

    try {
        var f = Ti.Filesystem.getFile('your.pdf');
        Ti.Android.currentActivity.startActivity(Ti.Android.createIntent({
            action: Ti.Android.ACTION_VIEW,
            type: 'application/pdf',
            data: f.getNativePath()
        }));
    }
    catch (err) {
        var alertDialog = Titanium.UI.createAlertDialog({
            title: 'No PDF Viewer',
            message: 'We tried to open a PDF but failed. Do you want to search the marketplace for a PDF viewer?',
            buttonNames: ['Yes','No'],
            cancel: 1
        });
        alertDialog.show();
        alertDialog.addEventListener('click', function(evt) {
            if (evt.index == 0) {
                Ti.Platform.openURL('http://search?q=pdf');
            }
        });
    }
    
    — answered August 16th 2011 by Dawson Toth
    permalink
    18 Comments
    • Awesome. Thanks man. I was not looking forward to hacking the source each time a new SDK came out.

      — commented August 19th 2011 by Ken Rucker
    • Hi,

      I tried the same code, but for some reason, am getting 'Invalid file path' error. This is the path used . I am downloading a pdf file to the same path before invoking this below code.

      var f = Ti.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,'my.pdf');
      Ti.Android.currentActivity.startActivity(Ti.Android.createIntent({
                      action: Ti.Android.ACTION_VIEW,
                      type: 'application/pdf',
                      data: f.getNativePath()
                  }));
      

      The device I'm using is a Spring Evo 4G which I believe is running Android 2.3.

      — commented September 9th 2011 by Prathima Doraiswamy
    • @Prathima: You are getting the invalid path error because the PDF reading app that your intent is launching can't access the file. Your application's data directory is sandboxed to your app, so no one else can access it. You need to either a) place the PDF in a publicly accessible place, like on the SDCard, or b) set the file as world_readable. Note that option b isn't possible with Titanium yet, so you would need to create your own module.

      There is an open feature request for expose the world_readable mode: http://jira.appcelerator.org/browse/TIMOB-2957

      — commented September 9th 2011 by Dawson Toth
    • I'm using your code to open a PDF file on the web, but an error message appear that "Unable to open this file"

      I'm putting the url of the pdf file here: var f = Ti.Filesystem.getFile('your.pdf');
      instead of 'your.pdf'

      — commented September 20th 2011 by Haya aziz
    • @Haya aziz: Please read my comment directly above your own @Prathima. The PDF is not accessible outside of your application when it isn't on the SDCard.

      — commented September 20th 2011 by Dawson Toth
    • @Dawson, Thanks for the answer!

      Regarding the first solution, we are concerned that some android phones may not have the SD card and so will not be reliable.

      About the second solution, that sounds good.
      I happened to see that this ticket is resolved already in 1.7 release. Can you let me know how I can set the file as world_Readable?

      — commented September 29th 2011 by Prathima Doraiswamy
    • Hi,

      I tried this code too, but I get the error that there is no activity to handle the Intent. Do I need to add another activity to the tiapp.xml manifest? If so, what should it be?

      Here is the exception I am getting-

      android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=file:///data/data/com.intel.vaandroid/app_appdata/va10-stan-lee-guardians-article-gd-092911.pdf typ=application/pdf }
      E/KrollMethod(16060): at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1408)

      (I was so excited to find this answer to view PDFs in Android. I hope this work!)

      Thanks,
      Sri

      — commented October 17th 2011 by Sridevi Kolluri
    • @Sridevi: The device doesn't have a PDF reading app. That's where the try-catch in my sample comes in to play. It asks the user if they want to search the market for a PDF reading app.

      — commented October 17th 2011 by Dawson Toth
    • Thanks, Dawson. I have now fixed that problem, downloaded Adobe Reader and another PDF Viewer on the Android Samsung Galaxy I testing the app on. Now, the app asks me if I want to open it in one of the PDF Viewers. But when I select Adobe, it opens Adobe reader, and gives me the message that there are no files to display.

      Can you help me with this, please?

      Thanks so much!
      Sri

      — commented October 18th 2011 by Sridevi Kolluri
    • Dawson,

      As per your comment above - that noone can access the files on the app's data directory (I would assume the Resources folder as well), how can we move that file to a place where it can be accessible? - to the SD Card (which may not work for us), or to set the file as "World-readable"?

      You mentioned this is fixed in 1.7. I am running 1.7.3 Titanium SDK now.

      THanks,
      Sri

      — commented October 18th 2011 by Sridevi Kolluri
    • @Sridevi: Please look at the Jira ticket I mentioned earlier: TIMOB-2957. Jon Alter has posted a workaround (store your PDF in Titanium.Filesystem.externalStorageDirectory).

      — commented October 18th 2011 by Dawson Toth
    • I found another psoting which had an answer on how to get the path for an external storage for an android device.

      http://developer.appcelerator.com/blog/2011/09/sharing-project-assets-with-android-intents.html

      Thanks all of you who are answering our questions!

      Thanks,
      Sri

      — commented October 18th 2011 by Sridevi Kolluri
    • This works perfectly for me (on SDK 3.2.1 and android 4.2.2) after installing a PDF Viewer on emulator.

      I'm putting files on /data/data/myapp.com/app_appdata

      — commented July 4th 2014 by f fabreti
    • Oh, forget to mention that Ti.Platform.openURL('http://search?q=pdf'); did NOT worked for me.

      Instead, I used Ti.Platform.openURL('market://search?q=pdf');

      — commented July 4th 2014 by f fabreti
    • You can write the PDF file to 'Ti.Filesystem.applicationDataDirectory' but you need to copy it to a temp location to make it accessible to other apps.

      I tried Ti.Filesystem.createTempFile but it creates files NOT word readable.

      So I did this:

      function openPDF(filename) {
      
         //create tmpdir
         var tmpdir = Ti.Filesystem.getFile(Ti.Filesystem.tempDirectory,'pdfs');
         tmpdir.createDirectory();
      
         //create temp file //WORLD READABLE/WRITEABLE
         var tmpFile = Ti.Filesystem.getFile(tmpdir.nativePath, filename ); 
      
         //copy file to temp file     
         var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, filename);
         tmpFile.write( f.read() );
      
         //start intent
         try {
           Ti.Android.currentActivity.startActivity(
                  Ti.Android.createIntent({
                          action: Ti.Android.ACTION_VIEW,
                          type: 'application/pdf',
                          data: tmpFile.getNativePath()
                  })
           );
         }
        ....
      

      — commented July 5th 2014 by f fabreti
    • Hi f fabreti!
      I was trying to use your recent code in my Android app without any success, so I noticed that my local .pdf is in the Resources folder. So the trick is change:

      var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, filename);
      

      by

      var f = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, filename);
      

      Thank you for the tip!

      — commented July 21st 2014 by Carlos Henrique Lustosa Zinato
    • I have used the above code.my pdfreader is opening and then giving an error " the document path is not valid"

      — commented January 19th 2015 by Naimika Senghani
    • How to open .docx using the intent. What will be the tpye for the intent?

      — commented May 21st 2015 by chidambaram samiappan
  • Actually, I have a better answer now.

    If you look at the source for what Titanium.Platform.openURL is doing on Android, you'll see it's creating and starting an intent. This works great for PDFs on most Android devices.

    But it doesn't work exactly like it should, and I found it didn't work at all on a bunch of HTC android devices.

    I got around this by pulling the source for Titanium Mobile down, and adding a new method to the Titanium.Platform: "openURLWithType". It looks something like this:

    public boolean openURLWithType(String url, String type) {
                   if (DBG) {
                           Log.d(LCAT, "Launching viewer for: " + url);
                   }
                   Uri uri = Uri.parse(url);
                   Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                   intent.setDataAndType(uri, type);
                   intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                   try {
                           getTiContext().getActivity().startActivity(intent);
                           return true;
                   } catch (ActivityNotFoundException e) {
                           Log.e(LCAT,"Activity not found: " + url, e);
                   }
                   return false;
    }
    

    Two small differences:
    1) intent.setDataAndType(uri, type) will let you specify what you're linking to so that third party apps can pick it up.
    2) intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)

    Then I can do the following and the PDF is properly launched:

    if (Ti.Platform.openURLWithType('my.pdf', 'application/pdf')) {
       // success!
    }
    else {
       alert('You need to download a PDF viewer from the market!');
    }
    

    I'm working with the latest code from the 1.4x branch on github. I remember hearing rumor that they were adding support for this in 1.5 or something, but I don't know anything definite.

    DM me @dawsontoth on Twitter if you want to know more about this approach…

    — answered November 10th 2010 by Dawson Toth
    permalink
    4 Comments
    • Any chance you could give me some instruction on hour to do this? I guess the TI code is compiled or something on my dev Mac. I don't see where the raw code is to where I can modify it to add this function… or how I would recomoile TI or whatever after the new function is added. Kind of a newbie to advanced things like this. Maybe there is a module somewhere I could use instead? Any help is greatly appreciated. Open PDF with open URL doesn't work on my HTC or may Acer tablet.

      — commented August 1st 2011 by Ken Rucker
    • I think this may be what I need. Haven't tried yet but maybe it will help others-

      http://www.metalsoft.com.ar/2011/07/22/titanium-mobile-android-open-urls-specifying-the-type/

      — commented August 1st 2011 by Ken Rucker
    • Got it going with the link above. Works awesome. Thanks Dawson and Sebastian. Real life savers.

      — commented August 2nd 2011 by Ken Rucker
    • Hey Ken, I just added a new answer to this. You don't need to apply any hacks to the source code anymore.

      — commented August 16th 2011 by Dawson Toth
  • you can simply open it using Google viewer
    http://docs.google.com/viewer?pli=1

    — answered September 10th 2011 by Haya aziz
    permalink
    0 Comments
  • I'm new to android and I'm trying to develop an application which creates the ".pdf" files i.e. i have one form(contains the information of the person) this information should be stored in the .pdf format.. so how to do this ???please help me out in this…

    — answered December 22nd 2011 by varun k
    permalink
    1 Comment
    • Since I dont know anything about generating PDFs locally, i would use a server for doing that. Send your data via http, to a server which generates the PDF with your data, and send that back to you (your phone)

      — commented June 25th 2012 by Lars C. Magnusson
  • I was able to load a PDF inside the android browser using Pdf.js https://github.com/mozilla/pdf.js

    It's a javascript library the renders it into the HTML 5 Canvas element. It's a little heavy. That's the only downside. It renders out near perfect though. Also, I was able to get it to work on Android 4.0+ in the emulator. I tried it on my android device which is 2.2.2 and it didn't work.

    — answered July 11th 2012 by Ronnie Swietek
    permalink
    1 Comment
    • How you do that, I tried withe thier examples and there was a lot of problem. Pdf doesn't appeared :/ Could you give me tip?

      — commented September 18th 2012 by Tomasz Mucha
  • To view pdf you can use MPDF libraries. It's free and you can also use annotation and highlight the text features. More details you will get on http://www.mupdf.com

    there are also some pdf viewer apis that you can use:
    1. apdfviewer
    2. droidreader

    — answered July 5th 2013 by Pooja Laad
    permalink
    0 Comments
  • i was wondering whether this vb.net pdf viewer can integrate with the android system. if so, then everything will become much easier. you can load and and process pdf documents.

    — answered July 1st 2013 by fdsf fdsfd
    permalink
    1 Comment
  • Hi,

    Get the pdf from resourcesDirectory, and trying to write into tempDirectory.
    After successfully saved into tempDirectory, try to open in the Adobe Reader. Unable to open getting error
    message like file corrupted. Please help me to write the pdf in proper way.

    var pdfFile = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory,'My_PDF.pdf');

     setTimeout(function()
     {
            var tmpFile = Ti.Filesystem.getFile(Ti.Filesystem.tempDirectory,'tmpFile.pdf');
            tmpFile.write(pdfFile.read());
            Ti.API.info("Temp Directories:" + Ti.Filesystem.tempDirectory);
        },1000);
    

    Thanks in Advance..

    — answered June 5th 2015 by chidambaram samiappan
    permalink
    1 Comment
    • PDF (Which we saved in temp directory) should support to open in all browser and supported application.

      — commented June 5th 2015 by chidambaram samiappan
  • if you need to open/view PDF file in your own app go to the marketplace Android PDF Reader. The demo is available to see how does it look like

    — answered December 24th 2013 by Ario Barzan
    permalink
    0 Comments
The ownership of individual contributions to this community generated content is retained by the authors of their contributions.
All trademarks remain the property of the respective owner.