web-dev-qa-db-ja.com

Xamarin.Formsファイルシステムにファイルを保存しています

Webからファイルをダウンロードして、Environment.SpecialFolderの場所に保存しようとしています。どんなアプローチをしようとも関係なく、いつも

System.UnauthorizedAccessException: 'パスへのアクセス'試行したすべての可能なパス(Environment.SpecialFolderを超えても) 'が拒否されました。

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));
    
    4
    Bibipkins

    権限の問題が発生しています。

    まず、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 -マシュマロ/

    3
    Bruno Caceiro

    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" />を追加することにより、いくつかの制限付きフォルダーにアクセスすることもできますユーザーがアクセスできるすべてのファイル/フォルダーにアクセスできます。

    Capabilities designer

    2
    Fabulous

    私はAndroidでも同じ問題を抱えていましたが、問題は

    1. ランタイムの許可を求める必要がありました。ACCESS_COARSE_LOCATIONWRITE_EXTERNAL_STORAGEの両方の許可が必要であることを覚えておいてください

    2. 私は間違ったパスを使用していましたが、私の主な問題は解決できないパスを実用的に取得することでした。手動でパスを入力して解決しました。私はあなたが正しい完全なパス(etc storage/emulated/0 /)を使用すれば、問題に直面することはないと信じています。

    1
    hadi