mo *_*laz 0 c# mobile xamarin.forms
我有一个 pdf 文件,已使用 xamarin 表单添加为 Android 和 IOS 项目的 AndroidAsset 和 BundleResource。
我只是希望能够使用设备默认的任何 pdf 查看器从任何设备打开这些文件。
本质上,我只想能够做类似的事情:
Device.OpenUri("file:///android_asset/filename.pdf");
Run Code Online (Sandbox Code Playgroud)
但这似乎不起作用。没有任何反应,也不会提示用户打开 pdf 文件。我不想使用任何允许 pdf 在应用程序中打开的第三方库,我只是希望它将用户重定向到 pdf 查看器或浏览器。
有任何想法吗?
首先,您需要一个接口类,因为您需要调用依赖项服务才能将文档传递给应用程序的本机实现:
因此,在您的共享代码中添加一个名为“IDocumentView.cs”的界面:
public interface IDocumentView
{
void DocumentView(string file, string title);
}
Run Code Online (Sandbox Code Playgroud)
安卓
现在在你的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();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,MainApplication.FormsContext 是我添加到 MainApplication.cs 中的静态变量,以便能够快速访问应用程序的上下文。
在您的 Android 清单中,添加
在您的应用程序资源中,添加名为 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>
Run Code Online (Sandbox Code Playgroud)
此外,您还需要确保目标设备上安装了能够处理相关文件的应用程序。(Acrobat Reader、Word、Excel 等)。
iOS系统
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
终于可以打电话了
DependencyService.Get<IDocumentView>().DocumentView(file.path, "Title of the view");
Run Code Online (Sandbox Code Playgroud)
显示有问题的文件。
| 归档时间: |
|
| 查看次数: |
4919 次 |
| 最近记录: |