I try to download file from web and save to any of Environment.SpecialFolder locations. No matter of what approach I try - I always get 
System.UnauthorizedAccessException: 'Access to the path 'any possible path I try (even beyond Environment.SpecialFolder)' is denied.'
I tried accessing filesystem on UWP and Android - both same exception.
 What I tried with no luck so far:
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));
                You are facing a permissions issue.
First, you will have to add in your AndroidManifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
And since Android Marshmallow, you need to ask the user for the permissions, so I advise to use the package Permissions.Plugin
And add in your 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);
}
You can check in runtime if you have the permissions by:
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];
    }
For further information you can check this blog post explaining all the permissions in Android - https://devblogs.microsoft.com/xamarin/requesting-runtime-permissions-in-android-marshmallow/
In addition to Bruno Caceiro's accepted answer, the UWP permissions you want to declare are as follows: DocumentsLibrary for documents, MusicLibrary for the music folder and so on.
You can get to these graphically via Right click project -> Properties and then clicking Package Manifest and going to the capabilities tab as shown in the screenshot, or alternatively right-clicking package.appxmanifest and selecting view code to edit the xml. See the code excerpt for how to declare capabilities. Some won't have a representation in the dialog.
<Capabilities>
    <Capability Name="internetClient" />
    <uap:Capability Name="documentsLibrary"/>
    <uap:Capability Name="picturesLibrary" />
</Capabilities>
Edit additionally, you can also access some restricted folders by using the rescap (restricted capability) namespace to add <rescap:Capability Name="broadFileSystemAccess" /> to gain access to any file/folder the user has access to.

I Had the Same problem on Android, i realized the problem is because
I Had to ask permission on Runtime , keep in mind that you need both ACCESS_COARSE_LOCATION and WRITE_EXTERNAL_STORAGE permissions
I was using wrong Path, my main problem was to get the path pragmatically which i couldn't solve and I solved it by typing the path Manually. i believe if you use the correct full path(etc storage/emulated/0/) you're not going to face any problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With