Xamarin.Forms сохранить файл (pdf) в локальном хранилище и открыть с помощью программы просмотра по умолчанию - PullRequest
0 голосов
/ 25 февраля 2020

Отредактировано для уточнения вопроса

В Android мне нужно загрузить файл pdf в папку «Документы» и открыть его с помощью программы по умолчанию. Я скачал документ и сохранил его в массиве байтов. Затем я вызываю этот метод:

    /// <summary>
    /// Save data bytes on "My documents" folder and open
    /// </summary>
    /// <param name="fileName">Filename, for example: "Test.pdf"</param>
    /// <param name="data">Array of bytes to save</param>
    /// <returns>True if success or false if error</returns>
    public bool SaveAndOpen(string fileName, byte[] data)
    {
        try
        {
            // Get my documents path
            string filePath = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, Android.OS.Environment.DirectoryDownloads);
            // Combine with filename
            string fullName = Path.Combine(filePath, fileName);

            // If the file exist on device delete it
            if (File.Exists(fullName))
            {
                // Note: In the second run of this method, the file exists
                File.Delete(fullName);
            }

            // Write bytes on "My documents"
            File.WriteAllBytes(fullName, data);

            // Launch file as process
            Process.Start(fullName);

            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine("ERROR: " + ex.Message + ex.StackTrace);
            return false;
        }
    }

Проблема заключается в том, чтобы открыть документ PDF с помощью программы чтения PDF по умолчанию.

Строка "Process.Start (fullName);" выдает исключение

System.ComponentModel.Win32Exception (0x80004005): доступ запрещен

Спасибо за ваше время!

1 Ответ

0 голосов
/ 25 февраля 2020

Я нашел способ сохранить и открыть файл:

    /// <summary>
    /// Save data bytes on "My documents" folder and open
    /// </summary>
    /// <param name="fileName">Filename, for example: "Test.pdf"</param>
    /// <param name="data">Array of bytes to save</param>
    /// <returns>True if success or false if error</returns>
    public bool SaveAndOpen(string fileName, byte[] data)
    {
        try
        {
            // Get my downloads path
            string filePath = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, Android.OS.Environment.DirectoryDownloads);

            // Combine with filename
            string fullName = Path.Combine(filePath, fileName);

            // If the file exist on device delete it
            if (File.Exists(fullName))
            {
                // Note: In the second run of this method, the file exists
                File.Delete(fullName);
            }

            // Write bytes on "My documents"
            File.WriteAllBytes(fullName, data);

            // Get the uri for the saved file
            Android.Net.Uri file = Android.Support.V4.Content.FileProvider.GetUriForFile(
                this,
                this.PackageName + ".fileprovider",
                new Java.IO.File(fileName));
            Intent intent = new Intent(Intent.ActionView);
            intent.SetDataAndType(file, "application/pdf");
            intent.SetFlags(ActivityFlags.ClearWhenTaskReset | ActivityFlags.NewTask | ActivityFlags.GrantReadUriPermission | ActivityFlags.NewTask);
            this.ApplicationContext.StartActivity(intent);

            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine("ERROR: " + ex.Message + ex.StackTrace);
            return false;
        }
    }

Необходимо запрашивать разрешения во время выполнения. Я использовал Plugin.Permisions, доступные в Nuget:

    Plugin.Permissions.PermissionsImplementation.Current.RequestPermissionsAsync(
         new Plugin.Permissions.Abstractions.Permission[]
         {
             Plugin.Permissions.Abstractions.Permission.Storage,
             Plugin.Permissions.Abstractions.Permission.MediaLibrary
         });

Также добавьте провайдера в AndroidManifest. xml Файл:

<application android:label="My app" android:icon="@mipmap/icon">
    <provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true">
        <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data>
    </provider>
</application>

В том же AndroidManifest добавьте разрешения для:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />

И добавьте внешний путь в Resources / xml / file_paths. xml

<external-path name="external_files" path="."/>

Не знаю, не нужны ли мне разрешения, но этот способ работает.

...