0

I've been trying to create a function where the user will download a file(PDF) when a button is clicked. I stored the file in firebase storage and can be accessible via url/link. I found this solution How to download files in Xamarin.Forms? that helps you download from a url. However I got an error that say **System.UnauthorizedAccessException:** 'Access to the path '/data/user/0/com.companyname.pawadopt_v5/files' is denied.' I already made sure to check and request permission using Xamarin.Essentials but I keep getting this error even with Permission.Granted for StorageRead and StorageWrite.

Here is my code: Download Function

    public async Task<bool> DownloadFile(string fileURL)
    {
        var checkPermission = await PermissionServices.PermissionClientInstance.checkStorage();
        if(checkPermission == true)
        {
            string path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            try
            {
                var client = new HttpClient();

                var downloadStream = await client.GetStreamAsync(fileURL);

                var fileStream = File.Create(path);

                await downloadStream.CopyToAsync(fileStream);

                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }

Check and Request Permission

        var Readpermission = await Permissions.CheckStatusAsync<Permissions.StorageRead>();
        var Writepermission = await Permissions.CheckStatusAsync<Permissions.StorageWrite>();
        if (Readpermission != PermissionStatus.Granted || Writepermission != PermissionStatus.Granted)
        {
            Readpermission = await Permissions.RequestAsync<Permissions.StorageRead>();
            Writepermission = await Permissions.RequestAsync<Permissions.StorageWrite>();
        }
        if (Readpermission != PermissionStatus.Granted && Writepermission != PermissionStatus.Granted)
            return false;
        else
            return true;

What are your thoughts and solutions about this? Any ideas and solution are greatly appreciated

UPDATE

When I changed the path into string localPath = Path.Combine(FileSystem.AppDataDirectory,"File.pdf");, No error shows and prompt the 'Download Successful'. However I cant find where this local path is.

Lomon13
  • 15
  • 3

2 Answers2

0

For anybody having this problem, if you want to download a file in Xamarin or MAUI android, it is better to use the download manager, and for Android versions >= 10, you can avoid a System.UnauthorizedAccessException by specifying a path within the application's external files directory.

This is how we do it: Create a download manager request,

        using var request = new DownloadManager.Request(global::Android.Net.Uri.Parse(downloadUrl));

Use this method to set the download path to your application's external files directory:

        request.SetDestinationInExternalFilesDir(Platform.CurrentActivity, Environment.DirectoryDownloads, fileName);

And, you use a download manager instance to download your item.

        long downloadId = manager.Enqueue(request);

When the download finishes, you'l have full access to the file downloaded, you'l be able to read, write, delete the file as you wish.

For more details about using this approach, for downloading, monitoring and controlling your downloads, checkout this awesome article.

Damien Doumer
  • 1,991
  • 1
  • 18
  • 33
0

I kept getting an unauthorized access issue on Android 13, in the end using Java.IO.File instead of System.File fixed the issue on Android for me when targeting internal app data. I gave a full example in this Stackoverflow thread.

CVStrydom
  • 11
  • 5