Xamarin-System.UnauthorizedAccessException:对路径的访问被拒绝

问题描述 投票:0回答:5

我正在尝试下载文件,但收到 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 时代码工作正常 请提出您的想法来解决该问题。

提前致谢。

xamarin xamarin.android
5个回答
36
投票

根据您使用的 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 的文档。


23
投票

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

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

但是,如果您像我一样,厌倦了 Android 每天让事情变得更加复杂,只需将

android:requestLegacyExternalStorage="true"
添加到您的清单
<application>
标签中,您就可以保存到开始针对 API 30 为止。


9
投票

如果您的应用定位 API29 或更高版本后遇到此问题,请转到此链接并查看 LandLu 的答案:

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

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

这才是正确答案!!!


1
投票

如果您运行的是 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);

0
投票

更换

Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;

Android.App.Application.Context.GetExternalFilesDir("").AbsolutePath;
© www.soinside.com 2019 - 2024. All rights reserved.