Reputation: 55
I am building an Android/iOS Application with ionic 3, which simply consists of a webview by cordova-plugin-inappbrowser (version 3.0.0) and a responsive homepage. The homepage holds different links to websites as well as to (online) PDF files.
As I've learned, the webview in Android (I haven't tried iOS, yet) does not support opening PDF files. That's why I wanted to intercept the called URLs, and open them in some other way, if they end on '.pdf':
import { Component } from '@angular/core';
import {InAppBrowser, InAppBrowserObject, InAppBrowserOptions} from "@ionic-native/in-app-browser";
export class HomePage {
options : InAppBrowserOptions = {
location : 'no',//Or 'no'
hidden : 'no', //Or 'yes'
clearcache : 'yes',
clearsessioncache : 'yes',
zoom : 'no',//Android only ,shows browser zoom controls
hardwareback : 'yes',
mediaPlaybackRequiresUserAction : 'no',
shouldPauseOnSuspend : 'no', //Android only
closebuttoncaption : 'Close', //iOS only
disallowoverscroll : 'no', //iOS only
toolbar : 'no', //iOS only
enableViewportScale : 'no', //iOS only
allowInlineMediaPlayback : 'no',//iOS only
presentationstyle : 'pagesheet',//iOS only
fullscreen : 'yes'//Windows only
};
constructor(private inAppBrowser: InAppBrowser) {
this.openWithCordovaBrowser('http://url.tohomepage.com');
}
public openWithCordovaBrowser(url : string){
let target = "_self";
this.browser = this.inAppBrowser.create(url,target,this.options);
this.browser.on('loadstart').subscribe((event) => {
if(event.url.endsWith('.pdf'))
{
//Open PDF in some other way
}
});
this.browser.on('loadstop').subscribe((event) => {
});
this.browser.on('exit').subscribe((event) => {
});
}
}
My problem now is, that when an PDF-URL is called, none of the 3 events (loadstart, loadstop, loaderror) are fired. With an usual URL these events fire as expected. Is there any other way I could intercept these calls? (The beforeload event does not exist in this version as far as I can see)
Thanks for any help/hints!
EDIT:
I installed the cordova-plugin-inappbrowser directly from the github master as suggested. The 'beforeload' channel is implemented in the module as far as I can see. But the 'beforeload' event is still not firing. ('loadstart' however is working for none-PDF URLs).
declare var cordova: any;
...
constructor() {
var iabRef = cordova.InAppBrowser.open("http://someurl.com", "_blank", "beforeload=yes");
iabRef.addEventListener('beforeload', function(params, callback){
alert('Beforeload fired');
// If the URL being loaded is a PDF
if(params.url.match(".pdf")){
// Open PDFs in system browser (instead of InAppBrowser)
cordova.inAppBrowser.open(params.url, "_system");
}else{
// Invoke callback to load this URL in InAppBrowser
callback(params.url);
}
});
iabRef.addEventListener('loadstart', function(params, callback){
alert('Loadstart fired');
});
}
Upvotes: 2
Views: 10534
Reputation: 1
In order to open pdf file in android in-app browser:
openPdfFile(url) {
if (url.match('.pdf')) {
let urlLink = encodeURIComponent(url)
this.inAppBrowser.create('https://docs.google.com/viewer
url=' +urlLink);
}
}
Upvotes: -1
Reputation: 2961
You can use this way
downloadFile(url: string) {
if (this.platform.is('ios')) {
this.pdfFileOpen(url, this.file.syncedDataDirectory);
} else {
this.pdfFileOpen(url, this.file.dataDirectory);
}
}
pdfFileOpen(url, fileDir) {
const pdfFileName = url.split('/')[4]
this.file.createDir(fileDir, 'FolderName', true)
.then(resp => {
const fileTransfer: FileTransferObject = this.transfer.create();
fileTransfer.download(url, resp.toURL() + pdfFileName)
.then(entry => {
this.fileOpener.showOpenWithDialog(resp.toURL() + pdfFileName, 'application/pdf');
});
});
}
Upvotes: 0
Reputation: 55
So finally with some workarounds I made it work:
declare var cordova: any;
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
private iabRef;
constructor(private inAppBrowser: InAppBrowser, private platform: Platform, private spinnerDialog: SpinnerDialog, private file: File, private fileTransfer: FileTransfer, private fileOpener: FileOpener) {
this.platform.ready().then(() => {
if (this.platform.is('android')) {
this.androidBrowser();
} else {
this.iosBrowser();
}
});
}
iosBrowser() {
let browser = this.inAppBrowser.create("http://someurl.com", "_blank", "location=no,navigationbuttoncolor=#ffffff);
}
androidBrowser() {
let that = this;
this.iabRef = cordova.InAppBrowser.open("http://someurl.com", "_blank", "beforeload=yes,location=no");
this.iabRef.addEventListener('beforeload', function(params, callback){
// If the URL being loaded is a PDF
if(params.url.match(".pdf")){
that.openPDF(params.url);
} else {
callback(params.url);
}
}, false);
this.iabRef.addEventListener('loadstart', function(params, callback){
that.spinnerDialog.show(null, null, true);
});
this.iabRef.addEventListener('loadstop', function(params, callback){
that.spinnerDialog.hide();
});
this.iabRef.addEventListener('exit', function(params, callback){
that.platform.exitApp();
});
}
openPDF(url: string) {
let title = url.substring(
url.lastIndexOf("/") + 1,
url.lastIndexOf(".pdf")
);
let path = this.file.dataDirectory;
const transfer = this.fileTransfer.create();
transfer.download(url, path + title + '.pdf').then(entry => {
let url = entry.toURL();
this.fileOpener.open(url, 'application/pdf');
});
}
}
After installing the Cordova plugin directly from the GitHub repository the ‘beforeload’ event is firing (although sometimes only after a second click on the pdf link, but I will have to live with that now).
At first I tried to open the PDF-URL with another cordova.InAppBrowser.open("http://someurl.com/pdffile.pdf", "_system");
That worked, but, as soon as I returned to my original inAppBrowser, the website was stuck. The buttons and links showed feedback that they were clicked, but the browser did not react anymore. Since I could not solve that issue, I am now downloading the pdf file and opening it with the FileOpener Plugin. When I now return to the app from the pdf, the browser is still working as before.
For iOS I could not get it running with the direct Cordova plugin as with android. So if the device is running iOS, I open it with the ionic native inAppBrowser plugin. The iOS Webview works just fine with pdfs, although there are no possibilities to download the displayed pdf, for which I couldn’t find a solution yet.
Upvotes: 2
Reputation: 30366
If you install cordova-plugin-inappbrowser
directly from the Github master branch, there's an unreleased feature added by PR #276 which adds a beforeload
event.
First install the plugin direct from master:
cordova plugin add https://github.com/apache/cordova-plugin-inappbrowser
Then use it something like this:
// Open InAppBrowser on initial page
var iabRef = cordova.InAppBrowser.open("http://www.someurl.com", "_blank", "beforeload=yes");
// Add beforeload event handler which is called before each new URL is loaded into the InAppBrowser Webview
iabRef.addEventListener('beforeload', function(params, callback){
// If the URL being loaded is a PDF
if(params.url.match(".pdf")){
// Open PDFs in system browser (instead of InAppBrowser)
cordova.InAppBrowser.open(params.url, "_system");
}else{
// Invoke callback to load this URL in InAppBrowser
callback(params.url);
}
});
Upvotes: 3