Appcelerator Blog

The Leading Resource for All Things Mobile

Appcelerator PDF Viewer Demo

3 Flares 3 Flares ×

Viewing a PDF file in a mobile app is a fairly common use case. However, how you do this on Android and iOS are very different. iOS has a built-in document viewer capability, while on Android you open the PDF file in an external application that has support for PDF viewing. This blog post demonstrates both how to view a PDF file downloaded from the web and a PDF file stored as an app resource.

The following links to the Appcelerator online documentation will be useful as background information:

  1. Filesystem Access and Storage
  2. Titanium.UI.iOS.DocumentViewer
  3. Android Intents

iOS

On iOS, the steps are fairly straightfoward.

Application Resource

For the local resource, the steps are:

  1. Get a handle to the file that is stored as a local resource. In this case, the file is stored in /app/assets/pdf/sample.pdf
appFile = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, 'pdf/sample.pdf');
  1. Create an instance of the document viewer with a reference to the PDF file and show the document viewer
var appfilepath = appFile.nativePath
docViewer = Ti.UI.iOS.createDocumentViewer({url:appfilepath});
docViewer.show();
Remote PDF File

For the remote PDF file, the steps are:

  1. Create a file to store the PDF file that will be retrieved from the remote source (e.g. web site). In this case, the PDF is a subway map, so the filename I am creating is map.pdf.
appFile = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'map.pdf');
  1. Retrieve the PDF file using a HTTPClient request. In this case, the PDF file is located at http://www.mbta.com/uploadedfiles/Documents/Schedules_and_Maps/Rapid%20Transit%20w%20Key%20Bus.pdf
var appfilepath = appFile.nativePath;
var xhr = Ti.Network.createHTTPClient();
xhr.onload = function() {
    appFile.write(this.responseData);
  docViewer = Ti.UI.iOS.createDocumentViewer({url:appfilepath});
  docViewer.show();
};
xhr.onerror = function() {
    alert("Cannot retrieve PDF from web site")
};
xhr.timeout = 10000;
xhr.open("GET", "http://www.mbta.com/uploadedfiles/Documents/Schedules_and_Maps/Rapid%20Transit%20w%20Key%20Bus.pdf");
xhr.send();

Android

On Android, there are a few more steps involved because:

  1. An Intent must be created to look for an application on the device that can handle PDF files and then pass the PDF file on to the app
  2. In order to pass the PDF file to an external PDF viewer application, the PDF file must be in external memory (i.e. SDCard)

But, Appcelerator makes this all easy.

Application Resource

For the local resource, the steps are:

  1. Get a handle to the file that is stored as a local resource. In this case, the file is stored in /app/assets/pdf/sample.pdf and store it in external memory.
var originalFile = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, 'pdf/sample.pdf');
appFile = Ti.Filesystem.getFile(Ti.Filesystem.externalStorageDirectory, 'sample.pdf');
appFile.write(originalFile.read());
  1. Try to open an external PDF viewer application and pass the PDF File
var appfilepath = appFile.nativePath;
try{
    Ti.Android.currentActivity.startActivity(Ti.Android.createIntent({
        action: Ti.Android.ACTION_VIEW,
        type: 'application/pdf',
        data: appfilepath
    }));
} catch(e) {
    Ti.API.info('error trying to launch activity, e = '+e);
    alert('No PDF apps installed!');
}
Remote PDF File

For the remote PDF file, the steps are:

  1. Create a file to store the PDF file that will be retrieved from the remote source (e.g. web site). In this case, the PDF is a subway map, so the filename I am creating is map.pdf.
appFile = Ti.Filesystem.getFile(Ti.Filesystem.externalStorageDirectory, 'map.pdf');
  1. Retrieve the PDF file using a HTTPClient request. In this case, the PDF file is located at http://www.mbta.com/uploadedfiles/Documents/Schedules_and_Maps/Rapid%20Transit%20w%20Key%20Bus.pdf and launch the intent:
var appfilepath = appFile.nativePath;
var xhr = Ti.Network.createHTTPClient();
xhr.onload = function() {
    appFile.write(this.responseData);
  try{
    Ti.Android.currentActivity.startActivity(Ti.Android.createIntent({
        action: Ti.Android.ACTION_VIEW,
        type: 'application/pdf',
        data: appfilepath
    }));
  } catch(e) {
    Ti.API.info('error trying to launch activity, e = '+e);
    alert('No PDF apps installed!');
  }
};
xhr.onerror = function() {
    alert("Cannot retrieve PDF from web site")
};
xhr.timeout = 10000;
xhr.open("GET", "http://www.mbta.com/uploadedfiles/Documents/Schedules_and_Maps/Rapid%20Transit%20w%20Key%20Bus.pdf");
xhr.send();

Putting It All Together

A sample app that handles iOS and Android and provides more modular, reusable code can be found here.

Screen Shots

iPhone Screen Shots:

Appcelerator PDF Viewer iPhone screenshot example

Android Screen Shots:

Appcelerator PDF Viewer Android screenshot example

3 Flares Twitter 0 Facebook 0 Google+ 3 LinkedIn 0 Email -- 3 Flares ×

6 Comments

  1. Michael

    Two other ways for android which won’t use external apps: using pdf.js (https://github.com/m1ga/ti-pdf-js) or this module (https://github.com/ishansingh2003/Android-Pdf-Viewer)

    • Leor Brenman

      Good point Michael. I neglected to mention that are libraries and modules for Android for in app PDF viewing. Thanks for adding.

  2. Dan

    Thanks for the info, but what if I get an e-mail with an attachment? Currently pressing on the attachment raises a dialog with apps associated with the type of file.

    How does one make that association using Appcelerator?
    How does my app get the data if it’s running vs. if it’s not running?

    In your example your app reaches out to a URL.

  3. I have to read this again later for reference. Thanks for sharing.

Comments are closed.

Sign up for updates!

Become a mobile leader. Take the first step to scale mobile innovation throughout your enterprise.
Get in touch
computer and tablet showing Appcelerator software
Start free, grow from there.
3 Flares Twitter 0 Facebook 0 Google+ 3 LinkedIn 0 Email -- 3 Flares ×