【问题标题】:Xamarin-System.UnauthorizedAccessException: Access to the path is deniedXamarin-System.UnauthorizedAccessException:对路径的访问被拒绝
【发布时间】:2018-04-05 07:23:06
【问题描述】:

我正在尝试下载文件,但出现 System.UnauthorizedAccessException:对路径“/storage/emulated/0/Download/test.pdf”的访问被拒绝。我已经在 Android Manifest 文件中设置了所需的权限。

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

下载路径:

Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads)

如果我使用以下路径作为我的下载路径,我可以下载该文件。但我无法将 PDF 文件分享到谷歌驱动器、投递箱或任何其他 System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal)

我正在使用 Xamarin.Forms v2.4.0.282 和 Xamarin.Android.Support 包 v25.4.0.2。

注意:当使用 Xamarin.Forms 版本 2.3.5.256-pre2 和 Xamarin.Android.Support 包 v23.3.0 时,代码运行良好 请提出解决问题的想法。

提前致谢。

【问题讨论】:

  • 您使用的是什么版本的 Android,因为任何 api 23 及更高版本都需要用户授予访问文件的明确权限
  • 我正面临从 android v5.1 到 v7.0 的问题
  • 在其中一台设备上,我将进入设置>应用程序单击该应用程序并检查是否启用了存储权限并重试。如果它之后它工作,那么你只需要提示用户启用权限
  • @Nick 谢谢。如您所说,它在启用许可后工作。现在我添加了询问运行时权限的代码。
  • 以下答案可能会有所帮助stackoverflow.com/a/66515458/7149454

标签: xamarin xamarin.android


【解决方案1】:

根据您使用的 Android 版本,即使在 6.0 或更高版本的清单中添加了权限,用户也必须在应用运行时显式启用该权限,并且在安装过程中询问较低版本的权限。例如,在应用启动时,我创建了一个方法来检查它是否已启用,如果未启用则请求权限。

private void CheckAppPermissions()
{
    if ((int)Build.VERSION.SdkInt < 23)
    {
        return;
    }
    else
    {
        if (PackageManager.CheckPermission(Manifest.Permission.ReadExternalStorage, PackageName) != Permission.Granted
            && PackageManager.CheckPermission(Manifest.Permission.WriteExternalStorage, PackageName) != Permission.Granted)
        {
            var permissions = new string[] { Manifest.Permission.ReadExternalStorage, Manifest.Permission.WriteExternalStorage };
            RequestPermissions(permissions, 1);
        }
     }
}

您也可以使用支持库来执行此操作,这样更简单,您不必检查 Android 版本。欲了解更多信息,请查看google's documentation.

【讨论】:

  • 这应该被标记为正确答案。工作得很好。
  • 我正在使用这个 sn-p,它为这两个权限返回“已授予”,但我仍然被拒绝访问。有什么想法吗?
  • 它可能不喜欢您尝试读取/写入的位置。尝试检查位置或将其更改为您知道存在的another path
  • 完全没问题。
【解决方案2】:

如果针对 API 29+,即使您请求权限并且用户授予权限,您也会收到错误消息,因为他们更改了存储的工作方式。

正确的解决方案是看看它应该如何在 API 29+ 上完成并执行。

但是,如果您像我一样,厌倦了 Android 让事情变得越来越复杂,只需将 android:requestLegacyExternalStorage="true" 添加到您的清单 &lt;application&gt; 标记中,您就可以保存,直到您开始以 API 30 为目标。

【讨论】:

  • 你是怎么做到的?
  • 嗨,我现在的目标是 API 30。我的应用程序正在存储日志文件并在位置“/storage/emulated/0/SpecialDir/LogFile.txt”中进行数据库备份。现在我面临访问被拒绝的问题。请你指导我该怎么做。
  • 你拯救了我的一天!谢谢。 (注意:即使在我授予外部存储权限后,我也使用了统一并得到了拒绝访问问题。现在通过在我的自定义清单中的应用程序标记中添加 'android:requestLegacyExternalStorage="true"' 来解决此问题)
  • 值得一提的是,这只是一个临时解决方案,最好让您的应用与 Scoped Storage 兼容:在您将应用更新为针对 Android 11(API 级别 30)后,系统会忽略当您的应用在 Android 11 设备上运行时使用 requestLegacyExternalStorage 属性,因此您的应用必须准备好支持范围存储并为这些设备上的用户迁移应用数据。安卓源:developer.android.com/training/data-storage/…
  • @SnapADragon 是的,我确实提到过。 “在您开始以 API 30 为目标之前,您将一直保存”。
【解决方案3】:

那些在你的应用面向 API29 或更高版本后遇到此问题的人,请转到此链接并查看 LandLu 的回答:

https://forums.xamarin.com/discussion/171039/saving-files-to-external-storage

之前我使用的是访问文件夹路径 返回 Android.OS.Environment.ExternalStorageDirectory.AbsolutePath; 但是使用这条线解决了我的问题: 返回 Android.App.Application.Context.GetExternalFilesDir("").AbsolutePath;

【讨论】:

    【解决方案4】:

    如果您运行的是 Android api 级别 23 或更高版本,即使您在清单文件中提到了它们,您也需要用户的运行时许可。检查如果用户尚未授予READ_EXTERNAL_STORAGE & WRITE_EXTERNAL_STORAGE,请使用以下代码;

    var permissions = new string[] { Manifest.Permission.ReadExternalStorage, Manifest.Permission.WriteExternalStorage };
                RequestPermissions(permissions, 77);
    

    如果我使用以下路径作为我的下载路径,我可以下载 文件。但我无法将 PDF 文件共享到谷歌驱动器、投递箱 或任何其他 System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal)

    您将文件存储在应用程序的私人存储中。保存到内部存储的所有文件都是您的应用程序私有的,其他应用程序(谷歌驱动器、投递箱或任何其他)无法访问它们(用户也不能)。您可以为此目的使用任何公用文件夹;

    var finalPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads);
    

    【讨论】:

      【解决方案5】:

      替换

      Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
      

      Android.App.Application.Context.GetExternalFilesDir("").AbsolutePath;
      

      【讨论】:

      • 嗨!添加一些上下文可能会大大提高答案的质量。您可能还会发现 here 中的信息对未来的答案很有用,
      猜你喜欢
      • 2017-01-24
      • 1970-01-01
      • 1970-01-01
      • 2021-04-02
      • 1970-01-01
      • 1970-01-01
      • 2021-06-19
      相关资源
      最近更新 更多