使用 Xamarin Forms 打开 PDF



我有一个pdf作为AndroidAsset添加的pdf,以及使用xamarin表单为我的Android和IOS项目的BundleResource。

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

从本质上讲,我只是希望能够做这样的事情:

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

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

有什么想法吗?

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

所以在你的共享代码中添加一个名为"IDocumentView.cs"的接口:

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

人造人

现在在您的 android 项目中创建相应的实现"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以便能够快速访问应用程序的上下文。

在您的安卓清单中,添加

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

<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等(。

苹果

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

[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"); 

以显示有问题的文件。

相关内容

  • 没有找到相关文章

最新更新