Webからファイルをダウンロードして、Environment.SpecialFolderの場所に保存しようとしています。どんなアプローチをしようとも関係なく、いつも
System.UnauthorizedAccessException: 'パスへのアクセス'試行したすべての可能なパス(Environment.SpecialFolderを超えても) 'が拒否されました。
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];
}
詳細については、Android- https://devblogs.Microsoft.com/xamarin/requesting-runtime-permissions-in-Android -マシュマロ/
Bruno Caceiro's 承認済みの回答に加えて、宣言するUWP権限は次のとおりです。ドキュメントの場合はDocumentsLibrary
、音楽フォルダの場合はMusicLibrary
など。
これらをグラフィカルに表示するには、プロジェクトを右クリックして[プロパティ]をクリックし、[パッケージマニフェスト]をクリックしてスクリーンショットに示すように機能タブに移動するか、またはpackage.appxmanifest
を右クリックしてビューコードを選択し、xmlを編集します。機能を宣言する方法については、コードの抜粋を参照してください。ダイアログに表示されないものもあります。
<Capabilities>
<Capability Name="internetClient" />
<uap:Capability Name="documentsLibrary"/>
<uap:Capability Name="picturesLibrary" />
</Capabilities>
Editさらに、rescap
(制限された機能)名前空間を使用して<rescap:Capability Name="broadFileSystemAccess" />
を追加することにより、いくつかの制限付きフォルダーにアクセスすることもできますユーザーがアクセスできるすべてのファイル/フォルダーにアクセスできます。
私はAndroidでも同じ問題を抱えていましたが、問題は
ランタイムの許可を求める必要がありました。ACCESS_COARSE_LOCATIONとWRITE_EXTERNAL_STORAGEの両方の許可が必要であることを覚えておいてください
私は間違ったパスを使用していましたが、私の主な問題は解決できないパスを実用的に取得することでした。手動でパスを入力して解決しました。私はあなたが正しい完全なパス(etc storage/emulated/0 /)を使用すれば、問題に直面することはないと信じています。