xamarin Forms将文件(pdf)保存在本地存储中,并使用默认查看器打开

s8vozzvw  于 2023-03-27  发布在  其他
关注(0)|答案(2)|浏览(198)

编辑以细化问题

在Android中,我需要下载一个pdf文件到“Documents”文件夹,并使用默认程序打开它。我下载了文档并将其存储在Byte数组中。然后我调用这个方法:

/// <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);“引发异常
系统异常(0x 80004005):拒绝访问
谢谢你的时间!

cigdeys3

cigdeys31#

我找到了保存和打开文件的方法:

/// <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。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="."/>

不知道如果我没有需要的权限,但与这种方式的作品。

xxe27gdn

xxe27gdn2#

我将扩展@duefectu答案与类阅读文件更多的扩展其中MainActivity.MainActivityInstance存储MainActivityContext

public void Open(string path)
{
    try
    {
        var url = new Java.IO.File(path);
        var uri = FileProvider.GetUriForFile(MainActivity.MainActivityInstance,
            MainActivity.MainActivityInstance.PackageName + ".fileprovider", url);

        var intent = new Intent(Intent.ActionView);
        if (url.ToString().Contains(".doc") || url.ToString().Contains(".docx"))
        {
            // Word document
            intent.SetDataAndType(uri, "application/msword");
        }
        else if (url.ToString().Contains(".pdf"))
        {
            // PDF file
            intent.SetDataAndType(uri, "application/pdf");
        }
        else if (url.ToString().Contains(".ppt") || url.ToString().Contains(".pptx"))
        {
            // Powerpoint file
            intent.SetDataAndType(uri, "application/vnd.ms-powerpoint");
        }
        else if (url.ToString().Contains(".xls") || url.ToString().Contains(".xlsx"))
        {
            // Excel file
            intent.SetDataAndType(uri, "application/vnd.ms-excel");
        }
        else if (url.ToString().Contains(".zip"))
        {
            // ZIP file
            intent.SetDataAndType(uri, "application/zip");
        }
        else if (url.ToString().Contains(".rar"))
        {
            // RAR file
            intent.SetDataAndType(uri, "application/x-rar-compressed");
        }
        else if (url.ToString().Contains(".rtf"))
        {
            // RTF file
            intent.SetDataAndType(uri, "application/rtf");
        }
        else if (url.ToString().Contains(".wav") || url.ToString().Contains(".mp3"))
        {
            // WAV audio file
            intent.SetDataAndType(uri, "audio/x-wav");
        }
        else if (url.ToString().Contains(".gif"))
        {
            // GIF file
            intent.SetDataAndType(uri, "image/gif");
        }
        else if (url.ToString().Contains(".jpg") || url.ToString().Contains(".jpeg") ||
                 url.ToString().Contains(".png"))
        {
            // JPG file
            intent.SetDataAndType(uri, "image/jpeg");
        }
        else if (url.ToString().Contains(".txt"))
        {
            // Text file
            intent.SetDataAndType(uri, "text/plain");
        }
        else if (url.ToString().Contains(".3gp") || url.ToString().Contains(".mpg") ||
                 url.ToString().Contains(".mpeg") || url.ToString().Contains(".mpe") ||
                 url.ToString().Contains(".mp4") || url.ToString().Contains(".avi"))
        {
            // Video files
            intent.SetDataAndType(uri, "video/*");
        }
        else
        {
            intent.SetDataAndType(uri, "*/*");
        }
        intent.SetFlags(ActivityFlags.ClearWhenTaskReset | ActivityFlags.NewTask | ActivityFlags.GrantReadUriPermission | ActivityFlags.NewTask);
        MainActivity.MainActivityInstance.StartActivity(intent);
    }
    catch (Exception exception)
    {
        
    }
}

相关问题