Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin-System.UnauthorizedAccessException: Access to the path is denied

I'm trying to download a file and I'm getting System.UnauthorizedAccessException: Access to the path "/storage/emulated/0/Download/test.pdf" is denied. I have set required permission in Android Manifest file.

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Download Path:

Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads)

If i use the below path as my download path i can able to download the file. But i cant able to share the PDF file to google drive, drop box or any other System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal)

I am using Xamarin.Forms v2.4.0.282 and Xamarin.Android.Support packages v25.4.0.2.

Note: The code was woking fine when use Xamarin.Forms version 2.3.5.256-pre2 and Xamarin.Android.Support packages v23.3.0 Please suggest your ideas to resolve the issue.

Thanks in Advance.

like image 840
Melody Avatar asked Oct 24 '17 13:10

Melody


People also ask

What is System UnauthorizedAccessException?

An UnauthorizedAccessException exception is thrown when the operating system denies access because of an I/O error or a security error. If you are attempting to access a file or registry key, make sure it is not read-only.


2 Answers

Depending on the version of Android you are using even with the permissions added in the manifest in 6.0 or up the user has to explicitly enable the permission when the app runs and on lower versions permission is asked during install. For example, on startup of the app I created a method to check if it is enabled and request permission if it's not.

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);
        }
     }
}

You can also use the support library to do this, which is simpler and allows you to not have to check the Android version. For more info check out google's documentation.

like image 145
Nick Peppers Avatar answered Oct 09 '22 03:10

Nick Peppers


If targeting API 29+, you will get the error even if you request the permission and user grants it, because they changed how storage works.

The correct solution is to look how it should be done on API 29+ and do it.

But if you are like me, tired of Android making things more complicated every day, just add android:requestLegacyExternalStorage="true" to your manifest <application> tag and you are saved until you start targeting API 30.

like image 23
David Riha Avatar answered Oct 09 '22 04:10

David Riha