Открытие PDF с помощью форм Xamarin - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть PDF, который я добавил в качестве AndroidAsset и BundleResource для моих проектов Android и IOS с использованием форм xamarin.

Я просто хочу иметь возможность открывать эти файлы с любого устройства, используя любой файл PDFПросмотрщик устройства по умолчанию.

По сути, я просто хочу иметь возможность сделать что-то вроде:

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

, но это не похоже на работу.Ничего не происходит, и пользователю никогда не предлагается открыть PDF-файл.Я не хочу использовать какие-либо сторонние библиотеки, которые позволяют открывать PDF в приложении, я просто хочу, чтобы он перенаправлял пользователя в просмотрщик PDF или браузер.

Есть идеи?

1 Ответ

0 голосов
/ 12 сентября 2018

Прежде всего вам понадобится интерфейсный класс, так как вам нужно вызвать службу зависимостей, чтобы передать документ в собственную реализацию (ы) вашего приложения:

, поэтому в вашем общем коде добавьте интерфейс, который называется «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 для быстрого доступа к контексту приложения.

В манифесте Android добавьте

В ресурсах вашего приложения добавьте ресурс xml (в папку "xml") с именем file_paths.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» в вашем проекте iOS):

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

для отображения рассматриваемого файла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...