Hy, I'm working in a Xamarin PCL project with the platforms Android and UWP. As a feature the user should be able to open an pdf file.
For this I'm using Mozilla pdf.js. I have followed this link to get it done on Android and UWP. https://developer.xamarin.com/recipes/cross-platform/xamarin-forms/controls/display-pdf/ Only for UWP I can't get it to function.
Here is my custom renderer for UWP
[assembly: ExportRenderer(typeof(PdfView),
typeof(PDF.UWP.Renderers.PdfViewRenderer))]
namespace PDF.UWP.Renderers
{
/// <summary>
/// The asset folder of the UWP app must contain the pdfjs folder and files.
/// </summary>
public class PdfViewRenderer: WebViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
PdfView pdfView = Element as PdfView;
string sFile = string.Format("ms-appx-web://{0}", WebUtility.UrlEncode(pdfView.Uri));
Control.Source = new Uri(string.Format("ms-appx-web:///Assets/pdfjs/web/viewer.html?file={0}", sFile));
}
}
}
}
Here is my PdfView class.
public class PdfView: WebView
{
public static readonly BindableProperty DocumentInfoProperty =
BindableProperty.Create(propertyName: nameof(TheDocumentInfo), returnType: typeof(DocumentInfo),
declaringType: typeof(PdfView), defaultValue: default(DocumentInfo));
public DocumentInfo TheDocumentInfo
{
get { return (DocumentInfo)GetValue(DocumentInfoProperty); }
set { SetValue(DocumentInfoProperty, value); }
}
public string Uri { get { return TheDocumentInfo.LocalUrl; } }
public string FileName { get { return TheDocumentInfo.FileName; } }
}
The file location on uwp = "ms-appx-web://C%3A%5CUsers%5CUser%5CAppData%5CLocal%5CPackages%5CPDFTEST.UWP_v4j5n0js0cwst%5CLocalState%5CPDFTest.pdf"
And this is correct.
But the error is:
Message: Unexpected server response (0) while retrieving PDF "ms-appx-web://C:/Users/User/AppData/Local/Packages/PDFTest.UWP_v4j5n0js0cwst/LocalState/PDFTest.pdf/".
UPDATE
I have recreated the renderer to:
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
// TODO: testen
PdfView pdfView = Element as PdfView;
string sFile = string.Format("ms-appx-web://{0}/{1}", pdfView.Uri.Replace(pdfView.FileName, ""), WebUtility.UrlEncode(pdfView.FileName));
Control.Source = new Uri(string.Format("ms-appx-web:///Assets/pdfjs/web/viewer.html?file={0}", sFile));
}
}
I don't know if this is the solution to my problem but this error is gone. The error now is:
PDF.js v1.1.366 (build: 9e9df56)
Message: stream must have data
UPDATE (I don't know if u should add this in this question or if I should made another one).
My error is still
stream must have data
I know now why. Because I'm developing a UWP application and I want to access a file outside my instal folder. This location is
C:\Users\User\AppData\Local\Packages\PDFTest.UWP_v4j5n0js0cwst\LocalState\
Apperently I can't access files outside my instalation folder. This includes coping the file to my install folder and read it there.
UPDATE I have 2 versions of pdf.js in my project. (1.1.366 and 1.9.426) This is my code now
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
PdfView pdfView = Element as PdfView;
var uriString = "ms-appdata:///local/" + WebUtility.UrlEncode(pdfView.FileName);
Control.Source = new Uri(string.Format("ms-appx-web:///Assets/pdfjs/web/viewer.html?file={0}", uriString));
}
}
When I try to open the file with Launcher.LaunchFileAsync and use the uriString it opens my browser and shows me the file.
In my application I get the following error's
(v1.1.366) Stream must have data.
(v1.9.426) Unexpected server response (0) while retrieving PDF "ms-appdata:///local/PDFTest.pdf".
I know that the pdf uri is correct and accessible but it still doesn't work. (for v1.9.426 I have added in viewer.js
var HOSTED_VIEWER_ORIGINS = ['null', 'http://mozilla.github.io', 'https://mozilla.github.io', 'ms-appdata://', 'ms-appx-web://PDFTest.uwp'];)
link to the testproject