我正在尝试下载文件,但收到 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 版本,即使在 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 的文档。
如果针对 API 29+,即使您请求权限并且用户授予该权限,您也会收到错误,因为它们改变了存储的工作方式。
正确的解决方案是看看在 API 29+ 上应该如何完成并执行它。
但是,如果您像我一样,厌倦了 Android 每天让事情变得更加复杂,只需将
android:requestLegacyExternalStorage="true"
添加到您的清单 <application>
标签中,您就可以保存到开始针对 API 30 为止。
如果您的应用定位 API29 或更高版本后遇到此问题,请转到此链接并查看 LandLu 的答案:
https://forums.xamarin.com/discussion/171039/ saving-files-to-external-storage
之前我使用访问文件夹路径 返回Android.OS.Environment.ExternalStorageDirectory.AbsolutePath; 但使用这条线解决了我的问题: 返回 Android.App.Application.Context.GetExternalFilesDir("").AbsolutePath;
这才是正确答案!!!
如果您运行的是 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);
更换
Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
与
Android.App.Application.Context.GetExternalFilesDir("").AbsolutePath;