Unable to open PDF files in app view in Capacitor Ionic - capacitor

import { Plugins } from '#capacitor/core';
const { Browser } = Plugins;
Browser.open({ url: 'http://www.africau.edu/images/default/sample.pdf', windowName:'_self' });
When the url is specified as a link to a website, it works fine but doesnt when specified a PDF. Could someone please suggest if any changes required ? Do i need to specify the rel ? If yes how ? There is no such key to be passed in open call. Response received is 'NO enabled plugin supports this MIME type'.

The Browser plugin from Capacitor should work fine for this. Try without specifying windowName.
// Capacitor v2
import { Plugins } from '#capacitor/core';
const { Browser } = Plugins;
Browser.open({ url: 'http://www.africau.edu/images/default/sample.pdf'});
// or for Capacitor v3
import { Browser } from '#capacitor/browser';
Browser.open({ url: 'http://www.africau.edu/images/default/sample.pdf'});

InAppBrowser will not pdf files. you will have to use it in some other way,
first you can simply add a href this will open user default browser.. like for android it will open this link in android and for ios it will use safari.
open pdf
Second way is to use a plugin for document viewer .. i have added its link below
constructor(private document: DocumentViewer) { }
const options: DocumentViewerOptions = {
title: 'My PDF'
}
this.document.viewDocument('http://www.africau.edu/images/default/sample.pdf', 'application/pdf', options)
https://ionicframework.com/docs/native/document-viewer

Related

How to preview a base64 PDF with ionic capacitor

I am trying to open and preview a PDF from a capacitor application.
Here is my code :
const { Browser } = Plugins;
let base64Pdf = "";
var contentType = "application/pdf";
var dataBlob = this.b64toBlob(base64Pdf, contentType);
await Browser.open({ url: URL.createObjectURL(dataBlob) }).then(() => {
console.log("PDF OK");
}).catch(err => {
console.log(err);
})
This is working great on web, but does not work on iOS. I get an error saying that the URL is invalid. I also tried to use
window.open(URL.createObjectURL(dataBlob), '_blank');
and
window.open(URL.createObjectURL(dataBlob), '_system');
But none of these work. I do not get any error output.
When using self, the PDF is opening well, but since it opens inside the webview, there is no more control and the user is stuck :
window.open(URL.createObjectURL(dataBlob), '_system');
Thanks in advance for any help

Flutter-web:url_launcher_web not launching email in browser

I've added a feature of sending feedback through email for my flutter web app. This is my code :
static void launchEmail(String subjectLine) async {
const emailId = Constants.ARUDITO_EMAIL;
print('opening email app for uploading content');
String url = "mailto:$emailId?subject=$subjectLine";
if (kIsWeb) {
if (await webLauncher.UrlLauncherPlugin().canLaunch(url)) {
await webLauncher.UrlLauncherPlugin().launch(
url,
useWebView: true,
enableDomStorage: true,
enableJavaScript: true,
useSafariVC: true,
webOnlyWindowName: 'Arudito',
headers: null,
universalLinksOnly: false,
);
} else {
throw 'Could not open an email app';
}
} else {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not open an email app';
}
}
}
pubspec.yaml includes :
dependencies:
flutter:
sdk: flutter
url_launcher: ^5.4.2
url_launcher_web: ^0.1.3+1
This code is not launching email in a web browser. It only opens a new tab. However, it is launching on selecting mail app in Windows. Can someone please tell what is the issue here?
I had exactly the same problem. I found a useful answer in another StackOverflow post.
There it is mentioned that if you just omit the canLaunch check and instead wrap the launch in a try-catch block it works on Flutter Web. I just tried, and it works nicely.
Btw, there is also a quite new Link widget in the url_launcher package, which makes it possible to create proper web links (including right-click support).
I had the exact issue. Click on any email link will just opens a new blank tab. That's it.
Took me hours to figure out.
Open Mail app on mac, settings, general, and there's an option for default email reader. It was selecting chrome. Change it to a real email client and it works as expected now.

FILE_URI path for Camera not working on IONIC 4

