如何在安装文件夹之外的xamarin pcl uwp中显示pdf文件? [英] How can I show an pdf file in xamarin pcl uwp that is outside my instal folder?

查看:189
本文介绍了如何在安装文件夹之外的xamarin pcl uwp中显示pdf文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿,我正在使用 Android UWP 平台的 Xamarin PCL 项目中工作.作为一项功能,用户应该能够打开pdf文件.

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.

为此,我使用的是 Mozilla pdf.js .我已通过此链接在 Android和UWP 上完成此链接. https://developer.xamarin.com/recipes/cross-platform/xamarin-forms/controls/display-pdf/ 仅对于UWP,我无法使其正常工作.

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.

这是我的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));
        }
    }
}
}

这是我的PdfView类.

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; } }
}

uwp上的文件位置= "ms-appx-web://C%3A%5CUsers%5CUser%5CAppData%5CLocal%5CPackages%5CPDFTEST.UWP_v4j5n0js0cwst%5CLocalState%5CPDFTest.pdf"

The file location on uwp = "ms-appx-web://C%3A%5CUsers%5CUser%5CAppData%5CLocal%5CPackages%5CPDFTEST.UWP_v4j5n0js0cwst%5CLocalState%5CPDFTest.pdf"

这是正确的.

但是错误是:

消息:检索PDF时出现意外的服务器响应(0) "ms-appx-web://C:/Users/User/AppData/Local/Packages/PDFTest.UWP_v4j5n0js0cwst/LocalState/PDFTest.pdf/".

Message: Unexpected server response (0) while retrieving PDF "ms-appx-web://C:/Users/User/AppData/Local/Packages/PDFTest.UWP_v4j5n0js0cwst/LocalState/PDFTest.pdf/".

更新

我已将渲染器重新创建为:

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(内部版本:9e9df56)

PDF.js v1.1.366 (build: 9e9df56)

消息:流中必须有数据

更新(我不知道您是否应该在此问题中添加此内容,或者是否应该再添加一个).

UPDATE (I don't know if u should add this in this question or if I should made another one).

我的错误仍然是

流必须有数据

stream must have data

我现在知道为什么.因为我正在开发UWP应用程序,所以我想访问instal文件夹之外的文件.这个位置是

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 \

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.

更新 我的项目中有pdf.js的2个版本. (1.1.366和1.9.426) 这是我的代码

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));
        }
    }

当我尝试使用Launcher.LaunchFileAsync打开文件并使用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)流中必须有数据.

(v1.1.366) Stream must have data.

(v1.9.426)检索PDF"ms-appdata:///local/PDFTest.pdf"时出现意外的服务器响应(0).

(v1.9.426) Unexpected server response (0) while retrieving PDF "ms-appdata:///local/PDFTest.pdf".

我知道pdf uri正确且可访问,但仍然无法正常工作. (对于v1.9.426,我已经在viewer.js中添加了

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'];)

var HOSTED_VIEWER_ORIGINS = ['null', 'http://mozilla.github.io', 'https://mozilla.github.io', 'ms-appdata://', 'ms-appx-web://PDFTest.uwp'];)

链接到测试项目

推荐答案

我现在知道为什么.因为我正在开发UWP应用程序,所以我想访问instal文件夹之外的文件.这个位置是

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

您已使用 ms-appx-web: uri scheme作为您的pdf文件访问路径.实际上,您的pdf路径是C:\Users\User\AppData\Local\Packages\PDFTest.UWP_v4j5n0js0cwst\LocalState\,它存储在应用程序的本地文件夹中.因此将无法访问该文件.

You have use ms-appx-web: uri scheme as your pdf file access path. Actually, your pdf path is C:\Users\User\AppData\Local\Packages\PDFTest.UWP_v4j5n0js0cwst\LocalState\ that stored in the app's local folder. So the file will not be accessed.

我还使用"ms-appdata:///local/" uri方案进行了测试,以访问基于您的项目的pdf文件.不幸的是,它不能被viewer.js识别.

I have also tested with "ms-appdata:///local/" uri scheme to access the pdf file base on your project. Unfortunately, It can't be recognised by viewer.js.

然后,我尝试将pdf文件转换为Base64String,然后通过在viewer.js中调用openPdfAsBase64 JS函数来打开它.

And then, I tried to convert pdf file into Base64String then opening it by calling the openPdfAsBase64 JS function in the viewer.js.

private async Task<string> OpenAndConvert(string FileName) 
{
    var folder = ApplicationData.Current.LocalFolder;
    var file = await folder.GetFileAsync(FileName);
    var filebuffer = await file.OpenAsync(FileAccessMode.Read);
    var reader = new DataReader(filebuffer.GetInputStreamAt(0));
    var bytes = new byte[filebuffer.Size];
    await reader.LoadAsync((uint)filebuffer.Size);
    reader.ReadBytes(bytes);
    return Convert.ToBase64String(bytes);  
}

用法

protected  override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
    base.OnElementChanged(e);
    if (e.NewElement != null)
    {   
        Control.Source = new Uri("ms-appx-web:///Assets/pdfjs3/web/viewer.html");
        Control.LoadCompleted += Control_LoadCompleted;
    }
}

private async void Control_LoadCompleted(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs e)
{
    CustomWebView pdfView = Element as CustomWebView;
    if (string.IsNullOrEmpty(pdfView?.Filename)) return;

    var ret = await OpenAndConvert(pdfView?.Filename);       

    var obj = await Control.InvokeScriptAsync("openPdfAsBase64", new[] { ret });
}

您可以使用此

You could use this viewer.js that was added openPdfAsBase64 method.

以下提示: 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