Xamarin.Forms 正在文件系统中保存文件

Xamarin.Forms Saving file in filesystem

我尝试从网上下载文件并保存到任何 Environment.SpecialFolder 位置。无论我尝试哪种方法 - 我总是得到

System.UnauthorizedAccessException: 'Access to the path 'any possible path I try (even beyond Environment.SpecialFolder)' is denied.'

我尝试在 UWP 和 Android 上访问文件系统 - 都是相同的异常。

到目前为止,我尝试过但没有成功:

  • 我尝试通过 PCL 并使用 DependencyService 通过每个平台单独执行此操作。
  • 检查文件夹是否为只读
  • 以管理员权限Visual Studio开始
  • 将调试更改为发布
  • 尝试过Xam.Plugins.DownloadManager

  • 代码示例:

    var webClient = new WebClient();
    webClient.DownloadDataCompleted += (s, e) => {
       var bytes = e.Result;
       string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
       string localFilename = "downloaded.jpg";
       string localPath = Path.Combine(documentsPath, localFilename);
       File.WriteAllBytes(localPath, bytes);
    };
    webClient.DownloadDataAsync(new Uri(url));
    

    您遇到权限问题。

    首先,您必须在 AndroidManifest 中添加:

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

    并且由于 Android Marshmallow,您需要向用户询问权限,所以我建议使用包 Permissions.Plugin

    并在您的 MainActivity 中添加:

    public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
    {
        PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    }
    

    如果您有以下权限,您可以在运行时检查:

    var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Storage);
        if (status != PermissionStatus.Granted)
        {
            if(await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Storage))
            {
                await DisplayAlert("Need storage, "Request storage permission", "OK");
            }
    
            var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Storage);
            //Best practice to always check that the key exists
            if(results.ContainsKey(Permission.Storage))
                status = results[Permission.Storage];
        }
    

    有关详细信息,您可以查看此博客 post 解释 Android - https://devblogs.microsoft.com/xamarin/requesting-runtime-permissions-in-android-marshmallow/

    中的所有权限

    除了Bruno Caceiro's已接受的答案外,您要声明的UWP权限如下:DocumentsLibrary文档,MusicLibrary音乐文件夹等。

    您可以通过右键单击项目 -> 属性然后单击 Package Manifest 并转到功能选项卡,如屏幕截图所示,或者右键单击 package.appxmanifest 并选择查看代码以以图形方式访问这些内容编辑 xml。请参阅代码摘录以了解如何声明功能。有些不会在对话框中显示。

    <Capabilities>
        <Capability Name="internetClient" />
        <uap:Capability Name="documentsLibrary"/>
        <uap:Capability Name="picturesLibrary" />
    </Capabilities>
    

    编辑 此外,您还可以通过使用 rescap(受限功能)命名空间添加 <rescap:Capability Name="broadFileSystemAccess" /> 来访问某些受限文件夹,以获得对任何file/folder 用户有权访问。

    我在 Android 上遇到了同样的问题,我意识到这个问题是因为

    1. 我不得不请求运行时的许可,请记住你需要 ACCESS_COARSE_LOCATIONWRITE_EXTERNAL_STORAGE权限

    2. 我使用了错误的路径,我的主要问题是实用地获取我无法解决的路径,我通过手动输入路径解决了它。我相信如果您使用正确的完整路径(等 storage/emulated/0/),您将不会遇到任何问题。