When using the Cameara to take a picture with destinationType: this.camera.DestinationType.FILE_URI, the resulting URL will not work to display the image. For example, when attempting to take a photo like this:
this.camera.getPicture(options).then((url) => {
// Load Image
this.imagePath = url;
}, (err) => {
console.log(err);
});
Attempting to display it as <img [src]="imagePath" > will result in an error (file not found).
The problem here is that the URL is in the file:///storage... path instead of the correct one based on localhost.
In previous versions of Ionic, this would be solved by using normalizeURL. This will not work on Ionic 4 (or at least I could not make it work).
To solve this issue, you will need to use convertFileSrc():
import {WebView} from '#ionic-native/ionic-webview/ngx';
...
this.camera.getPicture(options).then((url) => {
// Load Image
this.imagePath = this.webview.convertFileSrc(url);
}, (err) => {
console.log(err);
});
Now the image URL will be in the appropriate http://localhost:8080/_file_/storage... format and will load correctly.
See WKWebView - Ionic Docs for more information.
In my case, the following code works with me
const downloadFileURL = 'file:///...';
// Convert a `file://` URL to a URL that is compatible with the local web server in the Web View plugin.
const displayedImg = (<any>window).Ionic.WebView.convertFileSrc(downloadFileURL);
In case some gots here looking for the answer on ionic4, check this out
"Not allowed to load local resource" for Local image from Remote page in PhoneGap Build
and look for the answer from #Alok Singh that's how I got it working on ionic4 and even works with livereload
UPDATE december 2021:
You have to install the new Ionic Webview
RUN:
ionic cordova plugin add cordova-plugin-ionic-webview
npm install #awesome-cordova-plugins/ionic-webview
Import it in app.module and your page where you wanna use it:
import { WebView } from '#awesome-cordova-plugins/ionic-webview/ngx';
image = "";
constructor(private webview: WebView){}
Then this will work:
this.camera.getPicture(options).then((imageData) => {
this.image = this.webview.convertFileSrc(imageData)
}, (err) => {
// Handle error
});
And show it in the HTML page:
<img [src]="image" alt="">

Deeplink not work with SocialSharing

I'm developing an ionic project.
I have follwed all steps to installa Social Sharing and Deeplinks.
This is my schema when I install plugin.
ionic cordova plugin add ionic-plugin-deeplinks --variable URL_SCHEME=app --variable DEEPLINK_SCHEME=https --variable DEEPLINK_HOST=app.com --variable ANDROID_PATH_PREFIX=/
But when I share with Social Sharing don't send a url, Social Sharing send as string or via email send some structure as string an other part as url.
e.g. via hangout as string
e.g. via email app://app.com/page --> app:// as string and app.com/page as url
In Social share documentation schema is share(meesage, subject, file, url)
message:string, subject:string, file:string|Array, url:string
this.socialSharing.share('Lorem ipsum', 'title', null, 'app://app.com/about')
.then( ()=> {
console.log('Success');
})
.catch( (error)=> {
console.log('Error: ', error);
});
The app open deeplinks when I tested using browser from codepen.io with hiperlink.
< h1 >< a href="app://app.com/about" >Click Me< /a>< /h1>
But when I share a deeplink send as string.
Why??? Can you help me???
I struggled with the same problem, the solution to this is very straight forward:
Do not use custom url schemes
The main reason for not using custom url schemes is that Gmail and other webmail provider indeed destroys links such as "app://...". So there is no way to get this work.
See the following links for details:
Make a link in the Android browser start up my app?
https://github.com/EddyVerbruggen/Custom-URL-scheme/issues/81
Use universal links instead
Universal links is supported by Android und iOS. Since you are already using the ionic-plugin-deeplinks plugin, you already configured a deeplink url.
All you have to do is change
href="app://app.com/about"
to
href="https://app.com/about"
For using universal links you need to create configuration files for android and iOS. These files must include application identifiers for all the apps with which the site wants to share credentials. See the following link for details:
https://medium.com/#ageitgey/everything-you-need-to-know-about-implementing-ios-and-android-mobile-deep-linking-f4348b265b49
The file has to be located on your website at exactly
https://www.example.com/.well-known/apple-app-site-association (for iOS)
https://www.example.com/.well-known/assetlinks.json (for android)
You can also use to get data from custom URL and deep link in our app if exist. Otherwise, redirect to play/app store like this:
index.html
$(document).ready(function (){
var lifestoryId = getParameterByName('lifestoryId');
if(navigator.userAgent.toLowerCase().indexOf("android") > -1){
setTimeout(function () {
window.location.href = "http://play.google.com/store/apps/details?id=com.android.xyz&hl=en";
}, 5000);
}
if(navigator.userAgent.toLowerCase().indexOf("iphone") > -1){
setTimeout(function () {
window.location.href = "https://itunes.apple.com/us/app/app/id12345678?ls=1&mt=8";
}, 5000);
}
window.location.href = "app://lifestory/info:"+lifestoryId;
});
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
Call link like: BASE_URL/index.html?lifestoryId=123

