question

GayatriGokhale-4983 avatar image
0 Votes"
GayatriGokhale-4983 asked JessieZhang-2116 answered

Creating Files in Android 11 gives Access Denied error.

I am trying to create file at Downloads Directory. Basically I want user to download excel file that resides in my app(In Android Assets folder). User will fill and upload it again. For downloading I do as follows

 public async void DownloadSupplierSample(object sender, EventArgs e)
     {
         try
         {
             string basepath;
             if (Device.RuntimePlatform == Device.Android)
                 basepath = DependencyService.Get<IDownloadPath>().GetDownloadsPath();
             else
                 basepath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "..", "Library");
    
             PermissionStatus readstatus = await Permissions.CheckStatusAsync<Permissions.StorageRead>();
             PermissionStatus writestatus = await Permissions.CheckStatusAsync<Permissions.StorageWrite>();
    
             if (readstatus == PermissionStatus.Granted && writestatus == PermissionStatus.Granted)
             {
                 DownloadSupplier(basepath);
             }
             else
             {
                 var read = await Permissions.RequestAsync<Permissions.StorageRead>();
                 var write = await Permissions.RequestAsync<Permissions.StorageWrite>();
    
                 if (read == PermissionStatus.Granted && write == PermissionStatus.Granted)
                 {
                     DownloadSupplier(basepath);
                 }
             }
             await DisplayAlert("", "Sample is downaloaded at Downloads directory","Ok");
         }
         catch (Exception ex)
         {
         }
     }
    
     async void DownloadSupplier(string basepath)
     {
         using (var stream = await FileSystem.OpenAppPackageFileAsync("SupplierMaster.xlsx"))
         {
             string filename = $"SupplierMaster_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx";
             string filepath = Path.Combine(basepath, filename);
    
             byte[] bytes = Utils.Common.StreamToBytes(stream);
             File.WriteAllBytes(filepath, bytes);
             //using (Stream filestream = File.Create(filepath))
             //{
             //    //stream.Seek(0, SeekOrigin.Begin);
             //    stream.CopyTo(filestream);
             //}
         }
     }

even if I give required permission and set flag in AndroidManifest.xml, I am getting this error.

I had asked on SO as well. Here is the linklink I tried to implement answer as well. It worked for few times but after that same error comes.

Please help.

Thank you


dotnet-xamarinformsdotnet-androiddotnet-xamarinessentials
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi @GayatriGokhale-4983 , if it is convenient for you, could you please post a basic demo so that we can test on our side?

0 Votes 0 ·

Congrats, I found you have found the solution. As a summary, I will post an answer so that it will help others who have similar problems.

0 Votes 0 ·
alessandrocaliaro avatar image
0 Votes"
alessandrocaliaro answered

Android 11 has a new storage update

storage

take a look to this:

xamarin-forms-accessing-external-storage-on-android-11-target-sdk-version-is-29


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

JessieZhang-2116 avatar image
0 Votes"
JessieZhang-2116 answered

Hello,


Welcome to our Microsoft Q&A platform!

1.Try to create a service class in Android project, just as follows:

  private class ActivityResultListener
     {
         private readonly TaskCompletionSource<Intent> Complete = new TaskCompletionSource<Intent>();
         public Task<Intent> Task { get { return this.Complete.Task; } }
    
         public ActivityResultListener(MainActivity activity)
         {
             // subscribe to activity results
             activity.ActivityResult += OnActivityResult;
         }
    
         private void OnActivityResult(int requestCode, Result resultCode, Intent data)
         {
             if(requestCode != CREATE_FILE_REQUEST_CODE)
             {
                 return;
             }
    
             // unsubscribe from activity results
             var activity = (MainActivity)_context;
             activity.ActivityResult -= OnActivityResult;
    
             // process result
             if (resultCode == Result.Ok)
             {
                 Complete.TrySetResult(data);
             }
             else
             {
                 Complete.TrySetResult(null);
             }
         }
     }
 }

2.In MainActivity.cs, add the following code:

  public event Action<int, Result, Intent> ActivityResult;
    
 protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) 
 {
     ActivityResult?.Invoke(requestCode, resultCode, data); 
 }

3.call Init method after Forms.Init:

  FilesManager.Init(this);

Refer: https://stackoverflow.com/questions/66560359/xamarin-forms-how-to-define-scoped-storage-for-android-and-how-can-i-implement

Best Regards,

Jessie Zhang


If the response is helpful, please click "Accept Answer" and upvote it.


Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.





5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.