question

SreejithSree-2948 avatar image
0 Votes"
SreejithSree-2948 asked SreejithSree-2948 commented

Xamarin Forms: Issue with showing a PDF files using Webview

I am using a custom renderer for showing a pdf file on my app.

Below are my renderer codes:

Main Project:

 public class PdfWebView : WebView
 {
     public static readonly BindableProperty UriProperty = BindableProperty.Create(propertyName: "Uri",
     returnType: typeof(string),
     declaringType: typeof(PdfWebView),
     defaultValue: default(string));
     public string Uri
     {
         get { return (string)GetValue(UriProperty); }
         set { SetValue(UriProperty, value); }
     }
 }

Android:

 [assembly: ExportRenderer(typeof(PdfWebView), typeof(MyWebViewRenderer))]
 namespace Projectname.Droid.Renderer
 {
     public class MyWebViewRenderer : WebViewRenderer
     {
         public MyWebViewRenderer(Context context) : base(context)
         {
         }

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

             if (Control != null)
             {
                 var customWebView = Element as PdfWebView;
                 Control.Settings.AllowUniversalAccessFromFileURLs = true;

                 Control.Settings.JavaScriptEnabled = true;
                 Control.LoadUrl(string.Format("https://drive.google.com/viewerng/viewer?url={0}", customWebView.Uri.ToString()));
             }
         }
     }
 }

Xaml and Xaml.cs:

 <local:PdfWebView 
     HorizontalOptions="FillAndExpand"
     VerticalOptions="FillAndExpand"
     x:Name="pdf_Webview"/>
        
 pdf_Webview.Source = pdfurl;
 pdf_Webview.Uri = pdfurl;

But when I run the app on the android platform getting the below exception:

System.NullReferenceException: 'Object reference not set to an instance of an object.'

No Renderers are using on the ios part and pdf is working fine on there. What is the actual issue on the android part?

dotnet-xamarin
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

JarvanZhang-MSFT avatar image
1 Vote"
JarvanZhang-MSFT answered SreejithSree-2948 commented

Hello,​

Welcome to our Microsoft Q&A platform!

System.NullReferenceException: 'Object reference not set to an instance of an object.'

Which line caused the exception? Does the error occur at 'customWebView.Uri.ToString()'? Please add a breakpoint to check if the 'customWebView.Uri' is null, you cuold add the if condition check the value. If you want to specify value to the 'Uri' of the custom webView, please call the LoadUrl in the OnElementPropertyChanged method.

[assembly: ExportRenderer(typeof(PdfWebView), typeof(MyWebViewRenderer))]
namespace TestApplication_5.Droid
{
    public class MyWebViewRenderer : WebViewRenderer
    {
        PdfWebView customWebView;
        public MyWebViewRenderer(Context context) : base(context)
        {
        }
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
        {
            base.OnElementChanged(e);

            if (Control != null)
            {
                customWebView = Element as PdfWebView;
                Control.Settings.AllowUniversalAccessFromFileURLs = true;

                Control.Settings.JavaScriptEnabled = true;
                if (customWebView.Uri != null)
                {
                    Control.LoadUrl(string.Format("https://drive.google.com/viewerng/viewer?url={0}", customWebView.Uri.ToString()));
                }
            }
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
            if (customWebView.Uri != null)
            {
                Control.LoadUrl(string.Format("https://drive.google.com/viewerng/viewer?url={0}", customWebView.Uri.ToString()));
            }
        }
    }
}

Best Regards,

Jarvan Zhang



If the response is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


· 7
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Your solution is working, but the pdf is continuously loading. Could you please check this video?


0 Votes 0 ·

It seems the LoadUrl method is called continuously. Try to change the OnElementPropertyChanged like below.

protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    base.OnElementPropertyChanged(sender, e);
    if (customWebView.Uri != null && !Control.Url.Contains(customWebView.Uri))
    {
        Control.LoadUrl(string.Format("https://drive.google.com/viewerng/viewer?url={0}", customWebView.Uri.ToString()));
    }
}


0 Votes 0 ·

The continuously loading issue is resolved now. But some of the pdf are taking too much time to load it on the webview, do you know why?

0 Votes 0 ·
Show more comments
nnovalbos-6961 avatar image
0 Votes"
nnovalbos-6961 answered SreejithSree-2948 commented

I don't know if it is possible to do that with a webview and pass the url directly.

When I used a webview for that, I had to make use of the pdfjs library.


 Control.LoadUrl(string.Format("file:///android_asset/pdfjs/web/viewer.html?file={0}", customWebView.Uri))


I had many problems when viewing pdf's in android through a webview. At the end, I chose to change the way I do it.

If you want to take a look at it, here is the example project where I implemented it

https://github.com/nnovalbos/PdfViewer

Greetings.

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thanks, I will check this and update you.

0 Votes 0 ·