PWA mobile camera access

My requirement is to access the mobile camera in iOS and android using the mobile browser.
Using Ionic PWA app can I access mobile camera in iOS and android device browsers? Looking for PWA solution using Cordova (not native solution).
While working on a PWA. I came across the need to access a mobile device's camera/images.(a native app was out of the question). After doing some research I came across this little nugget.
<input type="file" accept="image/*" capture="camera" />
By adding the accept and capture attributes I was able to access my phone's camera and images. I should also point out that you don't need to do anything special with your Server side (Node or PHP). It acts just like a standard file upload input in a browser.
You can open video devices in the web browser...
<video id="cameraPlayer"></video>
// find the video devices (font/back cameras etc)
navigator.mediaDevices.enumerateDevices().then(function (devices) {
// https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices
devices.forEach(function (device) {
if (device.kind === 'videoinput') {
cameraDeviceIds.push(device.deviceId)
}
})
})
// attach camera output to video tag
navigator.mediaDevices.getUserMedia({
video: { deviceId: { exact: cameraDeviceIds[currentCameraIndex] } }
}).then(function (stream) {
document.getElementById("cameraPlayer").srcObject = stream
})
If you just want an image you can use an input
<input type="file" accept="image/*" id="inputPhoto" class="hidden" capture="environment" />
// trigger capture
document.getElementById('inputPhoto').click()
// event handler for change
function onInputPhotoChange() {
if (document.getElementById('inputPhoto').files.length === 0) {
return
}
var reader = new window.FileReader()
reader.onloadend = function (event) {
event.target.result
// image data
// note you may need to rotate using EXIF data on a canvas
}
// Read the file into memory as dataurl
var blob = document.getElementById('inputPhoto').files[0]
reader.readAsDataURL(blob)
}
If you want to use the camera in an Ionic PWA app, you can use Capacitor:
https://capacitor.ionicframework.com/docs/apis/camera
I implemented the camera feature and it works 100%:
In addition to the above answers, you will have to add this in your index.html file, for the camera to work on PWA
<script nomodule="" src="https://unpkg.com/#ionic/pwa-elements#1.3.0/dist/ionicpwaelements/ionicpwaelements.js"></script>
The solution given above only make selection of file resticted to i
mages category only. But we want to access camera or audio device here
of browser.
So, to rescue this challege here come api from browser("browsers are
powerfull now yeah").
getUserMedia(:true/false)
Here <media_type> is type of media you want to access like
audio,video
You can set it as {audio: true/false} and {video:true/false}.
But error "NotFoundError" will be returned if media not found.
Here is eg; :>
if('mediaDevices' in navigator && 'getUserMedia' in
navigator.mediaDevices){ const stream = await
navigator.mediaDevices.getUserMedia({video: true}) }
It will run on Android and Ios platform with PWA and on a browser
home.page.ts file
import { Component } from '#angular/core';
import { Plugins, CameraResultType, Capacitor, FilesystemDirectory,
CameraPhoto, CameraSource } from '#capacitor/core';
const { Camera, Filesystem, Storage } = Plugins;
#Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
constructor() {}
async capturedImage(){
const image = await Camera.getPhoto({
resultType: CameraResultType.DataUrl,
source: CameraSource.Camera,
quality: 90
});
console.log('image',image)
}
}
home.page.html
<ion-button expand="full" (click)="capturedImage()"> Captured Image</ion-button>
Accessing the camera via Cordova (and more specifically ionic since you tagged the ionic-framework in your question) is a matter of installing the plugin, whether you're using ionic or not. There are several camera plugins but the one recommended by ionic can be found here:
https://github.com/apache/cordova-plugin-camera
For example to add the plugin to your ionic project, simply run:
ionic Cordova plugin add cordova-plugin-camera
You would use it like this in your component's .ts file (for example):
import { Camera, CameraOptions } from '#ionic-native/camera';
constructor(private camera: Camera) { }
...
const options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE
}
this.camera.getPicture(options).then((imageData) => {
// imageData is either a base64 encoded string or a file URI
// If it's base64:
let base64Image = 'data:image/jpeg;base64,' + imageData;
}, (err) => {
// Handle error
});
The above implementation was taken from here, where more details can also be found:
https://ionicframework.com/docs/native/camera/