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 上遇到了同样的问题,我意识到这个问题是因为
我不得不请求运行时的许可,请记住你需要 ACCESS_COARSE_LOCATION 和 WRITE_EXTERNAL_STORAGE权限
我使用了错误的路径,我的主要问题是实用地获取我无法解决的路径,我通过手动输入路径解决了它。我相信如果您使用正确的完整路径(等 storage/emulated/0/),您将不会遇到任何问题。
我尝试从网上下载文件并保存到任何 Environment.SpecialFolder 位置。无论我尝试哪种方法 - 我总是得到
System.UnauthorizedAccessException: 'Access to the path 'any possible path I try (even beyond Environment.SpecialFolder)' is denied.'
我尝试在 UWP 和 Android 上访问文件系统 - 都是相同的异常。
到目前为止,我尝试过但没有成功:
代码示例:
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 上遇到了同样的问题,我意识到这个问题是因为
我不得不请求运行时的许可,请记住你需要 ACCESS_COARSE_LOCATION 和 WRITE_EXTERNAL_STORAGE权限
我使用了错误的路径,我的主要问题是实用地获取我无法解决的路径,我通过手动输入路径解决了它。我相信如果您使用正确的完整路径(等 storage/emulated/0/),您将不会遇到任何问题。