baskren/Forms9Patch

ToPdfAsync on Android returns blank pdf for Android Q [API 29]

Closed this issue · 9 comments

Description

Steps to Reproduce

  1. Add reference to latest or any other version of the Forms9Patch nuget package to a Xamarin Forms app [Shared and the platform specific projects] OR create a new Xamarin project and add reference to the latest or any other version of the Forms9Patch nuget package
  2. Implement a Webview and handle to create PDF on button click or any other event.
  3. Load WebView with an HTML string or download from an Uri
  4. Ensure the target framework for Android project is Android Q [API 29]
  5. Run the app and click the button to generate the pdf.

Expected Behavior

Return a pdf file with content inside

Actual Behavior

The pdf file has no content [NOTE: The file does get created]

Basic Information

  • Android project target with Android Pie [API 28] is working just fine, no issues what so ever.
  • With Google asking new apps and/or app updates to target API 29 to accept on PlayStore, we are required to update to target 29 and that leads to this odd behavior.

Thank you for an awesome library @baskren. We cannot see why the same code will not work for API 29. Did you see a similar issue with your apps and/or from other community members?

I will love to collaborate and try to mitigate this.

I spent time during the weekend to get the master branch and see what can I do to handle this, but not sure if I am doing anything right as the behavior is still the same.

Please share if you have any thoughts around this.

I'm also facing the same error for API 29, emulator and real device

I'm also facing the same error for API 29, emulator and real device!

In my case, I'm not 100% sure, but it seems that the problem was with the sharing routine and not with the pdf creation itself.

  if (Forms9Patch.ToPdfService.IsAvailable)
            {
                if (await myWebView.ToPdfAsync("Celmi", Forms9Patch.PageSize.IsoA4) is ToFileResult pdfResult)
                {
                    if (pdfResult.IsError)
                        using (Toast.Create("PDF Failure", pdfResult.Result))
                        {
                        }
                    else
                    {
                        var collection = new Forms9Patch.MimeItemCollection();
                        collection.AddBytesFromFile("application/pdf", pdfResult.Result);
                        Forms9Patch.Sharing.Share(collection, RelatorioView.instance.PrintButton);
                    }
                }
            }

To make it work, I added this to my manifest :
android:requestLegacyExternalStorage="true" (I'm not sure this is really necessary)

And changed my code to:

      if (await myWebView.ToPdfAsync("Celmi", Forms9Patch.PageSize.IsoA4) is ToFileResult pdfResult)
           {
               if (pdfResult.IsError)
                   using (Toast.Create("PDF Failure", pdfResult.Result))
                   {
                   }
               else
               {
                   await Share.RequestAsync(new ShareFileRequest
                   {
                       File = new ShareFile(pdfResult.Result),
                       PresentationSourceBounds = new Rectangle(0, 0, 1, 1) // Fixes iPad share option
                   });
               }
           }

Now it works!

I had several problems, both using "HTML to a PDF" and "HTML to PNG".

I came to the conclusion that PDF / PNG is being generated BEFORE HTML finishes rendering. I had several problems, tested it in different ways, and sometimes it worked, sometimes not. On iOS, it even got stuck on Spinning when generating the PDF.

To definitely resolve the problem, I displayed the HTML in a WebView first, and then on that screen, I added a button to export to PNG or PDF. Since WebView already displayed HTML before generating PDF / PNG, it now worked 100% of the time on both iOS and Android.

This is a bit more difficult problem than I have ever hoped. In the UNO version of this functionality, I have most of these issues resolved but there is a little more work left. Once I complete some related work in UNO, I'll be able to update the Xamarin implementation.

We have moved to an alternative approach instead of generating a pdf. I will mark it close for now and try with a new package version when it is available. Thank you.

Hello @mistryhardik ,

Any chance to get infos about this alternative approach ?

Thanks

Has this issue been fixed in the develop branch? It's still in the 2.4.9 release

Using wagenheimer's advice, I've opted for a custom event for when the source of both the iOS and Android WebView renderer is fully loaded before any button to create a PDF is enabled.

I did this using this answer here https://stackoverflow.com/a/67528473/812013 for iOS. And I built on this approach in Android using this code here https://github.com/seansparkman/CookiesWebView/blob/master/Cookies.Android/CookieWebViewRenderer.cs#L45.