Open a PDF inside a WebView in Xamarin Forms (Android)

I am developing an App that should visualize a PDF document hosted online. I searched in the web but I have found nothing useful. Also this Xamarin documentation has not been useful for me. But on StackOverflow I have found two posts that have put me on the right way.

The first is this.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DisplayPDF.WebViewPage"
             Padding="0,20,0,0">
    <ContentPage.Content>
        <WebView Source="http://www.yoursite.com/your.pdf" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
    </ContentPage.Content>
</ContentPage>

Gerald’s solution is very simple, but it does not work for me. I have a blank view… nothing else. I have tried also the second Gerald’s solution (for “Local” files) but I am not be able to use pdf.js.

After other researches, I have found this post. Adam suggests to use a WebView and a Google service

"http://drive.google.com/viewerng/viewer?embedded=true&url=";

No luck. I have always a blank WebView on my device.

After a beer I thought to use

Device.OpenUri()

and visualize the PDF in an external browser but I don’t like this solution. So, I tried the last chance. Try to put together some code…

Create a CustomRenderer

PCL SIDE

using System;
using Xamarin.Forms;

namespace OpenPdf
{
    public class CustomWebView : WebView
    {
        public static readonly BindableProperty UriProperty = BindableProperty.Create(propertyName: "Uri",
                returnType: typeof(string),
                declaringType: typeof(CustomWebView),
                defaultValue: default(string));

        public string Uri
        {
            get { return (string)GetValue(UriProperty); }
            set { SetValue(UriProperty, value); }
        }

        public static readonly BindableProperty IsPdfProperty = BindableProperty.Create(propertyName: "IsPdf",
        returnType: typeof(bool),
        declaringType: typeof(CustomWebView),
        defaultValue: default(bool));

        public bool IsPdf
        {
            get { return (bool)GetValue(IsPdfProperty); }
            set { SetValue(IsPdfProperty, value); }
        }
    }
}

 

Only two properties. One is the PDF url. The second is a flag that identify if the url is relative to a PDF or something else.

ANDROID SIDE

using System;
using Android.Content;
using OpenPdf;
using OpenPdf.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(CustomWebView), typeof(CustomWebViewRenderer))]
namespace OpenPdf.Droid
{
    public class CustomWebViewRenderer : WebViewRenderer
    {

        public CustomWebViewRenderer(Context context) : base(context)
        {

        }

        protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement != null)
            {
                var customWebView = Element as CustomWebView;
                Control.Settings.AllowUniversalAccessFromFileURLs = true;
                if (!customWebView.IsPdf)
                    Control.LoadUrl(customWebView.Uri);
                else
                    Control.LoadUrl("https://drive.google.com/viewerng/viewer?embedded=true&url=" + customWebView.Uri);
            }
        }
    }
}

 

The Custom Renderer implementation in Android project.

First, take a look to the new Constructor with Context argument

Second, the OnElementChanged do two things:

  1. Set “AllowUniversalAccessFromFileURLs =true”: Sets whether JavaScript running in the context of a file scheme URL should be allowed to access content from any origin.
  2. Open the url:
    1. normally if the url is not a “PDF document”
    2. with the help of “https://drive.google.com/viewerng/viewer&#8221; if it is a “PDF document”

You can find a demo on GitHub

After some tests, thanks Gerald, there are some problems with Devices with Android < 7.0….. if someone can test and find a solution….

Sorry for my terrible English (I have written this in a few time…. without “google translator…”) and add some comments.

 

A repo for pdf.js solution

Gerald writes this post and this repo to use pdf.js to visualize PDF in Xamarin Forms

Un pensiero su “Open a PDF inside a WebView in Xamarin Forms (Android)

  1. Pingback: android – Forms, Open PDF from URL – in Android | Mister bricole !

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...