This is a provider that allows viewing of local PDFs on iOS and Android. Tested on Android 5,6 and 7. Tested on Ionic 3.19.1.
This will never work on Android if you use live reload as the above version of Ionic doesn’t see cordova. It does work without the live reload flag. So this, won’t show the PDF:
ionic run android -l
It uses Ionic Native File, Document Viewer and In App Browser. Ionic Native File Opener doesn’t work on iOS 11 at the moment so that isn’t an option and this solution uses the Document Viewer plugin on iOS but uses In App Browser on Android. Document Viewer on Android requires a third party app install which feels clunky and I wanted to avoid. This solution uses whatever native PDF viewer is available on Android (i.e. Google Docs).
First you need to add a line to your Ionic project config.xml to bypass the new permissions on Android 7 that prevent the local files from being viewed. There will no doubt be a more elegant solution but I wanted a quick fix:
<preferencename="android-targetSdkVersion"value="23" />
ionic g provider PdfViewer
import { File } from '@ionic-native/file';
import { DocumentViewer } from '@ionic-native/document-viewer';
import { InAppBrowser } from '@ionic-native/in-app-browser';
import { PdfViewerProvider } from '../providers/pdf-viewer/pdf-viewer';
providers: [ StatusBar, SplashScreen, File, DocumentViewer, InAppBrowser, {provide: ErrorHandler, useClass: IonicErrorHandler}, PdfViewerProvider ]
import { Injectable } from '@angular/core'; import { normalizeURL, Platform } from 'ionic-angular'; import { File } from '@ionic-native/file'; import { DocumentViewer } from '@ionic-native/document-viewer'; import { InAppBrowser } from '@ionic-native/in-app-browser'; /* **************************** This requires adding the line <preference name="android-targetSdkVersion" value="23" /> to the project config.xml otherwse Android 7 permissions don't allow opening the PDF file **************************** We're going to use Platfrom for platffrom detection then: Document Viewer for iOS In App Browser for Android window.open for browser And finally normalizeURL to propwerly format the URL based on platfrom. */ @Injectable() export class PdfViewerProvider { constructor(privatedocument:DocumentViewer, privateiab:InAppBrowser, privatefile:File, publicplt:Platform) { //console.log('Hello PdfViewerProvider Provider'); } openDocument(fileName) { letassetDirectory='assets/files/'; console.log(this.plt); console.log(assetDirectory); // normal link for browser if ( !this.plt.is('cordova') &&!this.plt.is('android') ) { console.log('browser'); window.open(assetDirectory+fileName); return; } // iOS and Android native letfilePath=this.file.applicationDirectory+'www/'+assetDirectory; // android using in app browser which prompts native file opener if (this.plt.is('android')) { lettheMove=this.file.copyFile(filePath, fileName, this.file.externalDataDirectory, fileName); filePath=this.file.externalDataDirectory; console.log(filePath+fileName); constbrowser=this.iab.create(normalizeURL(filePath+fileName), '_system', 'location=yes'); console.log(browser); } // ios use ionic document viewer becasue it's a nicer ux elseif (this.plt.is('ios')) { constoptions= { title:'My PDF', documentView : { closeLabel :'DONE' }, navigationView : { closeLabel :'DONE' }, email : { enabled :true }, print : { enabled :false }, openWith : { enabled :true }, bookmarks : { enabled :false }, search : { enabled :false }, autoClose: { onPause :true } } console.log(filePath+fileName); constviewer=this.document.viewDocument(filePath+fileName, 'application/pdf', options); console.log(viewer); } } }
Import your provider into whatever page component you want to display your PDF from:
import { PdfViewerProvider } from '../../providers/pdf-viewer/pdf-viewer';
and inject it into your constructor:
constructor(publicnavCtrl:NavController, publicnavParams:NavParams, publicpdfViewer:PdfViewerProvider) {}
and, after your constructor, add a function to call the function from your provider:
openDocument(fileName) { this.pdfViewer.openDocument(fileName); }
<button ion-button secondary (click)="openDocument('yourfile.pdf')">Open PDF</button>
Leave a Reply