使用Xamarin表单打开PDF [英] Opening a PDF with Xamarin Forms

查看:105
本文介绍了使用Xamarin表单打开PDF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经为使用xamarin表单的Android和IOS项目添加了一个pdf文件作为AndroidAsset和BundleResource.

I have a pdf i've added as an AndroidAsset and a BundleResource for my Android and IOS projects using xamarin forms.

我只希望能够使用该设备默认使用的任何pdf查看器从任何设备打开这些文件.

I just want to be able to open those files from any device, using whatever pdf viewer the device defaults to.

本质上,我只想能够执行以下操作:

Essentially, i just want to be able to do something like:

Device.OpenUri("file:///android_asset/filename.pdf");

但是这似乎不起作用.没有任何反应,也永远不会提示用户打开pdf.我不想使用任何允许pdf在应用程序中打开的第三方库,我只希望它将用户重定向到pdf查看器或浏览器.

but this doesn't seem to work. Nothing happens and the user is never prompted to open the pdf. I don't want to use any 3rd party libraries that allow the pdf to open in app, i just want it to redirect the user to a pdf viewer or browser.

有什么想法吗?

推荐答案

首先,您将需要一个接口类,因为您需要调用依赖项服务才能将文档传递给您的本机实现.应用:

First of all you will need an interface class, since you need to call the dependency service in order to pass your document to the native implementation(s) of your app:

因此,在您的共享代码中添加一个名为"IDocumentView.cs"的接口:

so in your shared code add an interface, called "IDocumentView.cs":

public interface IDocumentView
{
    void DocumentView(string file, string title);
}

Android

现在在您的android项目中创建相应的实现"DocumentView.cs":

Now in your android project create the corresponding implementation "DocumentView.cs":

assembly: Dependency(typeof(DocumentView))]
namespace MyApp.Droid.Services
{
public class DocumentView: IDocumentView
{
    void IDocumentView.DocumentView(string filepath, string title)
    {
        try
        {
            File file = new File(filepath);

            String mime = FileTypes.GetMimeTypeByExtension(MimeTypeMap.GetFileExtensionFromUrl(filepath));
            File extFile = new File (Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDocuments), file.Name);
            File extDir = extFile.ParentFile;
            // Copy file to external storage to allow other apps to access ist
            if (System.IO.File.Exists(extFile.AbsolutePath))
                System.IO.File.Delete(extFile.AbsolutePath);

            System.IO.File.Copy(file.AbsolutePath, extFile.AbsolutePath);
            file.AbsolutePath, extFile.AbsolutePath);
            // if copying was successful, start Intent for opening this file
            if (System.IO.File.Exists(extFile.AbsolutePath))
            {
                Intent intent = new Intent();
                intent.SetAction(Android.Content.Intent.ActionView);
                intent.SetDataAndType(Android.Net.Uri.FromFile(extFile), mime);
                MainApplication.FormsContext.StartActivityForResult(intent, 10);
            }
        }
        catch (ActivityNotFoundException anfe)
        {
            // android could not find a suitable app for this file
            var alert = new AlertDialog.Builder(MainApplication.FormsContext);
            alert.SetTitle("Error");
            alert.SetMessage("No suitable app found to open this file");
            alert.SetCancelable(false);
            alert.SetPositiveButton("Okay", (object sender, DialogClickEventArgs e) => ((AlertDialog)sender).Hide());
            alert.Show();
        }
        catch (Exception ex)
        {
            // another exception
            var alert = new AlertDialog.Builder(MainApplication.FormsContext);
            alert.SetTitle("Error");
            alert.SetMessage("Error when opening document");
            alert.SetCancelable(false);
            alert.SetPositiveButton("Okay", (object sender, DialogClickEventArgs e) => ((AlertDialog)sender).Hide());
            alert.Show();
        }
    }
}
}

请注意,MainApplication.FormsContext是我添加到MainApplication.cs中的静态变量,以便能够快速访问应用程序的上下文.

Please note that MainApplication.FormsContext is a static variable I added to my MainApplication.cs in order to be able to access the Context of the app quickly.

在您的Android清单中,添加

In your Android manifest, add

在您的应用程序资源中,添加一个名为file_paths.xml的xml资源(到文件夹"xml"中),其内容如下:

In your application resources, add an xml resource (into folder "xml") called file_paths.xml with the following content:

<paths xmlns:android="http://schemas.android.com/apk/res/android">
   <external-files-path name="root" path="/"/>
   <external-files-path name="files" path="files" />
</paths>

此外,您还需要确保在目标设备上安装了能够处理相关文件的应用程序. (Acrobat Reader,Word,Excel等).

Also you need to ensure that there are apps installed on the target device, which are able to handle the file in question. (Acrobat Reader, Word, Excel, etc...).

iOS

iOS已经内置了一个非常不错的文档预览,因此您可以简单地使用它(再次在iOS项目中创建一个名为"DocumentView.cs"的文件):

iOS already comes with a quite nice document preview built in, so you can simply use that (again create a file named "DocumentView.cs" in your iOS Project):

[assembly: Dependency(typeof(DocumentView))]
namespace MyApp.iOS.Services
{
public class DocumentView: IDocumentView
{
    void IDocumentView.DocumentView(string file, string title)
    {
        UIApplication.SharedApplication.InvokeOnMainThread(() =>
        {
            QLPreviewController previewController = new QLPreviewController();

            if (File.Exists(file))
            {
                previewController.DataSource = new PDFPreviewControllerDataSource(NSUrl.FromFilename(file), title);
                UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(previewController, true, null);
            }
        });
    }
}

public class PDFItem : QLPreviewItem
{
    public PDFItem(string title, NSUrl uri)
    {
        this.Title = title;
        this.Url = uri;
    }
    public string Title { get; set; }
    public NSUrl Url { get; set; }
    public override NSUrl ItemUrl { get { return Url; } }
    public override string ItemTitle { get { return Title; } }
}

public class PDFPreviewControllerDataSource : QLPreviewControllerDataSource
{
    PDFItem[] sources;

    public PDFPreviewControllerDataSource(NSUrl url, string filename)
    {
        sources = new PDFItem[1];
        sources[0] = new PDFItem(filename, url);
    }

    public override IQLPreviewItem GetPreviewItem(QLPreviewController controller, nint index)
    {
        int idx = int.Parse(index.ToString());
        if (idx < sources.Length)
            return sources.ElementAt(idx);
        return null;
    }

    public override nint PreviewItemCount(QLPreviewController controller)
    {
        return (nint)sources.Length;
    }
}
}

最后您可以致电

DependencyService.Get<IDocumentView>().DocumentView(file.path, "Title of the view"); 

显示有问题的文件.

这篇关于使用Xamarin表单打开PDF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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